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): def unset_command(self, command: str):
del self._commands[command] 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 "" prefix = module_name+"." if module_name else ""
for name, func in module.__dict__.items(): for name, func in module:
if isinstance(func, CommandCallable): if isinstance(func, CommandCallable):
self.set_command(prefix+name, func) 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 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 panflute import TableRow, TableCell, Caption, Doc
from typing import Union, Callable from typing import Union, Callable
from types import ModuleType
import os import os
import re import re
import warnings import warnings
import importlib
from .whitespace import NBSP from .whitespace import NBSP
from .elements import FQuoted 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 from .context import Context, CommandCallable
from .whitespace import Whitespace, bavlna from .whitespace import Whitespace, bavlna
from .command import BlockCommand, InlineCommand, Command from .command import BlockCommand, InlineCommand, Command
from .command_util import handle_command_define, parse_command from .command_util import handle_command_define, parse_command
@ -33,6 +35,7 @@ class TransformProcessor:
self.context: Context = None self.context: Context = None
self.root_file_path = root_file_path self.root_file_path = root_file_path
self.root_highlight_style = "default" self.root_highlight_style = "default"
self._command_modules = []
self.TYPE_DICT = { self.TYPE_DICT = {
TableRow: self.transform_TableRow, TableRow: self.transform_TableRow,
@ -100,6 +103,9 @@ class TransformProcessor:
BlockCommand: self.transform_BlockCommand 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]]: def get_pretransformers(self) -> list[Callable[[ELCl],ELCl]]:
return [self.handle_if_attribute, self.handle_ifnot_attribute] return [self.handle_if_attribute, self.handle_ifnot_attribute]
@ -324,6 +330,8 @@ class TransformProcessor:
if self.context is not None: if self.context is not None:
raise DoubleDocError() raise DoubleDocError()
self.context = Context(e, self.root_file_path) 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 = self.transform(e.content)
e.content = [BlockGroup(*e.content, context=self.context)] e.content = [BlockGroup(*e.content, context=self.context)]
return e 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:]}) e = InlineCommand(identifier=e.identifier, classes=e.classes, attributes={**e.attributes, "c": e.content[0].text[1:]})
return self.transform(e) return self.transform(e)
## Handle import [#path/file.md]{} ## Handle import [#ksp_formatitko as ksp]{}, [#ksp_formatitko]{type=module} or [#path/file.md]{type=md}
# This is the exact opposite of partials. We take the commands, flags # Import a python module as commands (type=module, the default) or
# and metadata but drop the content. # import all metadata from a md file, dropping its contents.
elif re.match(r"^#.+$", e.content[0].text): elif re.match(r"^#.+$", e.content[0].text):
importedDoc = import_md(open(self.context.dir + "/" + e.content[0].text[1:], "r").read()) if not "type" in e.attributes:
self.transform(importedDoc.content) 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) return nullify(e)
## Handle metadata print [$key1.key2]{} ## Handle metadata print [$key1.key2]{}

2
test/test.md

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

Loading…
Cancel
Save