34 lines
1.2 KiB
Python
34 lines
1.2 KiB
Python
from .context import Context, CommandCallable # This is there because of a wild circular import dependency between many functions and classes
|
|
from panflute import CodeBlock, Null
|
|
|
|
|
|
from . import command_env
|
|
from .util import nullify
|
|
|
|
def parse_command(code: str) -> CommandCallable:
|
|
code_lines = code.split("\n")
|
|
tabs = False
|
|
for line in code_lines:
|
|
if len(line) != 0 and line[0] == "\t":
|
|
tabs = True
|
|
break
|
|
indented_code_lines = []
|
|
for line in code_lines:
|
|
indented_code_lines.append(("\t" if tabs else " ")+line)
|
|
code = "def command(element: Command, context: Context) -> list[Element]:\n"+"\n".join(indented_code_lines)
|
|
env = {**command_env.__dict__}
|
|
exec(code, env)
|
|
return env["command"]
|
|
|
|
# This function is called in trasform.py, defining a command which can be
|
|
# called later
|
|
def handle_command_define(e: CodeBlock, c: Context) -> Null:
|
|
command = parse_command(e.text)
|
|
if "define" in e.attributes:
|
|
if not c.get_command(e.attributes["define"]):
|
|
c.set_command(e.attributes["define"], command)
|
|
else:
|
|
raise NameError(f"Command already defined: '{e.attributes['define']}'")
|
|
if "redefine" in e.attributes:
|
|
c.set_command(e.attributes["redefine"], command)
|
|
return nullify(e)
|