You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

74 lines
1.9 KiB

from panflute import Div,Span,Para
from typing import List
# Import local files
from util import *
from context import Context
from mj_show import show
class Command:
pass
class InlineCommand(Span, Command):
def replaceSelf(self, content: List[Element]) -> Span:
try:
return Span(*content)
except TypeError:
if len(content) == 1 and isinstance(content[0], Para):
return Span(*content[0].content)
else:
raise SyntaxError(f"The command {self.attributes['c']} returned multiple Paragraphs and must be executed using `::: {{c={self.attributes['c']}}}\\n:::`.")
pass
class BlockCommand(Div, Command):
def replaceSelf(self, content: List[Element]) -> Div:
return Div(*content)
pass
def handle_command_define(e: Element, c: Context):
if "define" in e.attributes:
if not c.get_command(e.attributes["define"]):
c.set_command(e.attributes["define"], compile(e.text, '<string>', 'exec'))
return nullify(e)
else:
raise NameError(f"Command already defined: '{e.attributes['define']}'")
if "redefine" in e.attributes:
c.set_command(e.attributes["redefine"], compile(e.text, '<string>', 'exec'))
return nullify(e)
def executeCommand(source, element: Element, ctx: Context) -> List[Element]:
mode = 'empty'
text = ""
content = []
def print(s: str=""):
nonlocal mode, text
if mode == 'elements':
raise SyntaxError("Cannot use `print` and `appendChild` in one command at the same time.")
mode = 'text'
text += s
def println(s: str=""):
print(s+"\n")
def appendChild(e: Element):
nonlocal mode, content
if mode == 'text':
raise SyntaxError("Cannot use `print` and `appendChild` in one command at the same time.")
mode = 'elements'
content.append(e)
def appendChildren(l: List[Element]):
for e in l:
appendChild(e)
exec(source)
if mode == 'text':
return import_md(text, standalone=False)
if mode == 'elements':
return content
return []