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,7 +409,10 @@ 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) | ||||||
|  | 
 | ||||||
|  | 	def generate_InlineGroup(self, e: InlineGroup): | ||||||
| 		self.generate_simple_tag(e) | 		self.generate_simple_tag(e) | ||||||
| 
 | 
 | ||||||
| 	# Special elements with more contents | 	# Special elements with more contents | ||||||
|  |  | ||||||
|  | @ -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