Přidány InlineGroups, metadatum language
přejmenováno na lang
, unifikován handling jazyka. #21
This commit is contained in:
parent
4a301b8b29
commit
0c2ce7d56c
10 changed files with 72 additions and 41 deletions
|
@ -1,4 +1,4 @@
|
||||||
from panflute import Doc, Element, Div
|
from panflute import Doc, Element, Div, Span
|
||||||
|
|
||||||
from typing import Union, Callable
|
from typing import Union, Callable
|
||||||
from types import ModuleType
|
from types import ModuleType
|
||||||
|
@ -79,8 +79,6 @@ class Context:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def set_metadata(self, key: str, value):
|
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
|
meta = self.doc.metadata
|
||||||
keys = key.split(".")
|
keys = key.split(".")
|
||||||
for k in keys[:-1]:
|
for k in keys[:-1]:
|
||||||
|
@ -99,9 +97,14 @@ class Context:
|
||||||
# and also causes KaTeX math blocks to be isolated in a similar way.
|
# 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.
|
# 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):
|
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
|
self.context = context
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
class BlockGroup(Group, Div):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class InlineGroup(Group, Span):
|
||||||
|
pass
|
||||||
|
|
|
@ -2,7 +2,7 @@ from panflute import Quoted
|
||||||
|
|
||||||
|
|
||||||
from .command import Command, InlineCommand, BlockCommand
|
from .command import Command, InlineCommand, BlockCommand
|
||||||
from .context import Group
|
from .context import Group, BlockGroup, InlineGroup
|
||||||
from .whitespace import Whitespace, NBSP
|
from .whitespace import Whitespace, NBSP
|
||||||
|
|
||||||
# This is a small extension to the Quoted panflute elements which allows to
|
# This is a small extension to the Quoted panflute elements which allows to
|
||||||
|
|
|
@ -6,7 +6,7 @@ import sys
|
||||||
# Import local files
|
# Import local files
|
||||||
from .transform import transform
|
from .transform import transform
|
||||||
from .util import import_md
|
from .util import import_md
|
||||||
from .context import Context, Group
|
from .context import Context, BlockGroup
|
||||||
from .katex import KatexClient
|
from .katex import KatexClient
|
||||||
from .html import html
|
from .html import html
|
||||||
from .tex import tex
|
from .tex import tex
|
||||||
|
@ -41,7 +41,7 @@ def main():
|
||||||
|
|
||||||
# The language metadatum is important, so it's read before transformation and
|
# The language metadatum is important, so it's read before transformation and
|
||||||
# then attached to a group inside the Doc
|
# 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)
|
context = Context(doc1, args.input_filename)
|
||||||
|
|
||||||
# Transform the document. This includes all the fancy formatting this software does.
|
# 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
|
# Now wrap the document contents in a group, which is able to pop its language
|
||||||
# setting out to TeX
|
# 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)
|
doc2 = TransformProcessor(args.input_filename).transform(doc2)
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ from pygments.formatters import HtmlFormatter
|
||||||
from pygments.util import ClassNotFound
|
from pygments.util import ClassNotFound
|
||||||
|
|
||||||
from .whitespace import NBSP
|
from .whitespace import NBSP
|
||||||
from .context import Group
|
from .context import Group, BlockGroup, InlineGroup
|
||||||
from .output_generator import OutputGenerator
|
from .output_generator import OutputGenerator
|
||||||
from .katex import KatexClient
|
from .katex import KatexClient
|
||||||
from .images import ImageProcessor
|
from .images import ImageProcessor
|
||||||
|
@ -78,6 +78,8 @@ class HTMLGenerator(OutputGenerator):
|
||||||
TableFoot: "tfoot",
|
TableFoot: "tfoot",
|
||||||
TableRow: "tr",
|
TableRow: "tr",
|
||||||
TableCell: "td",
|
TableCell: "td",
|
||||||
|
InlineGroup: "span",
|
||||||
|
BlockGroup: "div"
|
||||||
}[type(e)]
|
}[type(e)]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
return type(e).__name__.lower()
|
return type(e).__name__.lower()
|
||||||
|
@ -193,9 +195,15 @@ class HTMLGenerator(OutputGenerator):
|
||||||
|
|
||||||
self.generate(link)
|
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):
|
def generate_Group(self, e: Group):
|
||||||
self.katexClient.begingroup()
|
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()
|
self.katexClient.endgroup()
|
||||||
|
|
||||||
def generate_Plain(self, e: Plain):
|
def generate_Plain(self, e: Plain):
|
||||||
|
|
|
@ -6,7 +6,7 @@ from typing import Union
|
||||||
|
|
||||||
from .whitespace import NBSP
|
from .whitespace import NBSP
|
||||||
from .elements import FQuoted
|
from .elements import FQuoted
|
||||||
from .context import Group
|
from .context import Group, InlineGroup, BlockGroup
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ class OutputGenerator:
|
||||||
TableBody: self.generate_TableBody,
|
TableBody: self.generate_TableBody,
|
||||||
TableFoot: self.generate_TableFoot,
|
TableFoot: self.generate_TableFoot,
|
||||||
TableHead: self.generate_TableHead,
|
TableHead: self.generate_TableHead,
|
||||||
Group: self.generate_Group
|
BlockGroup: self.generate_BlockGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
self.TYPE_DICT_INLINE = {
|
self.TYPE_DICT_INLINE = {
|
||||||
|
@ -84,7 +84,8 @@ class OutputGenerator:
|
||||||
Superscript: self.generate_Superscript,
|
Superscript: self.generate_Superscript,
|
||||||
Underline: self.generate_Underline,
|
Underline: self.generate_Underline,
|
||||||
NBSP: self.generate_NBSP,
|
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]]]):
|
def generate(self, e: Union[Element, ListContainer, list[Union[Element, ListContainer]]]):
|
||||||
|
@ -408,9 +409,12 @@ class OutputGenerator:
|
||||||
def generate_Doc(self, e: Doc):
|
def generate_Doc(self, e: Doc):
|
||||||
self.generate_simple_tag(e)
|
self.generate_simple_tag(e)
|
||||||
|
|
||||||
def generate_Group(self, e: Group):
|
def generate_BlockGroup(self, e: BlockGroup):
|
||||||
self.generate_simple_tag(e)
|
self.generate_simple_tag(e)
|
||||||
|
|
||||||
|
def generate_InlineGroup(self, e: InlineGroup):
|
||||||
|
self.generate_simple_tag(e)
|
||||||
|
|
||||||
# Special elements with more contents
|
# Special elements with more contents
|
||||||
def generate_Table(self, e: Table):
|
def generate_Table(self, e: Table):
|
||||||
self.generate_simple_tag(e, content=[e.head, e.content, e.foot])
|
self.generate_simple_tag(e, content=[e.head, e.content, e.foot])
|
||||||
|
|
|
@ -247,8 +247,8 @@ def tex(e: Union[Element, ListContainer], i: ImageProcessor, indent_level: int=0
|
||||||
elif isinstance(e, Group):
|
elif isinstance(e, Group):
|
||||||
tag = "begingroup"
|
tag = "begingroup"
|
||||||
open = ""
|
open = ""
|
||||||
if "language" in e.metadata and e.metadata["language"] is not None:
|
if "lang" in e.metadata and e.metadata["lang"] is not None:
|
||||||
open = "\\language"+e.metadata["language"]
|
open = "\\language"+e.metadata["lang"]
|
||||||
close = "\\endgroup"
|
close = "\\endgroup"
|
||||||
|
|
||||||
# The default which all non-overriding elements get generated by. This
|
# The default which all non-overriding elements get generated by. This
|
||||||
|
|
|
@ -5,7 +5,7 @@ import os
|
||||||
# Import local files
|
# Import local files
|
||||||
from .whitespace import Whitespace, NBSP, bavlna
|
from .whitespace import Whitespace, NBSP, bavlna
|
||||||
from .util import nullify, import_md
|
from .util import nullify, import_md
|
||||||
from .context import Context, Group
|
from .context import Context, BlockGroup
|
||||||
from .command import Command, BlockCommand, InlineCommand
|
from .command import Command, BlockCommand, InlineCommand
|
||||||
from .command_util import handle_command_define, parse_command
|
from .command_util import handle_command_define, parse_command
|
||||||
from .elements import FQuoted
|
from .elements import FQuoted
|
||||||
|
@ -70,9 +70,9 @@ def transform(e: Element, c: Context) -> Element:
|
||||||
if not c.trusted:
|
if not c.trusted:
|
||||||
trusted = False
|
trusted = False
|
||||||
nContext = Context(includedDoc, path, c, trusted=trusted)
|
nContext = Context(includedDoc, path, c, trusted=trusted)
|
||||||
language = includedDoc.get_metadata("language")
|
language = includedDoc.get_metadata("lang")
|
||||||
includedDoc = includedDoc.walk(transform, nContext)
|
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.
|
# Transform panflute's Quoted to custom FQuoted, see above.
|
||||||
if isinstance(e, Quoted):
|
if isinstance(e, Quoted):
|
||||||
|
@ -82,7 +82,7 @@ def transform(e: Element, c: Context) -> Element:
|
||||||
"sk": "cs",
|
"sk": "cs",
|
||||||
None: None
|
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):
|
if isinstance(e, Image):
|
||||||
# Pass down the directory of the current source file for finding image
|
# Pass down the directory of the current source file for finding image
|
||||||
|
|
|
@ -6,10 +6,11 @@ from typing import Union, Callable
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
import warnings
|
||||||
|
|
||||||
from .whitespace import NBSP
|
from .whitespace import NBSP
|
||||||
from .elements import FQuoted
|
from .elements import FQuoted
|
||||||
from .context import Group
|
from .context import Group, InlineGroup, BlockGroup
|
||||||
from .util import nullify, import_md
|
from .util import nullify, import_md
|
||||||
from .context import Context
|
from .context import Context
|
||||||
from .whitespace import Whitespace, bavlna
|
from .whitespace import Whitespace, bavlna
|
||||||
|
@ -69,6 +70,8 @@ class TransformProcessor:
|
||||||
TableFoot: self.transform_TableFoot,
|
TableFoot: self.transform_TableFoot,
|
||||||
TableHead: self.transform_TableHead,
|
TableHead: self.transform_TableHead,
|
||||||
Group: self.transform_Group,
|
Group: self.transform_Group,
|
||||||
|
InlineGroup: self.transform_InlineGroup,
|
||||||
|
BlockGroup: self.transform_BlockGroup,
|
||||||
|
|
||||||
Cite: self.transform_Cite,
|
Cite: self.transform_Cite,
|
||||||
Code: self.transform_Code,
|
Code: self.transform_Code,
|
||||||
|
@ -253,6 +256,14 @@ class TransformProcessor:
|
||||||
e.content = self.transform(e.content)
|
e.content = self.transform(e.content)
|
||||||
return e
|
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:
|
def transform_Cite(self, e: Cite) -> Cite:
|
||||||
e.content = self.transform(e.content)
|
e.content = self.transform(e.content)
|
||||||
return e
|
return e
|
||||||
|
@ -314,7 +325,7 @@ class TransformProcessor:
|
||||||
raise DoubleDocError()
|
raise DoubleDocError()
|
||||||
self.context = Context(e, self.root_file_path)
|
self.context = Context(e, self.root_file_path)
|
||||||
e.content = self.transform(e.content)
|
e.content = self.transform(e.content)
|
||||||
e.content = [Group(*e.content, context=self.context)]
|
e.content = [BlockGroup(*e.content, context=self.context)]
|
||||||
return e
|
return e
|
||||||
|
|
||||||
|
|
||||||
|
@ -326,7 +337,7 @@ class TransformProcessor:
|
||||||
"sk": "cs",
|
"sk": "cs",
|
||||||
None: None
|
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:
|
def transform_Image(self, e: Image) -> Image:
|
||||||
e.content = self.transform(e.content)
|
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
|
e.attributes["no-srcset"] = self.context.get_metadata("no-srcset") if self.context.get_metadata("no-srcset") is not None else False
|
||||||
return e
|
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
|
old_context = self.context
|
||||||
self.context = new_context
|
self.context = new_context
|
||||||
content = self.transform([*content])
|
content = self.transform([*content])
|
||||||
self.context = old_context
|
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]:
|
def transform_Div(self, e: Div) -> Union[Div, Group, Null]:
|
||||||
e.content = self.transform(e.content)
|
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
|
# 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)
|
new_context = Context(Doc(), self.context.path, self.context, trusted=self.context.trusted)
|
||||||
for attribute, value in e.attributes.items():
|
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)
|
return self.create_Group(*e.content, new_context=new_context)
|
||||||
|
|
||||||
if "c" in e.attributes:
|
if "c" in e.attributes:
|
||||||
|
@ -383,19 +397,22 @@ class TransformProcessor:
|
||||||
trusted = False
|
trusted = False
|
||||||
return self.create_Group(*includedDoc.content, new_context=Context(includedDoc, path, self.context, trusted=trusted))
|
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
|
return e
|
||||||
|
|
||||||
def transform_Span(self, e: Span) -> Span:
|
def transform_Span(self, e: Span) -> Span:
|
||||||
e.content = self.transform(e.content)
|
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.
|
# TODO: This sadly doesn't work. We would need to create a separate class InlineGroup, that would be Inline.
|
||||||
#if "group" in e.classes:
|
if "group" in e.classes:
|
||||||
# # `.group` class for Spans
|
# `.group` class for Spans
|
||||||
# # Content of Span is enclosed in a separate context, all attributes are passed as metadata
|
# 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)
|
new_context = Context(Doc(), self.context.path, self.context, trusted=self.context.trusted)
|
||||||
# for attribute, value in e.attributes.items():
|
for attribute, value in e.attributes.items():
|
||||||
# new_context.set_metadata(attribute, value)
|
new_context.set_metadata(attribute, value)
|
||||||
# return self.create_Group(*e.content, new_context=new_context)
|
return self.create_Group(*e.content, new_context=new_context, inline=True)
|
||||||
|
|
||||||
if "c" in e.attributes:
|
if "c" in e.attributes:
|
||||||
# Commands can be called multiple ways, this handles the following syntax:
|
# Commands can be called multiple ways, this handles the following syntax:
|
||||||
|
|
|
@ -30,14 +30,14 @@ return [
|
||||||
|
|
||||||
```markdown {.group}
|
```markdown {.group}
|
||||||
---
|
---
|
||||||
language: "cs"
|
lang: "cs"
|
||||||
---
|
---
|
||||||
Tak toto je "v prádelně" pánové!
|
Tak toto je "v prádelně" pánové!
|
||||||
```
|
```
|
||||||
|
|
||||||
```markdown {.group}
|
```markdown {.group}
|
||||||
---
|
---
|
||||||
language: "en"
|
lang: "en"
|
||||||
---
|
---
|
||||||
This is "in a laundry room" gentlemen!
|
This is "in a laundry room" gentlemen!
|
||||||
```
|
```
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
title: 'Wooooo a title'
|
title: 'Wooooo a title'
|
||||||
subtitle: 'A subtitle'
|
subtitle: 'A subtitle'
|
||||||
are_we_there_yet: False
|
are_we_there_yet: False
|
||||||
language: "en"
|
|
||||||
lang: "en"
|
lang: "en"
|
||||||
---
|
---
|
||||||
[#test-files/test-import.md]{}
|
[#test-files/test-import.md]{}
|
||||||
|
@ -56,7 +55,7 @@ This should only be shown to cats the second time
|
||||||
|
|
||||||
```markdown {.group}
|
```markdown {.group}
|
||||||
---
|
---
|
||||||
language: cs
|
lang: cs
|
||||||
---
|
---
|
||||||
V​ pravém jízdním bruhu.
|
V​ pravém jízdním bruhu.
|
||||||
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
|
maybe even
|
||||||
|
|
||||||
:::{.group language=cs}
|
:::{.group lang=cs}
|
||||||
celé pasáže textu v češtině.
|
celé pasáže textu v češtině.
|
||||||
|
|
||||||
Růžový bagr bez zeleného bagru se žlutým bagrem.
|
Růžový bagr bez zeleného bagru se žlutým bagrem.
|
||||||
|
|
Loading…
Reference in a new issue