Browse Source

Přidány InlineGroups, metadatum `language` přejmenováno na `lang`, unifikován handling jazyka. #21

citace
Jan Černohorský 9 months ago
parent
commit
0c2ce7d56c
  1. 13
      src/formatitko/context.py
  2. 2
      src/formatitko/elements.py
  3. 6
      src/formatitko/formatitko.py
  4. 12
      src/formatitko/html_generator.py
  5. 14
      src/formatitko/output_generator.py
  6. 4
      src/formatitko/tex.py
  7. 8
      src/formatitko/transform.py
  8. 43
      src/formatitko/transform_processor.py
  9. 4
      test/test-files/test-partial.md
  10. 7
      test/test.md

13
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

2
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

6
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)

12
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):

14
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])

4
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

8
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

43
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:

4
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!
```

7
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 <!-- Tohle nefunguje :( -->
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.

Loading…
Cancel
Save