Compare commits
2 commits
1b971ea3b4
...
dc3b6510bb
Author | SHA1 | Date | |
---|---|---|---|
dc3b6510bb | |||
b7ebe6d4a0 |
3 changed files with 45 additions and 9 deletions
|
@ -30,12 +30,22 @@ def main():
|
|||
parser.add_argument("-t", "--output-tex", help="The TEX file to write into.")
|
||||
parser.add_argument("-m", "--output-md", help="The Markdown file to write into. (Uses pandoc to generate markdown)")
|
||||
parser.add_argument("-j", "--output-json", help="The JSON file to dump the pandoc-compatible AST into.")
|
||||
parser.add_argument("input_filename", help="The markdown file to process.")
|
||||
parser.add_argument("--katex-server", action='store_true', help="Starts a KaTeX server and prints the socket filename onto stdout. Useful for running formatitko many times without starting the KaTeX server each time.")
|
||||
parser.add_argument("-k", "--katex-socket", help="The KaTeX server socket filename obtained by running with `--katex-server`.")
|
||||
parser.add_argument("input_filename", help="The markdown file to process.", nargs="?" if "--katex-server" in sys.argv else None)
|
||||
parser.add_argument("--debug", action='store_true')
|
||||
args = parser.parse_args()
|
||||
# TODO: Accept path to unix socket for katexClient, then don't init our own,
|
||||
# just connect to an existing one. For formátíking many files in a row.
|
||||
|
||||
if args.katex_server:
|
||||
with KatexClient(connect=False) as katexClient:
|
||||
print(katexClient.get_socket())
|
||||
try:
|
||||
while True:
|
||||
pass
|
||||
except KeyboardInterrupt:
|
||||
print("Exiting...")
|
||||
return
|
||||
|
||||
# Use panflute to parse the input MD file
|
||||
doc = import_md(open(args.input_filename, "r").read())
|
||||
|
||||
|
@ -49,7 +59,7 @@ def main():
|
|||
|
||||
if args.output_html is not None:
|
||||
# Initialize KaTeX client (this runs the node app and connects to a unix socket)
|
||||
with KatexClient() as katexClient:
|
||||
with KatexClient(socket=args.katex_socket) as katexClient:
|
||||
with open(args.output_html, "w") as file:
|
||||
HTMLGenerator(file, katexClient, imageProcessor).generate(doc)
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ async function handleClient(client) {
|
|||
* the one from the parent group and can add its own stuff without
|
||||
* affecting the parent.
|
||||
*/
|
||||
const macroStack = [{}]
|
||||
let macroStack = [{}]
|
||||
for await (const line of rl) {
|
||||
try {
|
||||
// The custom commands for pushing and popping the macro stack.
|
||||
|
@ -94,6 +94,9 @@ async function handleClient(client) {
|
|||
} else if (line === "endgroup") {
|
||||
macroStack.pop()
|
||||
continue
|
||||
} else if (line === "init") {
|
||||
macroStack = [{}]
|
||||
continue
|
||||
}
|
||||
const query = JSON.parse(line)
|
||||
const results = []
|
||||
|
|
|
@ -19,8 +19,21 @@ class KatexClient:
|
|||
_server_process: subprocess.Popen[bytes]
|
||||
_socket_file: str
|
||||
_temp_dir: tempfile.TemporaryDirectory[str]
|
||||
_connected: bool
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self, socket: str=None, connect: bool=True):
|
||||
if socket is not None:
|
||||
self._socket_file = socket
|
||||
else:
|
||||
self.open_socket()
|
||||
if connect:
|
||||
self.connect()
|
||||
self._client.sendall("init\n".encode("utf-8")) # Reinitialize KaTeX Server in case it was reused.
|
||||
self._connected = True
|
||||
else:
|
||||
self._connected = False
|
||||
|
||||
def open_socket(self):
|
||||
# Create temporary directory for socket
|
||||
self._temp_dir = tempfile.TemporaryDirectory(prefix='formatitko')
|
||||
self._socket_file = self._temp_dir.name + "/katex-socket"
|
||||
|
@ -40,15 +53,20 @@ class KatexClient:
|
|||
|
||||
self._server_process = subprocess.Popen(["node", srcdir + "/katex-server/index.mjs", self._socket_file], stdout=subprocess.PIPE)
|
||||
|
||||
self._client = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
|
||||
ok = self._server_process.stdout.readline()
|
||||
if ok != b"OK\n":
|
||||
raise KatexServerError("Failed to connect to katex-server")
|
||||
|
||||
def connect(self):
|
||||
self._client = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||
self._client.connect(self._socket_file)
|
||||
|
||||
def get_socket(self):
|
||||
return self._socket_file
|
||||
|
||||
def render(self, tex: str, options: dict={}):
|
||||
if not self._connected:
|
||||
raise KatexServerError("KatexClient not connected to Katex server. It should be initialized with connect=True.")
|
||||
# Send formulas to translate
|
||||
self._client.sendall((json.dumps({"formulas":[{"tex":tex}], "options":options})+"\n").encode("utf-8"))
|
||||
|
||||
|
@ -67,13 +85,18 @@ class KatexClient:
|
|||
|
||||
# Special commands implemented in the JS file for grouping defs together.
|
||||
def begingroup(self):
|
||||
if not self._connected:
|
||||
raise KatexServerError("KatexClient not connected to Katex server. It should be initialized with connect=True.")
|
||||
self._client.sendall("begingroup\n".encode("utf-8"))
|
||||
|
||||
def endgroup(self):
|
||||
if not self._connected:
|
||||
raise KatexServerError("KatexClient not connected to Katex server. It should be initialized with connect=True.")
|
||||
self._client.sendall("endgroup\n".encode("utf-8"))
|
||||
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, type, value, tb):
|
||||
self._server_process.terminate()
|
||||
if hasattr(self, "_server_process") and self._server_process is not None:
|
||||
self._server_process.terminate()
|
||||
|
|
Loading…
Reference in a new issue