Browse Source

Velmi velmi nedodělané generování pandoc-like LaTeXu, see #22.

pull/28/head
Jan Černohorský 1 year ago
parent
commit
6b60c313be
  1. 7
      src/formatitko/html_generator.py
  2. 95
      src/formatitko/latex_generator.py
  3. 7
      src/formatitko/output_generator.py

7
src/formatitko/html_generator.py

@ -32,7 +32,7 @@ class HTMLGenerator(OutputGenerator):
return return
super().generate(e) super().generate(e)
def htmlescapespecialchars(self, text: str) -> str: def escape_special_chars(self, text: str) -> str:
text = re.sub(re.compile(r"&"), "&", text) text = re.sub(re.compile(r"&"), "&", text)
text = re.sub(re.compile(r"<"), "&lt;", text) text = re.sub(re.compile(r"<"), "&lt;", text)
text = re.sub(re.compile(r">"), "&rt;", text) text = re.sub(re.compile(r">"), "&rt;", text)
@ -44,7 +44,7 @@ class HTMLGenerator(OutputGenerator):
def stag(self, tag: str, attributes: Dict[str,str]={}) -> str: def stag(self, tag: str, attributes: Dict[str,str]={}) -> str:
words = [tag] words = [tag]
for key, value in attributes.items(): for key, value in attributes.items():
words.append(f"{key}=\"{self.htmlescapespecialchars(value)}\"") words.append(f"{key}=\"{self.escape_special_chars(value)}\"")
return "<" + " ".join(words) + ">" return "<" + " ".join(words) + ">"
def etag(self, tag: str, attributes: Dict[str,str]={}) -> str: def etag(self, tag: str, attributes: Dict[str,str]={}) -> str:
@ -91,9 +91,6 @@ class HTMLGenerator(OutputGenerator):
attributes["class"] = " ".join(e.classes) attributes["class"] = " ".join(e.classes)
return attributes return attributes
def generate_Str(self, e: Str):
self.write(self.htmlescapespecialchars(e.text))
def generate_NBSP(self, e: NBSP): def generate_NBSP(self, e: NBSP):
self.write(" ") # Unicode no-break space, because we trust unicode? self.write(" ") # Unicode no-break space, because we trust unicode?

95
src/formatitko/latex_generator.py

@ -0,0 +1,95 @@
from panflute import Element, ListContainer, Inline, Block
from panflute import Cite, Code, Emph, Image, LineBreak, Link, Math, Note, Quoted, RawInline, SmallCaps, SoftBreak, Space, Span, Str, Strikeout, Strong, Subscript, Superscript, Underline
from panflute import BlockQuote, BulletList, Citation, CodeBlock, Definition, DefinitionItem, DefinitionList, Div, Figure, Header, HorizontalRule, LineBlock, LineItem, ListItem, MetaBlocks, MetaBool, MetaInlines, MetaList, MetaMap, MetaString, Null, OrderedList, Para, Plain, RawBlock, Table, TableBody, TableFoot, TableHead
from panflute import TableRow, TableCell, Caption, Doc
from typing import Union, Dict
from .whitespace import NBSP
from .transform import FQuoted
from .context import Group
from .output_generator import OutputGenerator
from .images import ImageProcessor
import re
class LaTeXGenerator(OutputGenerator):
def __init__(self, output_file, imageProcessor: ImageProcessor, *args, **kwargs):
self.imageProcessor = imageProcessor
super().__init__(outpout_file, *args, **kwargs)
def generate(self, e: Union[Element, ListContainer]):
if hasattr(e, "attributes") and "only" in e.attributes and e.attributes["only"] != "tex":
return
super().generate(e)
def escape_special_chars(self, text: str) -> str:
text = re.sub(re.compile(r"&"), "\\&", text)
text = re.sub(re.compile(r"%"), "\\%", text)
text = re.sub(re.compile(r"\$"), "\\$", text)
text = re.sub(re.compile(r"#"), "\\#", text)
text = re.sub(re.compile(r"_"), "\\_", text)
text = re.sub(re.compile(r"\{"), "\\{", text)
text = re.sub(re.compile(r"\}"), "\\}", text)
text = re.sub(re.compile(r"~"), "\\textasciitilde{}", text)
text = re.sub(re.compile(r"\^"), "\\textasciicircum{}", text)
text = re.sub(re.compile(r"\\"), "\\textbackslash{}", text)
text = re.sub(re.compile(r" "), "~", text) # We use unicode no-break spaces to force nbsp in output
return text
def stag(self, tag: str, attributes: Dict[str,str]={}) -> str:
return "\\" + tag + "{"
def etag(self, tag: str, attributes: Dict[str,str]={}) -> str:
return "}"
def ntag(self, tag: str, attributes: Dict[str,str]={}) -> str:
return "\\" + tag + "{}"
def generate_NBSP(self, e: NBSP):
self.write("~")
def generate_Null(self, e: Null):
pass
def generate_LineBreak(self, e: LineBreak):
self.write("\\\\")
self.endln()
def generate_Para(self, e: Para):
self.generate(e)
self.endln()
def generate_Header(self, e: Header):
tag = {
1: "section",
2: "subsection",
3: "subsubsection",
4: "paragraph",
5: "subparagraph",
6: "textbf"
}
self.generate_simple_block_tag(e, tag[e.level])
def generate_HorizontalRule(self, e: HorizontalRule):
self.writeln("\\begin{center}\\rule{0.5\\linewidth}{0.5pt}\\end{center}")
# These are also disabled in pandoc so they shouldn't appear in the AST at all.
def generate_Citation(self, e: Citation):
self.writeln("% FIXME: Citations not implemented")
def generate_Cite(self, e: Cite):
self.writeln("% FIXME: Cites not implemented")
def generate_Definition(self, e: Definition):
self.writeln("% FIXME: Definitions not implemented")
def generate_DefinitionItem(self, e: DefinitionItem):
self.writeln("% FIXME: DefinitionItems not implemented")
def generate_DefinitionList(self, e: DefinitionList):
self.writeln("% FIXME: DefinitionLists not implemented")

7
src/formatitko/output_generator.py

@ -8,6 +8,8 @@ from .whitespace import NBSP
from .transform import FQuoted from .transform import FQuoted
from .context import Group from .context import Group
import re
class UnknownElementError(Exception): class UnknownElementError(Exception):
"An unknown Element has been passed to the Output_generator, probably because panflute introduced a new one." "An unknown Element has been passed to the Output_generator, probably because panflute introduced a new one."
pass pass
@ -19,6 +21,9 @@ class OutputGenerator:
self.indent_level = initial_indent_level self.indent_level = initial_indent_level
self._at_start_of_line = True self._at_start_of_line = True
def escape_special_chars(self, text: str) -> str:
return text
def indent(self) -> str: def indent(self) -> str:
return self.indent_str*self.indent_level return self.indent_str*self.indent_level
@ -118,7 +123,7 @@ class OutputGenerator:
}[type(e)](e) }[type(e)](e)
def generate_Str(self, e: Str): def generate_Str(self, e: Str):
self.write(e.text) self.write(self.escape_special_chars(e.text))
def generate_Space(self, e: Space): def generate_Space(self, e: Space):
self.write(" ") self.write(" ")

Loading…
Cancel
Save