|
|
@ -3,16 +3,18 @@ from panflute import Cite, Code, Emph, Image, LineBreak, Link, Math, Note, Quote |
|
|
|
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, Callable |
|
|
|
from types import ModuleType |
|
|
|
|
|
|
|
import os |
|
|
|
import re |
|
|
|
import warnings |
|
|
|
import importlib |
|
|
|
|
|
|
|
from .whitespace import NBSP |
|
|
|
from .elements import FQuoted |
|
|
|
from .context import Group, InlineGroup, BlockGroup |
|
|
|
from .util import nullify, import_md |
|
|
|
from .context import Context |
|
|
|
from .context import Context, CommandCallable |
|
|
|
from .whitespace import Whitespace, bavlna |
|
|
|
from .command import BlockCommand, InlineCommand, Command |
|
|
|
from .command_util import handle_command_define, parse_command |
|
|
@ -33,6 +35,7 @@ class TransformProcessor: |
|
|
|
self.context: Context = None |
|
|
|
self.root_file_path = root_file_path |
|
|
|
self.root_highlight_style = "default" |
|
|
|
self._command_modules = [] |
|
|
|
|
|
|
|
self.TYPE_DICT = { |
|
|
|
TableRow: self.transform_TableRow, |
|
|
@ -100,6 +103,9 @@ class TransformProcessor: |
|
|
|
BlockCommand: self.transform_BlockCommand |
|
|
|
} |
|
|
|
|
|
|
|
def add_command_module(self, module: Union[dict[str, CommandCallable], ModuleType], module_name: str=""): |
|
|
|
self._command_modules.append((module, module_name)) |
|
|
|
|
|
|
|
def get_pretransformers(self) -> list[Callable[[ELCl],ELCl]]: |
|
|
|
return [self.handle_if_attribute, self.handle_ifnot_attribute] |
|
|
|
|
|
|
@ -324,6 +330,8 @@ class TransformProcessor: |
|
|
|
if self.context is not None: |
|
|
|
raise DoubleDocError() |
|
|
|
self.context = Context(e, self.root_file_path) |
|
|
|
for module, module_name in self._command_modules: |
|
|
|
self.context.add_commands_from_module(module, module_name) |
|
|
|
e.content = self.transform(e.content) |
|
|
|
e.content = [BlockGroup(*e.content, context=self.context)] |
|
|
|
return e |
|
|
@ -422,12 +430,25 @@ class TransformProcessor: |
|
|
|
e = InlineCommand(identifier=e.identifier, classes=e.classes, attributes={**e.attributes, "c": e.content[0].text[1:]}) |
|
|
|
return self.transform(e) |
|
|
|
|
|
|
|
## Handle import [#path/file.md]{} |
|
|
|
# This is the exact opposite of partials. We take the commands, flags |
|
|
|
# and metadata but drop the content. |
|
|
|
## Handle import [#ksp_formatitko as ksp]{}, [#ksp_formatitko]{type=module} or [#path/file.md]{type=md} |
|
|
|
# Import a python module as commands (type=module, the default) or |
|
|
|
# import all metadata from a md file, dropping its contents. |
|
|
|
elif re.match(r"^#.+$", e.content[0].text): |
|
|
|
importedDoc = import_md(open(self.context.dir + "/" + e.content[0].text[1:], "r").read()) |
|
|
|
self.transform(importedDoc.content) |
|
|
|
if not "type" in e.attributes: |
|
|
|
e.attributes["type"] = "module" |
|
|
|
if e.attributes["type"] == "md": |
|
|
|
importedDoc = import_md(open(self.context.dir + "/" + e.content[0].text[1:], "r").read()) |
|
|
|
self.transform(importedDoc.content) |
|
|
|
elif e.attributes["type"] == "module": |
|
|
|
matches = re.match(r"^(\w+)(?: as (\w+))?$", e.content[0].text[1:]) |
|
|
|
if not matches: |
|
|
|
raise SyntaxError(f"`{e.content[0].text[1:]}`: invalid syntax") |
|
|
|
module = importlib.import_module(matches.group(1)) |
|
|
|
module_name = matches.group(1) if matches.group(2) is None else matches.group(2) |
|
|
|
self.context.add_commands_from_module(module, module_name) |
|
|
|
else: |
|
|
|
raise SyntaxError(f"`{e.attributes['type']}`: invalid import type") |
|
|
|
|
|
|
|
return nullify(e) |
|
|
|
|
|
|
|
## Handle metadata print [$key1.key2]{} |
|
|
|