Browse Source

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

citace
Jan Černohorský 10 months ago
parent
commit
edbd985043
  1. 6
      src/formatitko/context.py
  2. 33
      src/formatitko/transform_processor.py
  3. 2
      test/test.md

6
src/formatitko/context.py

@ -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)

33
src/formatitko/transform_processor.py

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

2
test/test.md

@ -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

Loading…
Cancel
Save