Browse Source

Add special StandaloneHTMLGenerator. Also handle prepending the document in a more pandocy way.

master
Jan Černohorský 2 months ago
parent
commit
72b9bc7bf1
  1. 27
      src/formatitko/formatitko.py
  2. 32
      src/formatitko/html_generator.py
  3. 2
      src/formatitko/images.py
  4. 3
      src/formatitko/output_generator.py
  5. 8
      test/test-top.html
  6. 11
      test/test.md

27
src/formatitko/formatitko.py

@ -8,11 +8,10 @@ import shutil
# Import local files
from .util import import_md
from .context import Context, BlockGroup
from .katex import KatexClient
from .images import ImageProcessor, ImageProcessorNamespace
from .output_generator import OutputGenerator, FormatitkoRecursiveError
from .html_generator import HTMLGenerator
from .html_generator import HTMLGenerator, StandaloneHTMLGenerator
from .transform_processor import TransformProcessor
from .pandoc_processor import PandocProcessor
from .tex_generator import UCWTexGenerator
@ -27,6 +26,7 @@ def main():
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.")
@ -35,6 +35,7 @@ def main():
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)
args = parser.parse_args()
if args.katex_server:
@ -54,12 +55,12 @@ def main():
try:
OutputGenerator(sys.stdout).generate(doc)
except FormatitkoRecursiveError as e:
e.pretty_print()
e.pretty_print(tracebacklimit=args.traceback_limit)
try:
doc = TransformProcessor(args.input_filename).transform(doc)
except FormatitkoRecursiveError as e:
e.pretty_print()
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)})
@ -71,15 +72,23 @@ def main():
try:
HTMLGenerator(file, katexClient, imageProcessor).generate(doc)
except FormatitkoRecursiveError as e:
e.pretty_print()
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()
e.pretty_print(tracebacklimit=args.traceback_limit)
if args.output_md is not None:
with open(args.output_md, "w") as file:
@ -96,7 +105,7 @@ def main():
try:
UCWTexGenerator(file, imageProcessor).generate(doc)
except FormatitkoRecursiveError as e:
e.pretty_print()
e.pretty_print(tracebacklimit=args.traceback_limit)
filename = fd.name
else:
filename = args.output_tex
@ -109,7 +118,7 @@ def main():
try:
OutputGenerator(sys.stdout).generate(doc)
except FormatitkoRecursiveError as e:
e.pretty_print()
e.pretty_print(tracebacklimit=args.traceback_limit)
if __name__ == "__main__":

32
src/formatitko/html_generator.py

@ -20,6 +20,7 @@ from .katex import KatexClient
from .images import ImageProcessor, ImageProcessorNamespaceSearcher
from .util import inlinify
class HTMLGenerator(OutputGenerator):
imageProcessor: ImageProcessor
katexClient: KatexClient
@ -317,3 +318,34 @@ class HTMLGenerator(OutputGenerator):
def generate_DefinitionList(self, e: DefinitionList):
self.writeln("<!-- FIXME: DefinitionLists not implemented -->")
class StandaloneHTMLGenerator(HTMLGenerator):
def generate_Doc(self, e: Doc):
self.writeraw("<!DOCTYPE html>")
self.writeln(self.start_tag("html", attributes={"lang": e.get_metadata("lang", None, True)}))
self.writeln(self.start_tag("head"))
self.indent_more()
self.writeln(self.single_tag("meta", attributes={"charset": "utf-8"}))
self.writeln(self.single_tag("meta", attributes={"viewport": "width=device-width, initial-scale=1.0"}))
self.writeln(self.single_tag("link", attributes={"href": "https://cdn.jsdelivr.net/npm/katex@0.16.4/dist/katex.min.css", "integrity":"sha384-vKruj+a13U8yHIkAyGgK1J3ArTLzrFGBbBc0tDp4ad/EyewESeXE/Iv67Aj8gKZ0", "crossorigin":"anonymous"}))
if "title" in e.metadata:
self.write(self.start_tag("title"))
self.generate(e.metadata["title"])
self.write(self.end_tag("title"))
self.endln()
if "html-head-includes" in e.metadata:
self.generate(e.metadata["html-head-includes"])
self.indent_less()
self.writeln(self.end_tag("head"))
self.writeln(self.start_tag("body"))
self.indent_more()
super().generate_Doc(e)
self.indent_less()
self.writeln(self.end_tag("body"))
self.writeln(self.end_tag("html"))

2
src/formatitko/images.py

@ -150,6 +150,8 @@ class ImageProcessor:
return self.namespaces[path.split(":")[0] if ":" in path else ""]
def get_path_without_namespace(self, path: str) -> str:
if len(path.split(":")) <= 1:
return path
return ":".join(path.split(":")[1:])
def get_searcher_by_path(self, path: str, rel_dir: str, source_dir: str) -> ImageProcessorNamespaceSearcher:

3
src/formatitko/output_generator.py

@ -478,12 +478,13 @@ class OutputGenerator:
self.generate_simple_tag(e)
def generate_Doc(self, e: Doc):
if "header-includes" in e.metadata: # This is the pandoc way of doing things
self.generate(e.metadata["header-includes"])
if "header_content" in e.metadata:
self.generate(e.metadata["header_content"])
self.generate_simple_tag(e)
if "footer_content" in e.metadata:
self.generate(e.metadata["footer_content"])
def generate_BlockGroup(self, e: BlockGroup):
self.generate_simple_tag(e)

8
test/test-top.html

@ -1,8 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset='utf-8'>
<link rel='stylesheet' href='https://cdn.jsdelivr.net/npm/katex@0.16.4/dist/katex.min.css' integrity='sha384-vKruj+a13U8yHIkAyGgK1J3ArTLzrFGBbBc0tDp4ad/EyewESeXE/Iv67Aj8gKZ0' crossorigin='anonymous'>
</head>
<body>

11
test/test.md

@ -3,12 +3,13 @@ title: 'Wooooo a title'
subtitle: 'A subtitle'
are_we_there_yet: False
lang: "en"
header-includes: |
<style>
body {
color: forestgreen;
}
</style>
---
:::: {.header_content}
::: {partial="test-top.html" type="html"}
:::
::::
[#test-files/test-import.md]{type=md}
[#test.json]{type=metadata key=orgs}

Loading…
Cancel
Save