Compare commits
No commits in common. "jk-bakalarka" and "master" have entirely different histories.
jk-bakalar
...
master
18 changed files with 98 additions and 546 deletions
2
.gitmodules
vendored
2
.gitmodules
vendored
|
@ -2,5 +2,5 @@
|
||||||
path = ucwmac
|
path = ucwmac
|
||||||
url = git://git.ucw.cz/ucwmac.git
|
url = git://git.ucw.cz/ucwmac.git
|
||||||
[submodule "src/formatitko/katex-server"]
|
[submodule "src/formatitko/katex-server"]
|
||||||
path = src/formatitko/katex_server
|
path = src/formatitko/katex-server
|
||||||
url = https://gitea.ks.matfyz.cz:/KSP/formatitko-katex-server
|
url = https://gitea.ks.matfyz.cz:/KSP/formatitko-katex-server
|
||||||
|
|
30
formatitko.tex
Normal file
30
formatitko.tex
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
\input luatex85.sty
|
||||||
|
\input ucwmac2.tex
|
||||||
|
\parskip=5pt plus 3pt minus 2pt
|
||||||
|
\parindent=0sp
|
||||||
|
|
||||||
|
\def\strong#1{{%
|
||||||
|
\def\emph##1{{\bi{}##1}}%
|
||||||
|
\bf{}#1%
|
||||||
|
}}
|
||||||
|
\def\emph#1{{%
|
||||||
|
\def\strong##1{{\bi{}##1}}%
|
||||||
|
\it{}#1%
|
||||||
|
}}
|
||||||
|
|
||||||
|
|
||||||
|
\def\superscript#1{\leavevmode\raise3pt\hbox{\fiverm#1}}
|
||||||
|
\def\subscript#1{\leavevmode\lower1pt\hbox{\fiverm#1}}
|
||||||
|
\newcount\fncount
|
||||||
|
\fncount=1
|
||||||
|
\def\fnmark{\superscript{\the\fncount}}
|
||||||
|
\def\fn#1{\footnote\fnmark{#1}\advance\fncount by 1}
|
||||||
|
\def\section#1{{\parskip1em\settextsize{18}\bf #1}}
|
||||||
|
\def\subsection#1{{\parskip1em\settextsize{16}\bf #1}}
|
||||||
|
\def\subsubsection#1{{\parskip1em\settextsize{14}\bf #1}}
|
||||||
|
\def\subsubsubsection#1{{\parskip1em\settextsize{12}\bf #1}}
|
||||||
|
\def\subsubsubsubsection#1{{\parskip1em\settextsize{10}\bf #1}}
|
||||||
|
\def\subsubsubsubsubsection#1{{\parskip1em\settextsize{10}\bi #1}}
|
||||||
|
\long\def\blockquote#1{\vskip\lineskip\vskip\parskip\hbox{\vrule\hskip5pt\vbox{#1}}}
|
||||||
|
\def\strikeout#1{FIXME: Strikeout not implemented}
|
||||||
|
\def\underline#1{FIXME: Underline not implemented}
|
|
@ -33,19 +33,11 @@ dependencies = [
|
||||||
[project.scripts]
|
[project.scripts]
|
||||||
formatitko = "formatitko.formatitko:main"
|
formatitko = "formatitko.formatitko:main"
|
||||||
|
|
||||||
[tool.setuptools.package-data]
|
|
||||||
"formatitko.katex_server" = [
|
|
||||||
"*",
|
|
||||||
"node_modules/*",
|
|
||||||
"node_modules/katex/*",
|
|
||||||
"node_modules/katex/src/*",
|
|
||||||
"node_modules/katex/dist/*",
|
|
||||||
]
|
|
||||||
|
|
||||||
[tool.setuptools_scm]
|
[tool.setuptools_scm]
|
||||||
|
|
||||||
[tool.setuptools.packages.find]
|
[tool.setuptools.packages.find]
|
||||||
where = ["src"]
|
where = ["src"]
|
||||||
|
exclude = ["src/formatitko/katex-server/node_modules"]
|
||||||
|
|
||||||
[tool.pyright]
|
[tool.pyright]
|
||||||
strictParameterNoneValue = false
|
strictParameterNoneValue = false
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from panflute import Doc, Element, Div, Span, Header, Figure
|
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
|
||||||
|
@ -19,23 +19,6 @@ CommandCallable = Callable[[Command, 'Context', 'NOPProcessor'], list[Element]]
|
||||||
#
|
#
|
||||||
# This class is basically an extension to panflute's doc, this is why metadata
|
# This class is basically an extension to panflute's doc, this is why metadata
|
||||||
# is read directly from it.
|
# is read directly from it.
|
||||||
def default_section_number_generator(e: Header, context: 'Context') -> list[Union[str, int]]:
|
|
||||||
l = e.level
|
|
||||||
section_counters = context.get_data("section_counters")
|
|
||||||
section_counters[l-1] += 1
|
|
||||||
for i in range(l, len(section_counters)):
|
|
||||||
section_counters[i] = 0
|
|
||||||
return list(section_counters[:l])
|
|
||||||
|
|
||||||
def default_figure_number_generator(e: Figure, context: 'Context') -> Union[str, int]:
|
|
||||||
figure_type = e.attributes.get("type", "img")
|
|
||||||
figure_counters = context.get_data("figure_counters")
|
|
||||||
figure_counters.setdefault(figure_type, 0)
|
|
||||||
figure_counters[figure_type] += 1
|
|
||||||
return figure_counters[figure_type]
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Context:
|
class Context:
|
||||||
parent: Union["Context", None]
|
parent: Union["Context", None]
|
||||||
_commands: dict[str, Union[CommandCallable, None]]
|
_commands: dict[str, Union[CommandCallable, None]]
|
||||||
|
@ -49,9 +32,6 @@ class Context:
|
||||||
rel_dir: str # Relative path to the current dir from the root dir
|
rel_dir: str # Relative path to the current dir from the root dir
|
||||||
deps: set[str]
|
deps: set[str]
|
||||||
|
|
||||||
section_counters: list[int]
|
|
||||||
number_generator: Callable[[Header, 'Context'], str]
|
|
||||||
|
|
||||||
def __init__(self, doc: Doc, path: str, parent: Union['Context', None]=None, trusted: bool=True):
|
def __init__(self, doc: Doc, path: str, parent: Union['Context', None]=None, trusted: bool=True):
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
self._commands = {}
|
self._commands = {}
|
||||||
|
@ -67,12 +47,6 @@ class Context:
|
||||||
self.add_dep(path)
|
self.add_dep(path)
|
||||||
if self.get_metadata("flags", immediate=True) is None:
|
if self.get_metadata("flags", immediate=True) is None:
|
||||||
self.set_metadata("flags", {})
|
self.set_metadata("flags", {})
|
||||||
if not parent:
|
|
||||||
self.set_data('section_number_generator', default_section_number_generator)
|
|
||||||
self.set_data('figure_number_generator', default_figure_number_generator)
|
|
||||||
self.set_data('section_counters', [0 for i in range(6)])
|
|
||||||
self.set_data('figure_counters', {})
|
|
||||||
self.set_data('obj_map', {})
|
|
||||||
|
|
||||||
def get_command(self, command: str) -> Union[CommandCallable, None]:
|
def get_command(self, command: str) -> Union[CommandCallable, None]:
|
||||||
if command in self._commands:
|
if command in self._commands:
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from panflute import Quoted, Emph, Link, Div
|
from panflute import Quoted, Link
|
||||||
|
|
||||||
|
|
||||||
from .command import Command, InlineCommand, BlockCommand, CodeCommand
|
from .command import Command, InlineCommand, BlockCommand, CodeCommand
|
||||||
|
@ -14,22 +14,6 @@ class FQuoted(Quoted):
|
||||||
del kwargs["style"]
|
del kwargs["style"]
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
class Slanted(Emph):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class FLink(Link):
|
|
||||||
obj_map: map
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
self.obj_map = kwargs["obj_map"]
|
|
||||||
del kwargs["obj_map"]
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
|
|
||||||
class FileLink(Link):
|
class FileLink(Link):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class FLineMarkup(Div):
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
self.color = kwargs["color"]
|
|
||||||
del kwargs["color"]
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,9 @@
|
||||||
|
|
||||||
import argparse
|
import argparse
|
||||||
import sys
|
import sys
|
||||||
import os
|
|
||||||
import tempfile
|
import tempfile
|
||||||
import subprocess
|
import subprocess
|
||||||
import shutil
|
import shutil
|
||||||
from pathlib import Path
|
|
||||||
|
|
||||||
# Import local files
|
# Import local files
|
||||||
from .util import import_md
|
from .util import import_md
|
||||||
|
@ -114,12 +112,7 @@ def main():
|
||||||
else:
|
else:
|
||||||
filename = args.output_tex
|
filename = args.output_tex
|
||||||
outdir = tempfile.TemporaryDirectory(prefix="formatitko")
|
outdir = tempfile.TemporaryDirectory(prefix="formatitko")
|
||||||
|
subprocess.run(["pdfcsplain", "-halt-on-error", "-output-directory="+outdir.name, "-jobname=formatitko", filename], check=True)
|
||||||
env = os.environ.copy()
|
|
||||||
d = Path("/".join(__file__.split("/")[:-1]))
|
|
||||||
env["TEXINPUTS"]=".:"+str(d/"tex")+":"+env.get("TEXINPUTS", "")
|
|
||||||
|
|
||||||
subprocess.run(["luatex", "-halt-on-error", "-output-directory="+outdir.name, "-jobname=formatitko", filename], check=True, env=env)
|
|
||||||
shutil.move(outdir.name+"/formatitko.pdf", args.output_pdf)
|
shutil.move(outdir.name+"/formatitko.pdf", args.output_pdf)
|
||||||
|
|
||||||
if args.deps is not None:
|
if args.deps is not None:
|
||||||
|
|
|
@ -111,7 +111,7 @@ class HTMLGenerator(OutputGenerator):
|
||||||
|
|
||||||
def generate_CodeBlock(self, e: CodeBlock):
|
def generate_CodeBlock(self, e: CodeBlock):
|
||||||
lexer = None
|
lexer = None
|
||||||
if e.classes and len(e.classes) > 0 and (e.attributes.get("highlight", False) in [True, 'True']):
|
if e.classes and len(e.classes) > 0 and (e.attributes["highlight"] == True or e.attributes["highlight"] == 'True'):
|
||||||
# Syntax highlighting using pygments
|
# Syntax highlighting using pygments
|
||||||
for cl in e.classes:
|
for cl in e.classes:
|
||||||
try:
|
try:
|
||||||
|
@ -123,7 +123,7 @@ class HTMLGenerator(OutputGenerator):
|
||||||
warnings.warn(f"Syntax highligher does not have lexer for element with these classes: {e.classes}", UserWarning)
|
warnings.warn(f"Syntax highligher does not have lexer for element with these classes: {e.classes}", UserWarning)
|
||||||
|
|
||||||
if lexer:
|
if lexer:
|
||||||
formatter = HtmlFormatter(style=e.attributes.get("style", self.context.get_metadata("highlight-style")), noclasses=True)
|
formatter = HtmlFormatter(style=e.attributes["style"], noclasses=True)
|
||||||
result = highlight(e.text, lexer, formatter)
|
result = highlight(e.text, lexer, formatter)
|
||||||
self.writeraw(result)
|
self.writeraw(result)
|
||||||
else:
|
else:
|
||||||
|
@ -344,9 +344,6 @@ class HTMLGenerator(OutputGenerator):
|
||||||
def generate_DefinitionList(self, e: DefinitionList):
|
def generate_DefinitionList(self, e: DefinitionList):
|
||||||
self.writeln("<!-- FIXME: DefinitionLists not implemented -->")
|
self.writeln("<!-- FIXME: DefinitionLists not implemented -->")
|
||||||
|
|
||||||
def generate_SmallCaps(self, e: SmallCaps):
|
|
||||||
self.generate_simple_tag(e, attributes=self.common_attributes(e) | {"style": "font-variant: small-caps;"})
|
|
||||||
|
|
||||||
|
|
||||||
class StandaloneHTMLGenerator(HTMLGenerator):
|
class StandaloneHTMLGenerator(HTMLGenerator):
|
||||||
def generate_Doc(self, e: Doc):
|
def generate_Doc(self, e: Doc):
|
||||||
|
|
|
@ -46,20 +46,20 @@ class KatexClient:
|
||||||
srcdir = os.path.dirname(os.path.realpath(__file__))
|
srcdir = os.path.dirname(os.path.realpath(__file__))
|
||||||
|
|
||||||
# Test if `node_modules` directory exists and if not, run `npm install`
|
# Test if `node_modules` directory exists and if not, run `npm install`
|
||||||
if not os.path.isdir(srcdir + "/katex_server/node_modules"):
|
if not os.path.isdir(srcdir + "/katex-server/node_modules"):
|
||||||
print("Installing node dependencies for the first time...")
|
print("Installing node dependencies for the first time...")
|
||||||
npm = shutil.which("npm") or shutil.which("yarnpkg")
|
npm = shutil.which("npm") or shutil.which("yarnpkg")
|
||||||
if npm is None:
|
if npm is None:
|
||||||
raise NPMNotFoundError("npm not found. Node.js is required to use KaTeX.")
|
raise NPMNotFoundError("npm not found. Node.js is required to use KaTeX.")
|
||||||
subprocess.run([npm, "install"], cwd=srcdir+"/katex_server", check=True)
|
subprocess.run([npm, "install"], cwd=srcdir+"/katex-server", check=True)
|
||||||
|
|
||||||
self._katex_server_path = srcdir + "/katex_server/index.mjs"
|
self._katex_server_path = srcdir + "/katex-server/index.mjs"
|
||||||
|
|
||||||
self._server_process = subprocess.Popen(["node", self._katex_server_path, self._socket_file], stdout=subprocess.PIPE)
|
self._server_process = subprocess.Popen(["node", self._katex_server_path, self._socket_file], stdout=subprocess.PIPE)
|
||||||
|
|
||||||
ok = self._server_process.stdout.readline()
|
ok = self._server_process.stdout.readline()
|
||||||
if ok != b"OK\n":
|
if ok != b"OK\n":
|
||||||
raise KatexServerError("Failed to connect to katex_server")
|
raise KatexServerError("Failed to connect to katex-server")
|
||||||
|
|
||||||
def connect(self):
|
def connect(self):
|
||||||
self._client = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
self._client = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||||
|
|
|
@ -6,7 +6,7 @@ from panflute import MetaValue
|
||||||
from typing import Union, Callable
|
from typing import Union, Callable
|
||||||
|
|
||||||
from .whitespace import NBSP
|
from .whitespace import NBSP
|
||||||
from .elements import FQuoted, Slanted, FLink, FileLink
|
from .elements import FQuoted, FileLink
|
||||||
from .context import Group, InlineGroup, BlockGroup, Context
|
from .context import Group, InlineGroup, BlockGroup, Context
|
||||||
from .whitespace import Whitespace
|
from .whitespace import Whitespace
|
||||||
from .command import BlockCommand, InlineCommand, CodeCommand, Command
|
from .command import BlockCommand, InlineCommand, CodeCommand, Command
|
||||||
|
@ -69,7 +69,6 @@ class NOPProcessor:
|
||||||
Cite: self.transform_Cite,
|
Cite: self.transform_Cite,
|
||||||
Code: self.transform_Code,
|
Code: self.transform_Code,
|
||||||
Emph: self.transform_Emph,
|
Emph: self.transform_Emph,
|
||||||
Slanted: self.transform_Slanted,
|
|
||||||
Image: self.transform_Image,
|
Image: self.transform_Image,
|
||||||
LineBreak: self.transform_LineBreak,
|
LineBreak: self.transform_LineBreak,
|
||||||
Link: self.transform_Link,
|
Link: self.transform_Link,
|
||||||
|
@ -89,7 +88,6 @@ class NOPProcessor:
|
||||||
Underline: self.transform_Underline,
|
Underline: self.transform_Underline,
|
||||||
NBSP: self.transform_NBSP,
|
NBSP: self.transform_NBSP,
|
||||||
FQuoted: self.transform_FQuoted,
|
FQuoted: self.transform_FQuoted,
|
||||||
FLink: self.transform_FLink,
|
|
||||||
FileLink: self.transform_FileLink,
|
FileLink: self.transform_FileLink,
|
||||||
|
|
||||||
InlineCommand: self.transform_InlineCommand,
|
InlineCommand: self.transform_InlineCommand,
|
||||||
|
@ -266,10 +264,6 @@ class NOPProcessor:
|
||||||
e.content = self.transform(e.content)
|
e.content = self.transform(e.content)
|
||||||
return e
|
return e
|
||||||
|
|
||||||
def transform_Slanted(self, e: Slanted) -> Slanted:
|
|
||||||
e.content = self.transform(e.content)
|
|
||||||
return e
|
|
||||||
|
|
||||||
def transform_Link(self, e: Link) -> Link:
|
def transform_Link(self, e: Link) -> Link:
|
||||||
e.content = self.transform(e.content)
|
e.content = self.transform(e.content)
|
||||||
return e
|
return e
|
||||||
|
@ -306,9 +300,6 @@ class NOPProcessor:
|
||||||
e.content = self.transform(e.content)
|
e.content = self.transform(e.content)
|
||||||
return e
|
return e
|
||||||
|
|
||||||
def transform_FLink(self, e: FLink) -> FLink:
|
|
||||||
return self.transform_Link(e)
|
|
||||||
|
|
||||||
def transform_FileLink(self, e: FileLink) -> FileLink:
|
def transform_FileLink(self, e: FileLink) -> FileLink:
|
||||||
e.content = self.transform(e.content)
|
e.content = self.transform(e.content)
|
||||||
return e
|
return e
|
||||||
|
|
|
@ -7,7 +7,7 @@ from panflute import stringify
|
||||||
from typing import Union, Callable
|
from typing import Union, Callable
|
||||||
|
|
||||||
from .whitespace import NBSP
|
from .whitespace import NBSP
|
||||||
from .elements import FQuoted, Slanted, FLink, FileLink, FLineMarkup
|
from .elements import FQuoted, FileLink
|
||||||
from .context import Group, InlineGroup, BlockGroup, Context
|
from .context import Group, InlineGroup, BlockGroup, Context
|
||||||
|
|
||||||
|
|
||||||
|
@ -88,7 +88,6 @@ class OutputGenerator:
|
||||||
DefinitionItem: self.generate_DefinitionItem,
|
DefinitionItem: self.generate_DefinitionItem,
|
||||||
DefinitionList: self.generate_DefinitionList,
|
DefinitionList: self.generate_DefinitionList,
|
||||||
Div: self.generate_Div,
|
Div: self.generate_Div,
|
||||||
FLineMarkup: self.generate_FLineMarkup,
|
|
||||||
Figure: self.generate_Figure,
|
Figure: self.generate_Figure,
|
||||||
Header: self.generate_Header,
|
Header: self.generate_Header,
|
||||||
HorizontalRule: self.generate_HorizontalRule,
|
HorizontalRule: self.generate_HorizontalRule,
|
||||||
|
@ -109,7 +108,6 @@ class OutputGenerator:
|
||||||
Cite: self.generate_Cite,
|
Cite: self.generate_Cite,
|
||||||
Code: self.generate_Code,
|
Code: self.generate_Code,
|
||||||
Emph: self.generate_Emph,
|
Emph: self.generate_Emph,
|
||||||
Slanted: self.generate_Slanted,
|
|
||||||
Image: self.generate_Image,
|
Image: self.generate_Image,
|
||||||
LineBreak: self.generate_LineBreak,
|
LineBreak: self.generate_LineBreak,
|
||||||
Link: self.generate_Link,
|
Link: self.generate_Link,
|
||||||
|
@ -129,7 +127,6 @@ class OutputGenerator:
|
||||||
Underline: self.generate_Underline,
|
Underline: self.generate_Underline,
|
||||||
NBSP: self.generate_NBSP,
|
NBSP: self.generate_NBSP,
|
||||||
FQuoted: self.generate_FQuoted,
|
FQuoted: self.generate_FQuoted,
|
||||||
FLink: self.generate_FLink,
|
|
||||||
FileLink: self.generate_FileLink,
|
FileLink: self.generate_FileLink,
|
||||||
InlineGroup: self.generate_InlineGroup
|
InlineGroup: self.generate_InlineGroup
|
||||||
}
|
}
|
||||||
|
@ -382,18 +379,12 @@ class OutputGenerator:
|
||||||
def generate_Emph(self, e: Emph):
|
def generate_Emph(self, e: Emph):
|
||||||
self.generate_simple_tag(e)
|
self.generate_simple_tag(e)
|
||||||
|
|
||||||
def generate_Slanted(self, e: Slanted):
|
|
||||||
self.generate_Emph(e)
|
|
||||||
|
|
||||||
def generate_Image(self, e: Image):
|
def generate_Image(self, e: Image):
|
||||||
self.generate_simple_tag(e)
|
self.generate_simple_tag(e)
|
||||||
|
|
||||||
def generate_Link(self, e: Link):
|
def generate_Link(self, e: Link):
|
||||||
self.generate_simple_tag(e)
|
self.generate_simple_tag(e)
|
||||||
|
|
||||||
def generate_FLink(self, e: FLink):
|
|
||||||
self.generate_Link(e)
|
|
||||||
|
|
||||||
def generate_Note(self, e: Note):
|
def generate_Note(self, e: Note):
|
||||||
self.generate_simple_tag(e)
|
self.generate_simple_tag(e)
|
||||||
|
|
||||||
|
@ -463,9 +454,6 @@ class OutputGenerator:
|
||||||
def generate_Div(self, e: Div):
|
def generate_Div(self, e: Div):
|
||||||
self.generate_simple_tag(e)
|
self.generate_simple_tag(e)
|
||||||
|
|
||||||
def generate_FLineMarkup(self, e: FLineMarkup):
|
|
||||||
self.generate_Div(e)
|
|
||||||
|
|
||||||
def generate_Header(self, e: Header):
|
def generate_Header(self, e: Header):
|
||||||
self.generate_simple_tag(e)
|
self.generate_simple_tag(e)
|
||||||
|
|
||||||
|
|
|
@ -1,189 +0,0 @@
|
||||||
\input ltluatex.tex
|
|
||||||
\input luatex85.sty
|
|
||||||
\input ucwmac2.tex
|
|
||||||
\ucwmodule{luaofs}
|
|
||||||
\ucwmodule{verb}
|
|
||||||
\ucwmodule{link}
|
|
||||||
\clickablefalse
|
|
||||||
|
|
||||||
\pdfglyphtounicode{summationtext}{2211}
|
|
||||||
\pdfglyphtounicode{summationdisplay}{2211}
|
|
||||||
\pdfglyphtounicode{summation}{2211}
|
|
||||||
|
|
||||||
\pdfglyphtounicode{parenleftbig}{0028}
|
|
||||||
\pdfglyphtounicode{parenrightbig}{0029}
|
|
||||||
\pdfglyphtounicode{parenleftBig}{0028}
|
|
||||||
\pdfglyphtounicode{parenrightBig}{0029}
|
|
||||||
\pdfglyphtounicode{parenleftbigg}{0028}
|
|
||||||
\pdfglyphtounicode{parenrightbigg}{0029}
|
|
||||||
\pdfglyphtounicode{parenleftBigg}{0028}
|
|
||||||
\pdfglyphtounicode{parenrightBigg}{0029}
|
|
||||||
|
|
||||||
\pdfglyphtounicode{radicalbig}{221A}
|
|
||||||
\pdfglyphtounicode{radicalBig}{221A}
|
|
||||||
\pdfglyphtounicode{radicalbigg}{221A}
|
|
||||||
\pdfglyphtounicode{radicalBigg}{221A}
|
|
||||||
\pdfglyphtounicode{hatwidest}{0302}
|
|
||||||
|
|
||||||
\input formatitkolib.tex
|
|
||||||
|
|
||||||
|
|
||||||
\input minim-xmp.tex
|
|
||||||
\startmetadata
|
|
||||||
pdfaid:part 2
|
|
||||||
pdfaid:conformance U
|
|
||||||
stopmetadata
|
|
||||||
|
|
||||||
|
|
||||||
\pdfcompresslevel=0
|
|
||||||
\pdfobjcompresslevel=0
|
|
||||||
% \pdfobj{/Alternate /DeviceRGB}
|
|
||||||
|
|
||||||
\input glyphtounicode.tex
|
|
||||||
\pdfgentounicode=1
|
|
||||||
|
|
||||||
|
|
||||||
%Create an OutputIntent in order to correctly specify colours
|
|
||||||
\immediate\pdfobj stream attr{/N 3} file{sRGB.icc}
|
|
||||||
\pdfcatalog{%
|
|
||||||
/OutputIntents [
|
|
||||||
<<
|
|
||||||
/Type /OutputIntent
|
|
||||||
/S /GTS_PDFA1
|
|
||||||
/DestOutputProfile \the\pdflastobj\space 0 R
|
|
||||||
/OutputConditionIdentifier (sRGB)
|
|
||||||
/Info (sRGB)
|
|
||||||
>>
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
\parskip=5pt plus 3pt minus 2pt
|
|
||||||
\parindent=0sp
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
% Fonty
|
|
||||||
\ofsdeclarefamily [Pagella] {%
|
|
||||||
\loadtextfam qplr;%
|
|
||||||
qplb;%
|
|
||||||
qpli;%
|
|
||||||
qplbi;;%
|
|
||||||
}
|
|
||||||
|
|
||||||
% doporučen je horní, dolní a pravý okraj 25 mm, levý okraj 40 mm.
|
|
||||||
% Protože doba tisknutí prací je už pryč, my máme stejně velkou stránku uprostřed papíru
|
|
||||||
\voffset 25mm
|
|
||||||
|
|
||||||
\hoffset 32.5mm
|
|
||||||
|
|
||||||
\vsize\pdfpageheight
|
|
||||||
\advance\vsize -2\voffset
|
|
||||||
|
|
||||||
\hsize\pdfpagewidth
|
|
||||||
\advance\hsize -2\hoffset
|
|
||||||
|
|
||||||
\advance\voffset -\pdfvorigin
|
|
||||||
\advance\hoffset -\pdfhorigin
|
|
||||||
|
|
||||||
\def\MSfeat#1{:mode=node;script=latn;+tlig}
|
|
||||||
\registertfm qplr - file:texgyrepagella-regular.otf\MSfeat{}
|
|
||||||
\registertfm qplb - file:texgyrepagella-bold.otf\MSfeat{}
|
|
||||||
\registertfm qpli - file:texgyrepagella-italic.otf\MSfeat{}
|
|
||||||
\registertfm qplbi - file:texgyrepagella-bolditalic.otf\MSfeat{}
|
|
||||||
|
|
||||||
%\setfonts[Pagella/10]
|
|
||||||
%\def\h{\it} % hint
|
|
||||||
%\def\bh{\bi} % bold hint
|
|
||||||
|
|
||||||
|
|
||||||
\def\mod{\mathrel{\rm mod}}
|
|
||||||
|
|
||||||
\settextsize{12}
|
|
||||||
|
|
||||||
|
|
||||||
\long\def\floatinsert#1{\par{
|
|
||||||
\setbox0=\vbox{\boxmaxdepth=2pt\relax #1}
|
|
||||||
\dimen0=\dimexpr \ht0 + \dp0 + \baselineskip + \pagetotal - \pageshrink \relax
|
|
||||||
\ifdim\dimen0 > \pagegoal
|
|
||||||
\insert\topins{
|
|
||||||
\penalty 100
|
|
||||||
\splittopskip=0pt
|
|
||||||
\splitmaxdepth=\maxdimen
|
|
||||||
\floatingpenalty=0
|
|
||||||
\box0
|
|
||||||
\nobreak\bigskip\medskip
|
|
||||||
}
|
|
||||||
\else
|
|
||||||
\goodbreak\bigskip
|
|
||||||
\box0
|
|
||||||
\goodbreak\bigskip
|
|
||||||
\unparskip
|
|
||||||
\fi
|
|
||||||
}}
|
|
||||||
|
|
||||||
% Obecny plovouci objekt: \float{objekt}{popisek}{mezera pred}{mezera po}
|
|
||||||
\long\def\figure#1#2#3#4{
|
|
||||||
\medskip#3
|
|
||||||
\hbox to \hsize{\hfil\vtop{
|
|
||||||
\parindent=0pt
|
|
||||||
\leftskip=0pt plus 0.2\hsize
|
|
||||||
\rightskip=0pt plus 0.2\hsize
|
|
||||||
\parfillskip=0pt
|
|
||||||
\spaceskip=0.3333em
|
|
||||||
\settextsize{10}
|
|
||||||
#1
|
|
||||||
}\hfil}#4
|
|
||||||
\medskip
|
|
||||||
\smallskip
|
|
||||||
{
|
|
||||||
\setbox0=\hbox{\settextsize{10}#2}
|
|
||||||
\ifdim\wd0 < 0.8\hsize
|
|
||||||
\centerline{\box0}
|
|
||||||
\else
|
|
||||||
\centerline{\vtop{
|
|
||||||
\hsize=0.8\hsize
|
|
||||||
\parindent=0pt
|
|
||||||
\leftskip=0pt plus 0.3\hsize
|
|
||||||
\rightskip=0pt plus 0.3\hsize
|
|
||||||
\parfillskip=0pt
|
|
||||||
\spaceskip=0.3333em
|
|
||||||
\settextsize{10}#2
|
|
||||||
}}
|
|
||||||
\fi
|
|
||||||
}}
|
|
||||||
|
|
||||||
\long\def\floatpage#1{
|
|
||||||
\pageinsert
|
|
||||||
\vbox to \vsize{#1}
|
|
||||||
\endinsert
|
|
||||||
}
|
|
||||||
|
|
||||||
% Dva floaty vedle sebe: \float{objekt1}{popisek1}{id1}{objekt2}{popisek2}{id2}
|
|
||||||
\def\twofloats#1#2#3#4#5#6{\floatinsert{
|
|
||||||
\medskip
|
|
||||||
\centerline{\vbox{\halign{\hss##\hss&\qquad\hss##\hss\cr
|
|
||||||
#1\cr
|
|
||||||
\noalign{\medskip\smallskip}
|
|
||||||
#2\cr
|
|
||||||
}}}
|
|
||||||
}}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
% Obsah a odkazy
|
|
||||||
\newwrite\tocfile
|
|
||||||
\immediate\openout\tocfile=toc-new.aux
|
|
||||||
|
|
||||||
% Voláme: \addtoc\tocmacro{number}{asterisks}{title}
|
|
||||||
\long\def\addtoc#1#2#3#4{%
|
|
||||||
\edef\brum{%
|
|
||||||
\write\tocfile{\string#1{\noexpand\the\noexpand\count0}{#2}{#3}{#4}}%
|
|
||||||
}
|
|
||||||
\brum%
|
|
||||||
}
|
|
|
@ -1,79 +0,0 @@
|
||||||
\def\strong#1{{%
|
|
||||||
\def\emph##1{{\bi{}##1}}%
|
|
||||||
\bf{}#1%
|
|
||||||
}}
|
|
||||||
\def\emph#1{{%
|
|
||||||
\def\strong##1{{\bi{}##1}}%
|
|
||||||
\it{}#1%
|
|
||||||
}}
|
|
||||||
|
|
||||||
\def\textasciitilde{$\sim$}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
\def\N{{\bb N}}
|
|
||||||
\def\R{{\bb R}}
|
|
||||||
\def\E{{\bb E}}
|
|
||||||
\def\O{{\cal O}}
|
|
||||||
\def\SYM{{\rm SYM}}
|
|
||||||
\def\frac#1#2{{{#1} \over {#2}}}
|
|
||||||
|
|
||||||
\def\superscript#1{$^{\hbox{\settextsize{0.8\textsize}#1}}$}
|
|
||||||
\def\subscript#1{$_{\hbox{\settextsize{0.8\textsize}#1}}$}
|
|
||||||
\newcount\fncount
|
|
||||||
\fncount=1
|
|
||||||
\def\fnmark{$^{\the\fncount}$}
|
|
||||||
\def\fn#1{\footnote\fnmark{#1}\advance\fncount by 1}
|
|
||||||
\def\sectioneject{\vfil\supereject}
|
|
||||||
\def\section#1#2{
|
|
||||||
\sectioneject
|
|
||||||
\vskip 16pt\vbox{\settextsize{20}\bf #1\kern 1em\relax#2%
|
|
||||||
\addtoc\tocsection{#1}{}{#2}%
|
|
||||||
}\nobreak\vskip 12pt
|
|
||||||
}
|
|
||||||
\def\subsection#1#2{
|
|
||||||
\vskip 12pt\vbox{\settextsize{18}\bf #1\kern 1em\relax#2%
|
|
||||||
\addtoc\tocsubsection{#1}{}{#2}%
|
|
||||||
}\nobreak\vskip 7pt
|
|
||||||
}
|
|
||||||
\def\subsubsection#1#2{
|
|
||||||
\vskip 10pt\vbox{\settextsize{16}\bf #1\kern 1em\relax#2%
|
|
||||||
\addtoc\tocsubsubsection{#1}{}{#2}%
|
|
||||||
}\nobreak\vskip 6pt
|
|
||||||
}
|
|
||||||
\def\subsubsubsection#1#2{
|
|
||||||
\vskip 8pt\vbox{\settextsize{14}\bf #1\kern 1em\relax#2}\nobreak\vskip 5pt
|
|
||||||
}
|
|
||||||
\def\subsubsubsubsection#1#2{
|
|
||||||
\vskip 7pt\vbox{\settextsize{12}\bf #1\kern 1em\relax#2}\nobreak\vskip 5pt
|
|
||||||
}
|
|
||||||
\def\subsubsubsubsubsection#1#2{
|
|
||||||
\vskip 7pt\vbox{\settextsize{12}\bf #1\kern 1em\relax#2}\nobreak\vskip 5pt
|
|
||||||
}
|
|
||||||
\long\def\blockquote#1{\vskip\lineskip\vskip\parskip\hbox{\vrule\hskip5pt\vbox{#1}}}
|
|
||||||
\def\strikeout#1{FIXME: Strikeout not implemented}
|
|
||||||
\def\underline#1{FIXME: Underline not implemented}
|
|
||||||
|
|
||||||
|
|
||||||
\def\mathbb#1{\hbox{\bb #1}}
|
|
||||||
|
|
||||||
\def\unparskip{\vskip-\parskip}
|
|
||||||
|
|
||||||
\catcode`@=11
|
|
||||||
\def\vecoverrightarrow#1{\mathpalette\vecoverrightarrowtmp{#1}}
|
|
||||||
\def\vecoverrightarrowtmp#1#2{\vbox{\m@th\ialign{##\crcr
|
|
||||||
\vecrightarrowfill\crcr\noalign{\kern-\p@\kern 0.09em\nointerlineskip}
|
|
||||||
$\hfil#1{#2\,}\hfil$\crcr}}}
|
|
||||||
\def\vecrightarrowfill{$\settextsize{5}\m@th\smash-\mkern-7mu%
|
|
||||||
\cleaders\hbox{$\mkern-2mu\smash-\mkern-2mu$}\hfill
|
|
||||||
\settextsize{5}\mkern-7mu\mathord\rightarrow$}
|
|
||||||
\catcode`@=12
|
|
||||||
|
|
||||||
|
|
||||||
\long\def\linemarkup#1#2{%
|
|
||||||
\par\noindent\hbox{%
|
|
||||||
\hbox{}\hskip -6pt {\colorlocal{#1}\vrule width 1pt \hskip 5pt}%
|
|
||||||
\hbox to \hsize{\vbox{#2}\hfil}%
|
|
||||||
%\hbox{}\hskip 5pt {\colorlocal{#1}\vrule width 1pt \hskip -6pt}%
|
|
||||||
}\par%
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
{
|
|
||||||
|
|
||||||
\def\pagelink#1{#1}
|
|
||||||
\def\toclink#1#2{%
|
|
||||||
#2
|
|
||||||
}
|
|
||||||
|
|
||||||
\def\stdskip{\vskip 3pt}
|
|
||||||
\def\tocsection#1#2#3#4{
|
|
||||||
\line{\bf\hbox to 2em{#2\hfil}#4~\hfil\pagelink{#1}}
|
|
||||||
}
|
|
||||||
\def\tocsubsection#1#2#3#4{
|
|
||||||
\line{\hskip 1.5cm \hbox to 3em{#2\hfil}#4~\hfil\pagelink{#1}}
|
|
||||||
}
|
|
||||||
\def\tocsubsubsection#1#2#3#4{
|
|
||||||
\line{\hskip 3cm \hbox to 4em{#2\hfil}#4~\hfil\pagelink{#1}}
|
|
||||||
}
|
|
||||||
\def\tocpicture#1#2#3#4{}
|
|
||||||
|
|
||||||
\vskip 1cm
|
|
||||||
\input toc.aux
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
{
|
|
||||||
|
|
||||||
\def\pagelink#1{#1}
|
|
||||||
\def\toclink#1#2{%
|
|
||||||
#2
|
|
||||||
}
|
|
||||||
|
|
||||||
\def\stdskip{\vskip 3pt}
|
|
||||||
\def\tocsection#1#2#3#4{}
|
|
||||||
\def\tocsubsection#1#2#3#4{}
|
|
||||||
\def\tocsubsubsection#1#2#3#4{}
|
|
||||||
\def\tocpicture#1#2#3#4{
|
|
||||||
\line{\hbox to 2em{#2\hfil}#4~\hfil\pagelink{#1}}\stdskip
|
|
||||||
}
|
|
||||||
|
|
||||||
\vskip 1cm
|
|
||||||
\input toc.aux
|
|
||||||
}
|
|
|
@ -11,14 +11,10 @@ from .output_generator import OutputGenerator
|
||||||
from .images import ImageProcessor, ImageProcessorNamespaceSearcher
|
from .images import ImageProcessor, ImageProcessorNamespaceSearcher
|
||||||
|
|
||||||
from .whitespace import NBSP
|
from .whitespace import NBSP
|
||||||
from .elements import FQuoted, FLineMarkup
|
from .elements import FQuoted
|
||||||
from .context import Group, InlineGroup, BlockGroup, Context
|
from .context import Group, InlineGroup, BlockGroup, Context
|
||||||
from .util import inlinify
|
from .util import inlinify
|
||||||
|
|
||||||
def color_to_rgb(color):
|
|
||||||
import matplotlib.colors
|
|
||||||
return matplotlib.colors.to_rgb(color)
|
|
||||||
|
|
||||||
class UCWTexGenerator(OutputGenerator):
|
class UCWTexGenerator(OutputGenerator):
|
||||||
imageProcessor: ImageProcessor
|
imageProcessor: ImageProcessor
|
||||||
_bold: int
|
_bold: int
|
||||||
|
@ -28,30 +24,22 @@ class UCWTexGenerator(OutputGenerator):
|
||||||
self.imageProcessor = imageProcessor
|
self.imageProcessor = imageProcessor
|
||||||
self._bold = 0
|
self._bold = 0
|
||||||
self._italic = 0
|
self._italic = 0
|
||||||
|
|
||||||
self._floatpages = {}
|
|
||||||
super().__init__(output_file, *args, **kwargs)
|
super().__init__(output_file, *args, **kwargs)
|
||||||
|
|
||||||
def escape_special_chars(self, text: str) -> str:
|
def escape_special_chars(self, text: str) -> str:
|
||||||
if '\\' in text:
|
text = text.replace("&", r"\&")
|
||||||
print("ESCAPE", text)
|
text = text.replace("%", r"\%")
|
||||||
out = ""
|
text = text.replace("$", r"\$")
|
||||||
for char in text:
|
text = text.replace("#", r"\#")
|
||||||
out += {
|
text = text.replace("_", r"\_")
|
||||||
'&': r"\&",
|
text = text.replace("{", r"\{")
|
||||||
'%': r"\%",
|
text = text.replace("}", r"\}")
|
||||||
'$': r"\$",
|
text = text.replace("~", r"\textasciitilde{}")
|
||||||
'#': r"\#",
|
text = text.replace("^", r"\textasciicircum{}")
|
||||||
'_': r"\_",
|
text = text.replace("\\", r"\textbackslash{}")
|
||||||
'{': r"\{",
|
text = text.replace(" ", "~") # We use unicode no-break spaces to force nbsp in output
|
||||||
'}': r"\}",
|
text = text.replace("", "")
|
||||||
'~': r"\textasciitilde{}",
|
return text
|
||||||
'^': r"\textasciicircum{}",
|
|
||||||
'\\': r"\textbackslash{}",
|
|
||||||
' ': r"~",
|
|
||||||
'': r"",
|
|
||||||
}.get(char, char)
|
|
||||||
return out
|
|
||||||
|
|
||||||
def generate(self, e: Union[Element, ListContainer]):
|
def generate(self, e: Union[Element, ListContainer]):
|
||||||
if hasattr(e, "attributes") and "only" in e.attributes and e.attributes["only"] != "tex":
|
if hasattr(e, "attributes") and "only" in e.attributes and e.attributes["only"] != "tex":
|
||||||
|
@ -79,17 +67,21 @@ class UCWTexGenerator(OutputGenerator):
|
||||||
self.writepar(r"\vskip5pt\hrule\hfil\vskip5pt{}")
|
self.writepar(r"\vskip5pt\hrule\hfil\vskip5pt{}")
|
||||||
|
|
||||||
def generate_Doc(self, e: Doc):
|
def generate_Doc(self, e: Doc):
|
||||||
|
self.writeln(r"\input ucwmac2.tex")
|
||||||
|
self.writeln(r"\ucwmodule{ofs}")
|
||||||
|
self.writeln(r"\ucwmodule{verb}")
|
||||||
|
self.writeln(r"\ucwmodule{link}")
|
||||||
self.writeln(r"\input formatitko.tex")
|
self.writeln(r"\input formatitko.tex")
|
||||||
self.generate(e.content)
|
self.generate(e.content)
|
||||||
self.writeln(r"\bye")
|
self.writeln(r"\bye")
|
||||||
|
|
||||||
def get_language_macro(self, lang: str):
|
def get_language_macro(self, lang: str):
|
||||||
if lang == "cs":
|
if lang == "cs":
|
||||||
return r"\uselanguage{czech}\frenchspacing\lefthyphenmin=2\righthyphenmin=2{}"
|
return r"\chyph\lefthyphenmin=2\righthyphenmin=2{}"
|
||||||
elif lang == "sk":
|
elif lang == "sk":
|
||||||
return r"\uselanguage{slovak}\frenchspacing\lefthyphenmin=2\righthyphenmin=2{}"
|
return r"\shyph\lefthyphenmin=2\righthyphenmin=2{}"
|
||||||
elif lang == "en":
|
elif lang == "en":
|
||||||
return r"\uselanguage{USenglish}\nonfrenchspacing\lefthyphenmin=2\righthyphenmin=2{}"
|
return r"\ehyph\lefthyphenmin=2\righthyphenmin=2{}"
|
||||||
else:
|
else:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
@ -109,7 +101,7 @@ class UCWTexGenerator(OutputGenerator):
|
||||||
|
|
||||||
def generate_Header(self, e: Header):
|
def generate_Header(self, e: Header):
|
||||||
self.ensure_empty(2)
|
self.ensure_empty(2)
|
||||||
self.write("\\"+"sub"*(e.level-1)+"section{"+".".join(map(str, e.attributes["number"]))+"}{")
|
self.write("\\"+"sub"*(e.level-1)+"section{")
|
||||||
self.generate(e.content)
|
self.generate(e.content)
|
||||||
self.write(r"}")
|
self.write(r"}")
|
||||||
self.ensure_empty(2)
|
self.ensure_empty(2)
|
||||||
|
@ -155,57 +147,30 @@ class UCWTexGenerator(OutputGenerator):
|
||||||
width = str(int(e.attributes["width"][:-1])/100) + "\\hsize"
|
width = str(int(e.attributes["width"][:-1])/100) + "\\hsize"
|
||||||
width = "width " + width
|
width = "width " + width
|
||||||
|
|
||||||
self.writeln(f'\\centerline{{\\putimage{{{width}}}{{{url}}}}}')
|
if isinstance(e.parent.parent, Figure):
|
||||||
|
self.writeln(f'\\putimage{{{width}}}{{{url}}}')
|
||||||
|
else:
|
||||||
|
self.writepar(f'\\putimage{{{width}}}{{{url}}}')
|
||||||
|
|
||||||
def generate_Code(self, e: Code):
|
def generate_Code(self, e: Code):
|
||||||
self.write(r"\verb`")
|
self.write(r"\verb`")
|
||||||
self.write(e.text)
|
self.write(e.text)
|
||||||
self.write(r"`")
|
self.write(r"`")
|
||||||
|
|
||||||
def generate_nonfloat_Figure(self, e: Figure):
|
def generate_Figure(self, e: Figure):
|
||||||
self.writeln(r"\figure{")
|
self.ensure_empty(2)
|
||||||
|
self.writeln(r"\vskip5pt")
|
||||||
|
self.writeln(r"\centerline{")
|
||||||
self.indent_more()
|
self.indent_more()
|
||||||
self.generate(e.content)
|
self.generate(e.content)
|
||||||
self.indent_less()
|
self.indent_less()
|
||||||
self.writeln(r"}{")
|
self.writeln(r"}")
|
||||||
|
self.writeln(r"\centerline{")
|
||||||
self.indent_more()
|
self.indent_more()
|
||||||
if 'number' in e.attributes:
|
|
||||||
type_text = e.attributes.get("type_text", "Obrázek")
|
|
||||||
self.writeln(f"{type_text} {e.attributes['number']}:")
|
|
||||||
self.generate(e.caption)
|
self.generate(e.caption)
|
||||||
if 'number' in e.attributes:
|
|
||||||
tocmac = e.attributes.get("tocmac", "tocpicture")
|
|
||||||
if tocmac:
|
|
||||||
self.writeln("\\addtoc\\"+tocmac+r"{"+str(e.attributes['number'])+"}{}{")
|
|
||||||
self.indent_more()
|
|
||||||
self.generate(e.caption.content)
|
|
||||||
self.indent_less()
|
self.indent_less()
|
||||||
self.writeln("}")
|
|
||||||
self.indent_less()
|
|
||||||
self.writeln(r"}{}{}")
|
|
||||||
|
|
||||||
|
|
||||||
def generate_Figure(self, e: Figure):
|
|
||||||
if "floatpage" in e.attributes:
|
|
||||||
fp = e.attributes["floatpage"]
|
|
||||||
flush = fp[-1]=="!"
|
|
||||||
if flush:
|
|
||||||
fp = fp[:-1]
|
|
||||||
self._floatpages.setdefault(fp, [])
|
|
||||||
self._floatpages[fp].append(e)
|
|
||||||
if flush:
|
|
||||||
self.writeln(r"\floatpage{")
|
|
||||||
self.writeln(r"\vfill")
|
|
||||||
for x in self._floatpages[fp]:
|
|
||||||
self.generate_nonfloat_Figure(x)
|
|
||||||
self.writeln(r"\vfill")
|
|
||||||
self.writeln(r"}")
|
|
||||||
del self._floatpages[fp]
|
|
||||||
else:
|
|
||||||
self.ensure_empty(2)
|
|
||||||
self.writeln(r"\floatinsert{")
|
|
||||||
self.generate_nonfloat_Figure(e)
|
|
||||||
self.writeln(r"}")
|
self.writeln(r"}")
|
||||||
|
self.writeln(r"\vskip5pt{}")
|
||||||
self.ensure_empty(2)
|
self.ensure_empty(2)
|
||||||
|
|
||||||
def generate_Emph(self, e: Emph):
|
def generate_Emph(self, e: Emph):
|
||||||
|
@ -218,11 +183,6 @@ class UCWTexGenerator(OutputGenerator):
|
||||||
self._italic-=1
|
self._italic-=1
|
||||||
self.write(r"}")
|
self.write(r"}")
|
||||||
|
|
||||||
def generate_Slanted(self, e: Emph):
|
|
||||||
self.write(r"{\sl{}")
|
|
||||||
self.generate(e.content)
|
|
||||||
self.write(r"}")
|
|
||||||
|
|
||||||
def generate_Strong(self, e: Strong):
|
def generate_Strong(self, e: Strong):
|
||||||
if self._italic > 0:
|
if self._italic > 0:
|
||||||
self.write(r"{\bi{}")
|
self.write(r"{\bi{}")
|
||||||
|
@ -234,15 +194,15 @@ class UCWTexGenerator(OutputGenerator):
|
||||||
self.write(r"}")
|
self.write(r"}")
|
||||||
|
|
||||||
def generate_Caption(self, e: Caption):
|
def generate_Caption(self, e: Caption):
|
||||||
self.generate(e.content)
|
self.generate_Emph(e)
|
||||||
|
|
||||||
def generate_Math(self, e: Math):
|
def generate_Math(self, e: Math):
|
||||||
if e.format == "DisplayMath":
|
if e.format == "DisplayMath":
|
||||||
self.ensure_empty(1)
|
self.ensure_empty(2)
|
||||||
self.writeraw("$$")
|
self.writeraw("$$")
|
||||||
self.writeraw(e.text.strip())
|
self.writeraw(e.text.strip())
|
||||||
self.writeraw("$$")
|
self.writeraw("$$")
|
||||||
self.ensure_empty(1)
|
self.ensure_empty(2)
|
||||||
else:
|
else:
|
||||||
self.write("$")
|
self.write("$")
|
||||||
self.write(e.text)
|
self.write(e.text)
|
||||||
|
@ -254,23 +214,22 @@ class UCWTexGenerator(OutputGenerator):
|
||||||
self.write(r"}")
|
self.write(r"}")
|
||||||
|
|
||||||
def generate_Table(self, e: Table):
|
def generate_Table(self, e: Table):
|
||||||
hskip = r"\hskip 0.6em\relax"
|
|
||||||
aligns = {
|
aligns = {
|
||||||
"AlignLeft": hskip+r"\relax#\hfil"+hskip,
|
"AlignLeft": r"\quad#\quad\hfil",
|
||||||
"AlignRight": hskip+r"\hfil#"+hskip,
|
"AlignRight": r"\quad\hfil#\quad",
|
||||||
"AlignCenter": hskip+r"\hfil#\hfil"+hskip,
|
"AlignCenter": r"\quad\hfil#\hfil\quad",
|
||||||
"AlignDefault": hskip+r"#\hfil"+hskip,
|
"AlignDefault": r"\quad#\quad\hfil"
|
||||||
}
|
}
|
||||||
self.writeln(r"\vskip1em")
|
self.writeln(r"\vskip1em")
|
||||||
self.writeln(r"\leavevmode\vbox{\halign{\strut"+"&".join([aligns[col[0]] for col in e.colspec])+r"\cr")
|
self.writeln(r"\halign{\strut"+"&".join([aligns[col[0]] for col in e.colspec])+r"\cr")
|
||||||
self.indent_more()
|
self.indent_more()
|
||||||
self.generate(e.head.content)
|
self.generate(e.head.content)
|
||||||
self.writeln(r"\noalign{\vskip 0.3em\hrule\vskip 0.3em}")
|
self.writeln(r"\noalign{\hrule}")
|
||||||
self.generate(e.content[0].content)
|
self.generate(e.content[0].content)
|
||||||
self.writeln(r"\noalign{\vskip 0.3em\hrule\vskip 0.3em}")
|
self.writeln(r"\noalign{\hrule}")
|
||||||
self.generate(e.foot.content)
|
self.generate(e.foot.content)
|
||||||
self.indent_less()
|
self.indent_less()
|
||||||
self.writeln("}}")
|
self.writeln("}")
|
||||||
self.writeln(r"\vskip1em")
|
self.writeln(r"\vskip1em")
|
||||||
|
|
||||||
def generate_TableRow(self, e: TableRow):
|
def generate_TableRow(self, e: TableRow):
|
||||||
|
@ -305,16 +264,6 @@ class UCWTexGenerator(OutputGenerator):
|
||||||
def generate_Div(self, e: Div):
|
def generate_Div(self, e: Div):
|
||||||
self.generate(e.content)
|
self.generate(e.content)
|
||||||
|
|
||||||
def generate_FLineMarkup(self, e: FLineMarkup):
|
|
||||||
self.ensure_empty(2)
|
|
||||||
r,g,b = color_to_rgb(e.color)
|
|
||||||
self.writeln(r"\linemarkup{\rgb{"+f"{r} {g} {b}"+"}}{")
|
|
||||||
self.indent_more()
|
|
||||||
self.generate(e.content)
|
|
||||||
self.indent_less()
|
|
||||||
self.writeln(r"}")
|
|
||||||
self.ensure_empty(2)
|
|
||||||
|
|
||||||
def generate_LineBlock(self, e: LineBlock):
|
def generate_LineBlock(self, e: LineBlock):
|
||||||
self.writeln()
|
self.writeln()
|
||||||
self.generate(e.content)
|
self.generate(e.content)
|
||||||
|
@ -374,11 +323,6 @@ class UCWTexGenerator(OutputGenerator):
|
||||||
self.writeln(r"}")
|
self.writeln(r"}")
|
||||||
|
|
||||||
def generate_Link(self, e: Link):
|
def generate_Link(self, e: Link):
|
||||||
if len(e.content) == 0:
|
|
||||||
if e.url.startswith('#'):
|
|
||||||
obj = e.obj_map[e.url[1:]]
|
|
||||||
self.write(str(obj.attributes["number"]))
|
|
||||||
return
|
|
||||||
if len(e.content) == 1 and isinstance(e.content[0], Str) and e.content[0].text == e.url:
|
if len(e.content) == 1 and isinstance(e.content[0], Str) and e.content[0].text == e.url:
|
||||||
self.write(r"\url{")
|
self.write(r"\url{")
|
||||||
else:
|
else:
|
||||||
|
@ -404,7 +348,7 @@ class UCWTexGenerator(OutputGenerator):
|
||||||
self.writeln("% FIXME: Citations not implemented")
|
self.writeln("% FIXME: Citations not implemented")
|
||||||
|
|
||||||
def generate_Cite(self, e: Cite):
|
def generate_Cite(self, e: Cite):
|
||||||
self.generate(e.content)
|
self.writeln("% FIXME: Cites not implemented")
|
||||||
|
|
||||||
def generate_Definition(self, e: Definition):
|
def generate_Definition(self, e: Definition):
|
||||||
self.writeln("% FIXME: Definitions not implemented")
|
self.writeln("% FIXME: Definitions not implemented")
|
||||||
|
@ -420,8 +364,3 @@ class UCWTexGenerator(OutputGenerator):
|
||||||
|
|
||||||
def generate_Strikeout(self, e: Strikeout):
|
def generate_Strikeout(self, e: Strikeout):
|
||||||
self.writeln("% FIXME: Strikeouts not implemented")
|
self.writeln("% FIXME: Strikeouts not implemented")
|
||||||
|
|
||||||
def generate_SmallCaps(self, e: Strikeout):
|
|
||||||
self.write(r"{\csc{}")
|
|
||||||
self.generate(e.content)
|
|
||||||
self.write(r"}")
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ import importlib
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from .whitespace import NBSP
|
from .whitespace import NBSP
|
||||||
from .elements import FQuoted, Slanted, FLink
|
from .elements import FQuoted
|
||||||
from .context import Group, InlineGroup, BlockGroup
|
from .context import Group, InlineGroup, BlockGroup
|
||||||
from .util import nullify, import_md
|
from .util import nullify, import_md
|
||||||
from .context import Context, CommandCallable
|
from .context import Context, CommandCallable
|
||||||
|
@ -228,12 +228,12 @@ class TransformProcessor(NOPProcessor):
|
||||||
importedDoc = import_md(open(filename, "r").read())
|
importedDoc = import_md(open(filename, "r").read())
|
||||||
self.transform(importedDoc.content)
|
self.transform(importedDoc.content)
|
||||||
elif e.attributes["type"] == "module":
|
elif e.attributes["type"] == "module":
|
||||||
matches = re.match(r"^([\w\.]+)(?: as (\w+))?$", e.content[0].text[1:])
|
matches = re.match(r"^(\w+)(?: as (\w+))?$", e.content[0].text[1:])
|
||||||
if not matches:
|
if not matches:
|
||||||
raise SyntaxError(f"`{e.content[0].text[1:]}`: invalid syntax")
|
raise SyntaxError(f"`{e.content[0].text[1:]}`: invalid syntax")
|
||||||
module = importlib.import_module(matches.group(1))
|
module = importlib.import_module(matches.group(1))
|
||||||
module_name = matches.group(1) if matches.group(2) is None else matches.group(2)
|
module_name = matches.group(1) if matches.group(2) is None else matches.group(2)
|
||||||
self.context.add_commands_from_module(module, "")
|
self.context.add_commands_from_module(module, module_name)
|
||||||
elif e.attributes["type"] == "metadata":
|
elif e.attributes["type"] == "metadata":
|
||||||
filename = self.context.dir + "/" + e.content[0].text[1:]
|
filename = self.context.dir + "/" + e.content[0].text[1:]
|
||||||
self.context.add_dep(filename)
|
self.context.add_dep(filename)
|
||||||
|
@ -260,11 +260,6 @@ class TransformProcessor(NOPProcessor):
|
||||||
raise TypeError(f"Cannot print value of metadatum '{e.content[0].text[1:]}' of type '{type(val)}'")
|
raise TypeError(f"Cannot print value of metadatum '{e.content[0].text[1:]}' of type '{type(val)}'")
|
||||||
return e
|
return e
|
||||||
|
|
||||||
if "slanted" in e.classes:
|
|
||||||
# `.slanted` class for Span
|
|
||||||
# Content of Span is enclosed into Slanted (subclass os Emph)
|
|
||||||
return self.transform(Slanted(*e.content))
|
|
||||||
|
|
||||||
return super().transform_Span(e)
|
return super().transform_Span(e)
|
||||||
|
|
||||||
def transform_CodeBlock(self, e: CodeBlock) -> Union[CodeBlock, Div, Null]:
|
def transform_CodeBlock(self, e: CodeBlock) -> Union[CodeBlock, Div, Null]:
|
||||||
|
@ -311,26 +306,3 @@ class TransformProcessor(NOPProcessor):
|
||||||
else:
|
else:
|
||||||
return e
|
return e
|
||||||
|
|
||||||
def transform_Header(self, e: Header) -> Header:
|
|
||||||
if "number" not in e.attributes:
|
|
||||||
if 'unnumbered' in e.classes:
|
|
||||||
e.attributes["number"] = ""
|
|
||||||
else:
|
|
||||||
e.attributes["number"] = self.context.get_data("section_number_generator")(e, self.context)
|
|
||||||
return e
|
|
||||||
|
|
||||||
def transform_Figure(self, e: Figure) -> Figure:
|
|
||||||
if "number" not in e.attributes:
|
|
||||||
if 'unnumbered' in e.classes:
|
|
||||||
e.attributes["number"] = ""
|
|
||||||
else:
|
|
||||||
e.attributes["number"] = self.context.get_data("figure_number_generator")(e, self.context)
|
|
||||||
self.context.get_data("obj_map")[e.identifier] = e
|
|
||||||
self.context.set_data("current_figure", e)
|
|
||||||
r = super().transform_Figure(e)
|
|
||||||
self.context.unset_data("current_figure")
|
|
||||||
return r
|
|
||||||
|
|
||||||
def transform_Link(self, e: Link) -> Link:
|
|
||||||
e = FLink(*e.content, url=e.url, identifier=e.identifier, attributes=e.attributes, classes=e.classes, obj_map=self.context.get_data("obj_map"))
|
|
||||||
return super().transform_Link(e)
|
|
||||||
|
|
|
@ -66,14 +66,14 @@ raise Exception("Jsem piča")
|
||||||
-->
|
-->
|
||||||
|
|
||||||
![This is a figure, go figure...](logo.svg){width=25%}What
|
![This is a figure, go figure...](logo.svg){width=25%}What
|
||||||
|
|
||||||
![This is a figure, go figure...](logo.pdf){width=50%}
|
![This is a figure, go figure...](logo.pdf){width=50%}
|
||||||
![Fakt epesní reproduktor](reproduktor.jpeg){width=10em}
|
|
||||||
![Fakt epesní reproduktor](reproduktor.png "Hodně rozpixelovaný obrázek reproduktoru"){width=10em file-width=1000}
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
![This is a figure, go figure...](logo.jpg){width=50%}
|
![This is a figure, go figure...](logo.jpg){width=50%}
|
||||||
|
|
||||||
|
![This is a figure, go figure...](logo1.png){width=10em}
|
||||||
|
|
||||||
|
![Fakt epesní reproduktor](reproduktor.jpeg){width=10em}
|
||||||
|
|
||||||
|
![Fakt epesní reproduktor](reproduktor.png "Hodně rozpixelovaný obrázek reproduktoru"){width=10em file-width=1000}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue