You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
133 lines
6.2 KiB
133 lines
6.2 KiB
#!/usr/bin/env python3
|
|
|
|
import argparse
|
|
import sys
|
|
import tempfile
|
|
import subprocess
|
|
import shutil
|
|
|
|
# Import local files
|
|
from .util import import_md
|
|
from .katex import KatexClient
|
|
from .images import ImageProcessor, ImageProcessorNamespace
|
|
from .output_generator import OutputGenerator, FormatitkoRecursiveError
|
|
from .html_generator import HTMLGenerator, StandaloneHTMLGenerator
|
|
from .transform_processor import TransformProcessor
|
|
from .pandoc_processor import PandocProcessor
|
|
from .tex_generator import UCWTexGenerator
|
|
from .context import get_context_from_doc
|
|
|
|
from panflute import convert_text
|
|
|
|
def main():
|
|
# Initialize command line arguments
|
|
parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
|
parser.add_argument("-l", "--img-lookup-dirs", help="Image lookup directories. When processing images, the program will try to find the image in them first. Always looks for images in the same folder as the markdown file.", nargs="+", default=[])
|
|
parser.add_argument("-p", "--img-public-dir", help="Directory to put processed images into. The program will overwrite images, whose dependencies are newer.", default="public")
|
|
parser.add_argument("-c", "--img-cache-dir", help="Directory to cache processed images and intermediate products. The program will overwrite files, whose dependencies are newer.", default="cache")
|
|
parser.add_argument("-i", "--img-web-path", help="Path where the processed images are available on the website.", default="/")
|
|
parser.add_argument("-w", "--output-html", help="The HTML file (for Web) to write into.")
|
|
parser.add_argument("-s", "--output-standalone-html", help="The Standalone HTML file to write into. A full page is generated instead of just a fragment.")
|
|
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("-P", "--output-pdf", help="The PDF file to save the PDF generated by TeX.")
|
|
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')
|
|
parser.add_argument("--traceback-limit", help="Traceback limit for when errors happen, defaults to 0, as it is only useful for internal debugging.", default=0)
|
|
parser.add_argument("--deps", help="File to write list of dependencies to. May depend on output formats used.")
|
|
args = parser.parse_args()
|
|
|
|
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())
|
|
|
|
if args.debug:
|
|
try:
|
|
OutputGenerator(sys.stdout).generate(doc)
|
|
except FormatitkoRecursiveError as e:
|
|
e.pretty_print(tracebacklimit=args.traceback_limit)
|
|
|
|
try:
|
|
doc = TransformProcessor(args.input_filename).transform(doc)
|
|
except FormatitkoRecursiveError as e:
|
|
e.pretty_print(tracebacklimit=args.traceback_limit)
|
|
|
|
# Initialize the image processor (this just keeps some basic state)
|
|
imageProcessor = ImageProcessor({"": ImageProcessorNamespace(args.img_public_dir, args.img_web_path, args.img_cache_dir, args.img_lookup_dirs, True)})
|
|
|
|
if args.output_html is not None:
|
|
# Initialize KaTeX client (this runs the node app and connects to a unix socket)
|
|
with KatexClient(socket=args.katex_socket) as katexClient:
|
|
with open(args.output_html, "w") as file:
|
|
try:
|
|
HTMLGenerator(file, katexClient, imageProcessor).generate(doc)
|
|
except FormatitkoRecursiveError as e:
|
|
e.pretty_print(tracebacklimit=args.traceback_limit)
|
|
|
|
if args.output_standalone_html is not None:
|
|
# Initialize KaTeX client (this runs the node app and connects to a unix socket)
|
|
with KatexClient(socket=args.katex_socket) as katexClient:
|
|
with open(args.output_standalone_html, "w") as file:
|
|
try:
|
|
StandaloneHTMLGenerator(file, katexClient, imageProcessor).generate(doc)
|
|
except FormatitkoRecursiveError as e:
|
|
e.pretty_print(tracebacklimit=args.traceback_limit)
|
|
|
|
if args.output_tex is not None:
|
|
with open(args.output_tex, "w") as file:
|
|
try:
|
|
UCWTexGenerator(file, imageProcessor).generate(doc)
|
|
except FormatitkoRecursiveError as e:
|
|
e.pretty_print(tracebacklimit=args.traceback_limit)
|
|
|
|
if args.output_md is not None:
|
|
with open(args.output_md, "w") as file:
|
|
file.write(convert_text(PandocProcessor().transform(doc), input_format="panflute", output_format="markdown"))
|
|
|
|
if args.output_json is not None:
|
|
with open(args.output_json, "w") as file:
|
|
file.write(convert_text(PandocProcessor().transform(doc), input_format="panflute", output_format="json"))
|
|
|
|
if args.output_pdf is not None:
|
|
if args.output_tex is None:
|
|
fd = tempfile.NamedTemporaryFile(dir=".", suffix=".tex")
|
|
with open(fd.name, "w") as file:
|
|
try:
|
|
UCWTexGenerator(file, imageProcessor).generate(doc)
|
|
except FormatitkoRecursiveError as e:
|
|
e.pretty_print(tracebacklimit=args.traceback_limit)
|
|
filename = fd.name
|
|
else:
|
|
filename = args.output_tex
|
|
outdir = tempfile.TemporaryDirectory(prefix="formatitko")
|
|
subprocess.run(["pdfcsplain", "-halt-on-error", "-output-directory="+outdir.name, "-jobname=formatitko", filename], check=True)
|
|
shutil.move(outdir.name+"/formatitko.pdf", args.output_pdf)
|
|
|
|
if args.deps is not None:
|
|
with open(args.deps, "w") as file:
|
|
for dep in get_context_from_doc(doc).get_deps():
|
|
file.write(dep + "\n")
|
|
|
|
if args.debug:
|
|
print("-----------------------------------")
|
|
try:
|
|
OutputGenerator(sys.stdout).generate(doc)
|
|
except FormatitkoRecursiveError as e:
|
|
e.pretty_print(tracebacklimit=args.traceback_limit)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|
|
|
|
|