diff --git a/src/formatitko/context.py b/src/formatitko/context.py index 9eac008..adaa9da 100644 --- a/src/formatitko/context.py +++ b/src/formatitko/context.py @@ -1,4 +1,4 @@ -from panflute import Doc, Element, Div +from panflute import Doc, Element, Div, Span from typing import Union, Callable from types import ModuleType @@ -79,8 +79,6 @@ class Context: return None def set_metadata(self, key: str, value): - if key == "language": - warnings.warn("Setting language this way doesn't propagate to TeX. Either use the Front Matter or specify it additionally using the \\languagexx macro.", UserWarning) meta = self.doc.metadata keys = key.split(".") for k in keys[:-1]: @@ -99,9 +97,14 @@ class Context: # and also causes KaTeX math blocks to be isolated in a similar way. # # Whenever a new context is created, its content should be eclosed in a group and vice-versa. -class Group(Div): +class Group(Element): def __init__(self, *args, context:Context, metadata={}, **kwargs): - self.metadata = metadata + self.metadata = metadata # This is only here for backwards compatibility with old html.py, tex.py and transform.py. FIXME: Remove this when the time comes. self.context = context super().__init__(*args, **kwargs) +class BlockGroup(Group, Div): + pass + +class InlineGroup(Group, Span): + pass diff --git a/src/formatitko/elements.py b/src/formatitko/elements.py index 25aea17..9915f15 100644 --- a/src/formatitko/elements.py +++ b/src/formatitko/elements.py @@ -2,7 +2,7 @@ from panflute import Quoted from .command import Command, InlineCommand, BlockCommand -from .context import Group +from .context import Group, BlockGroup, InlineGroup from .whitespace import Whitespace, NBSP # This is a small extension to the Quoted panflute elements which allows to diff --git a/src/formatitko/formatitko.py b/src/formatitko/formatitko.py index a31931a..770984a 100755 --- a/src/formatitko/formatitko.py +++ b/src/formatitko/formatitko.py @@ -6,7 +6,7 @@ import sys # Import local files from .transform import transform from .util import import_md -from .context import Context, Group +from .context import Context, BlockGroup from .katex import KatexClient from .html import html from .tex import tex @@ -41,7 +41,7 @@ def main(): # The language metadatum is important, so it's read before transformation and # then attached to a group inside the Doc - language = doc1.get_metadata("language", None, True) + language = doc1.get_metadata("lang", None, True) context = Context(doc1, args.input_filename) # Transform the document. This includes all the fancy formatting this software does. @@ -49,7 +49,7 @@ def main(): # Now wrap the document contents in a group, which is able to pop its language # setting out to TeX - doc1.content = [Group(*doc1.content, context=context, metadata={"language":language})] + doc1.content = [BlockGroup(*doc1.content, context=context, metadata={"lang":language})] doc2 = TransformProcessor(args.input_filename).transform(doc2) diff --git a/src/formatitko/html_generator.py b/src/formatitko/html_generator.py index f366998..a579d3f 100644 --- a/src/formatitko/html_generator.py +++ b/src/formatitko/html_generator.py @@ -14,7 +14,7 @@ from pygments.formatters import HtmlFormatter from pygments.util import ClassNotFound from .whitespace import NBSP -from .context import Group +from .context import Group, BlockGroup, InlineGroup from .output_generator import OutputGenerator from .katex import KatexClient from .images import ImageProcessor @@ -78,6 +78,8 @@ class HTMLGenerator(OutputGenerator): TableFoot: "tfoot", TableRow: "tr", TableCell: "td", + InlineGroup: "span", + BlockGroup: "div" }[type(e)] except KeyError: return type(e).__name__.lower() @@ -193,9 +195,15 @@ class HTMLGenerator(OutputGenerator): self.generate(link) + def generate_InlineGroup(self, e: InlineGroup): + self.generate_Group(e) + + def generate_BlockGroup(self, e: BlockGroup): + self.generate_Group(e) + def generate_Group(self, e: Group): self.katexClient.begingroup() - self.generate(e.content) + self.generate_simple_tag(e, attributes=self.common_attributes(e) | {"lang":self.context.get_metadata("lang")}) self.katexClient.endgroup() def generate_Plain(self, e: Plain): diff --git a/src/formatitko/output_generator.py b/src/formatitko/output_generator.py index b898365..0fc973c 100644 --- a/src/formatitko/output_generator.py +++ b/src/formatitko/output_generator.py @@ -6,7 +6,7 @@ from typing import Union from .whitespace import NBSP from .elements import FQuoted -from .context import Group +from .context import Group, InlineGroup, BlockGroup import re @@ -59,7 +59,7 @@ class OutputGenerator: TableBody: self.generate_TableBody, TableFoot: self.generate_TableFoot, TableHead: self.generate_TableHead, - Group: self.generate_Group + BlockGroup: self.generate_BlockGroup } self.TYPE_DICT_INLINE = { @@ -84,7 +84,8 @@ class OutputGenerator: Superscript: self.generate_Superscript, Underline: self.generate_Underline, NBSP: self.generate_NBSP, - FQuoted: self.generate_FQuoted + FQuoted: self.generate_FQuoted, + InlineGroup: self.generate_InlineGroup } def generate(self, e: Union[Element, ListContainer, list[Union[Element, ListContainer]]]): @@ -408,9 +409,12 @@ class OutputGenerator: def generate_Doc(self, e: Doc): self.generate_simple_tag(e) - def generate_Group(self, e: Group): + def generate_BlockGroup(self, e: BlockGroup): self.generate_simple_tag(e) - + + def generate_InlineGroup(self, e: InlineGroup): + self.generate_simple_tag(e) + # Special elements with more contents def generate_Table(self, e: Table): self.generate_simple_tag(e, content=[e.head, e.content, e.foot]) diff --git a/src/formatitko/tex.py b/src/formatitko/tex.py index 23a2d62..74b6e6f 100644 --- a/src/formatitko/tex.py +++ b/src/formatitko/tex.py @@ -247,8 +247,8 @@ def tex(e: Union[Element, ListContainer], i: ImageProcessor, indent_level: int=0 elif isinstance(e, Group): tag = "begingroup" open = "" - if "language" in e.metadata and e.metadata["language"] is not None: - open = "\\language"+e.metadata["language"] + if "lang" in e.metadata and e.metadata["lang"] is not None: + open = "\\language"+e.metadata["lang"] close = "\\endgroup" # The default which all non-overriding elements get generated by. This diff --git a/src/formatitko/transform.py b/src/formatitko/transform.py index 83601de..92c820e 100644 --- a/src/formatitko/transform.py +++ b/src/formatitko/transform.py @@ -5,7 +5,7 @@ import os # Import local files from .whitespace import Whitespace, NBSP, bavlna from .util import nullify, import_md -from .context import Context, Group +from .context import Context, BlockGroup from .command import Command, BlockCommand, InlineCommand from .command_util import handle_command_define, parse_command from .elements import FQuoted @@ -70,9 +70,9 @@ def transform(e: Element, c: Context) -> Element: if not c.trusted: trusted = False nContext = Context(includedDoc, path, c, trusted=trusted) - language = includedDoc.get_metadata("language") + language = includedDoc.get_metadata("lang") includedDoc = includedDoc.walk(transform, nContext) - e = Group(*includedDoc.content, context=nContext, metadata={"language": language}) + e = BlockGroup(*includedDoc.content, context=nContext, metadata={"lang": language}) # Transform panflute's Quoted to custom FQuoted, see above. if isinstance(e, Quoted): @@ -82,7 +82,7 @@ def transform(e: Element, c: Context) -> Element: "sk": "cs", None: None } - e = FQuoted(*e.content, quote_type=e.quote_type, style=quote_styles[c.get_metadata("language")]) + e = FQuoted(*e.content, quote_type=e.quote_type, style=quote_styles[c.get_metadata("lang")]) if isinstance(e, Image): # Pass down the directory of the current source file for finding image diff --git a/src/formatitko/transform_processor.py b/src/formatitko/transform_processor.py index b0032cf..998e6a9 100644 --- a/src/formatitko/transform_processor.py +++ b/src/formatitko/transform_processor.py @@ -6,10 +6,11 @@ from typing import Union, Callable import os import re +import warnings from .whitespace import NBSP from .elements import FQuoted -from .context import Group +from .context import Group, InlineGroup, BlockGroup from .util import nullify, import_md from .context import Context from .whitespace import Whitespace, bavlna @@ -69,6 +70,8 @@ class TransformProcessor: TableFoot: self.transform_TableFoot, TableHead: self.transform_TableHead, Group: self.transform_Group, + InlineGroup: self.transform_InlineGroup, + BlockGroup: self.transform_BlockGroup, Cite: self.transform_Cite, Code: self.transform_Code, @@ -253,6 +256,14 @@ class TransformProcessor: e.content = self.transform(e.content) return e + def transform_InlineGroup(self, e: InlineGroup) -> InlineGroup: + e.content = self.transform(e.content) + return e + + def transform_BlockGroup(self, e: BlockGroup) -> BlockGroup: + e.content = self.transform(e.content) + return e + def transform_Cite(self, e: Cite) -> Cite: e.content = self.transform(e.content) return e @@ -314,7 +325,7 @@ class TransformProcessor: raise DoubleDocError() self.context = Context(e, self.root_file_path) e.content = self.transform(e.content) - e.content = [Group(*e.content, context=self.context)] + e.content = [BlockGroup(*e.content, context=self.context)] return e @@ -326,7 +337,7 @@ class TransformProcessor: "sk": "cs", None: None } - return FQuoted(*e.content, quote_type=e.quote_type, style=quote_styles[self.context.get_metadata("language")]) + return FQuoted(*e.content, quote_type=e.quote_type, style=quote_styles[self.context.get_metadata("lang")]) def transform_Image(self, e: Image) -> Image: e.content = self.transform(e.content) @@ -340,12 +351,15 @@ class TransformProcessor: e.attributes["no-srcset"] = self.context.get_metadata("no-srcset") if self.context.get_metadata("no-srcset") is not None else False return e - def create_Group(self, *content, new_context: Context) -> Group: + def create_Group(self, *content, new_context: Context, inline: bool=False) -> Group: old_context = self.context self.context = new_context content = self.transform([*content]) self.context = old_context - return Group(*content, context=new_context) + if inline: + return InlineGroup(*content, context=new_context) + else: + return BlockGroup(*content, context=new_context) def transform_Div(self, e: Div) -> Union[Div, Group, Null]: e.content = self.transform(e.content) @@ -355,7 +369,7 @@ class TransformProcessor: # Content of Div is enclosed in a separate context, all attributes are passed as metadata new_context = Context(Doc(), self.context.path, self.context, trusted=self.context.trusted) for attribute, value in e.attributes.items(): - new_context.set_metadata(attribute, value) # FIXME: This raises a warning when done with `language`. Since context is available to OG, we should trash the warning and rework the OG to use the Context. + new_context.set_metadata(attribute, value) return self.create_Group(*e.content, new_context=new_context) if "c" in e.attributes: @@ -383,19 +397,22 @@ class TransformProcessor: trusted = False return self.create_Group(*includedDoc.content, new_context=Context(includedDoc, path, self.context, trusted=trusted)) + if "lang" in e.attributes: + warnings.warn("To set language in a way formátítko will understand, this Div has to have the `.group` class and be a Group.", UserWarning) + return e def transform_Span(self, e: Span) -> Span: e.content = self.transform(e.content) # TODO: This sadly doesn't work. We would need to create a separate class InlineGroup, that would be Inline. - #if "group" in e.classes: - # # `.group` class for Spans - # # Content of Span is enclosed in a separate context, all attributes are passed as metadata - # new_context = Context(Doc(), self.context.path, self.context, trusted=self.context.trusted) - # for attribute, value in e.attributes.items(): - # new_context.set_metadata(attribute, value) - # return self.create_Group(*e.content, new_context=new_context) + if "group" in e.classes: + # `.group` class for Spans + # Content of Span is enclosed in a separate context, all attributes are passed as metadata + new_context = Context(Doc(), self.context.path, self.context, trusted=self.context.trusted) + for attribute, value in e.attributes.items(): + new_context.set_metadata(attribute, value) + return self.create_Group(*e.content, new_context=new_context, inline=True) if "c" in e.attributes: # Commands can be called multiple ways, this handles the following syntax: diff --git a/test/test-files/test-partial.md b/test/test-files/test-partial.md index 9e63376..db8ae8e 100644 --- a/test/test-files/test-partial.md +++ b/test/test-files/test-partial.md @@ -30,14 +30,14 @@ return [ ```markdown {.group} --- -language: "cs" +lang: "cs" --- Tak toto je "v prádelně" pánové! ``` ```markdown {.group} --- -language: "en" +lang: "en" --- This is "in a laundry room" gentlemen! ``` diff --git a/test/test.md b/test/test.md index 90eb111..8cafab2 100644 --- a/test/test.md +++ b/test/test.md @@ -2,7 +2,6 @@ title: 'Wooooo a title' subtitle: 'A subtitle' are_we_there_yet: False -language: "en" lang: "en" --- [#test-files/test-import.md]{} @@ -56,7 +55,7 @@ This should only be shown to cats the second time ```markdown {.group} --- -language: cs +lang: cs --- V​ pravém jízdním bruhu. V pravém jízdním bruhu. @@ -115,10 +114,10 @@ $$ --- -In this text, there might be some phrases [v češtině]{.group language=cs} and +In this text, there might be some phrases [v češtině]{.group lang=cs} and maybe even -:::{.group language=cs} +:::{.group lang=cs} celé pasáže textu v češtině. Růžový bagr bez zeleného bagru se žlutým bagrem.