Přidáno několik způsobů, jak importovat commands. Resolves #31

This commit is contained in:
Jan Černohorský 2023-08-20 01:20:28 +02:00
parent d4eb343fa6
commit edbd985043
3 changed files with 32 additions and 9 deletions

View file

@ -46,9 +46,11 @@ class Context:
def unset_command(self, command: str):
del self._commands[command]
def add_commands_from_module(self, module: ModuleType, module_name: str=""):
def add_commands_from_module(self, module: Union[dict[str, CommandCallable], ModuleType], module_name: str=""):
if isinstance(module, ModuleType):
module = module.__dict__
prefix = module_name+"." if module_name else ""
for name, func in module.__dict__.items():
for name, func in module:
if isinstance(func, CommandCallable):
self.set_command(prefix+name, func)

View file

@ -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]{}

View file

@ -4,7 +4,7 @@ subtitle: 'A subtitle'
are_we_there_yet: False
lang: "en"
---
[#test-files/test-import.md]{}
[#test-files/test-import.md]{type=md}
# Hello world!
## H2