|
|
@ -10,13 +10,11 @@ from typing import List |
|
|
|
from whitespace import * |
|
|
|
from command import * |
|
|
|
from util import * |
|
|
|
from context import * |
|
|
|
|
|
|
|
from mj_show import show |
|
|
|
|
|
|
|
flags = ["dog"] |
|
|
|
commands = {} |
|
|
|
|
|
|
|
def executeCommand(source: Code, element: Element) -> List[Element]: |
|
|
|
def executeCommand(source, element: Element, ctx: Context) -> List[Element]: |
|
|
|
mode = 'empty' |
|
|
|
text = "" |
|
|
|
content = [] |
|
|
@ -50,11 +48,8 @@ def executeCommand(source: Code, element: Element) -> List[Element]: |
|
|
|
|
|
|
|
return [] |
|
|
|
|
|
|
|
def transform(e: Element, doc: Doc) -> Element: # Returns next sibling element to transform |
|
|
|
def transform(e: Element, context: Context) -> Element: # Returns next sibling element to transform |
|
|
|
"""Transform the AST, making format-agnostic changes.""" |
|
|
|
|
|
|
|
global commands |
|
|
|
global flags |
|
|
|
|
|
|
|
if isinstance(e, Whitespace) and bavlna(e): |
|
|
|
e = NBSP() |
|
|
@ -62,11 +57,11 @@ def transform(e: Element, doc: Doc) -> Element: # Returns next sibling element t |
|
|
|
if hasattr(e, "attributes"): |
|
|
|
# `if` attribute. Only show this element if flag is set. |
|
|
|
if "if" in e.attributes: |
|
|
|
if not e.attributes["if"] in flags: |
|
|
|
if not context.is_flag_set(e.attributes["if"]): |
|
|
|
return nullify(e) |
|
|
|
# `ifn` attribute. Only show this element if flag is NOT set |
|
|
|
if "ifn" in e.attributes: |
|
|
|
if e.attributes["ifn"] in flags: |
|
|
|
if context.is_flag_set(e.attributes["ifn"]): |
|
|
|
return nullify(e) |
|
|
|
|
|
|
|
# `c` attribute. Execute a command with the name saved in this attribute. |
|
|
@ -82,29 +77,25 @@ def transform(e: Element, doc: Doc) -> Element: # Returns next sibling element t |
|
|
|
# document. |
|
|
|
if (isinstance(e, Div)) and "partial" in e.attributes: |
|
|
|
includedDoc = import_md(open(e.attributes["partial"], "r").read()) |
|
|
|
oFlags = flags[:] |
|
|
|
oCommands = commands.copy() |
|
|
|
includedDoc = includedDoc.walk(transform) |
|
|
|
flags = oFlags |
|
|
|
commands = oCommands |
|
|
|
nContext = Context(includedDoc, context) |
|
|
|
includedDoc = includedDoc.walk(transform, nContext) |
|
|
|
e = Div(*includedDoc.content) |
|
|
|
|
|
|
|
# Execute python code inside source code block |
|
|
|
if isinstance(e, CodeBlock) and hasattr(e, "classes") and "python" in e.classes and "run" in e.classes: |
|
|
|
exec(e.text) |
|
|
|
return nullify(e) |
|
|
|
e = executeCommand(e.text, None, context) |
|
|
|
|
|
|
|
## Command defines |
|
|
|
# possible TODO: def/longdef? |
|
|
|
if isinstance(e, CodeBlock) and hasattr(e, "classes") and "python" in e.classes and hasattr(e, "attributes"): |
|
|
|
if "define" in e.attributes: |
|
|
|
if not e.attributes["define"] in commands: |
|
|
|
commands[e.attributes["define"]] = compile(e.text, '<string>', 'exec') |
|
|
|
if not context.get_command(e.attributes["define"]): |
|
|
|
context.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: |
|
|
|
commands[e.attributes["redefine"]] = compile(e.text, '<string>', 'exec') |
|
|
|
context.set_command(e.attributes["redefine"], compile(e.text, '<string>', 'exec')) |
|
|
|
return nullify(e) |
|
|
|
|
|
|
|
## Shorthands |
|
|
@ -118,7 +109,7 @@ def transform(e: Element, doc: Doc) -> Element: # Returns next sibling element t |
|
|
|
# and flags but drop the content. |
|
|
|
elif re.match(r"^#.+$", e.content[0].text): |
|
|
|
importedDoc = import_md(open(e.content[0].text[1:], "r").read()) |
|
|
|
importedDoc.walk(transform) |
|
|
|
importedDoc.walk(transform, context) |
|
|
|
return nullify(e) |
|
|
|
|
|
|
|
## Execute commands |
|
|
@ -126,10 +117,10 @@ def transform(e: Element, doc: Doc) -> Element: # Returns next sibling element t |
|
|
|
# so the content of the element the command receives is |
|
|
|
# already transformed. |
|
|
|
if isinstance(e, Command): |
|
|
|
if not e.attributes["c"] in commands: |
|
|
|
if not context.get_command(e.attributes["c"]): |
|
|
|
raise NameError(f"Command not defined '{e.attributes['c']}'.") |
|
|
|
e = e.replaceSelf(executeCommand(commands[e.attributes["c"]], e)) |
|
|
|
e.walk(transform) |
|
|
|
e = e.replaceSelf(executeCommand(context.get_command(e.attributes["c"]), e, context)) |
|
|
|
e.walk(transform, context) |
|
|
|
|
|
|
|
return e |
|
|
|
|
|
|
@ -138,7 +129,8 @@ doc = import_md(open(sys.argv[1], "r").read()) |
|
|
|
|
|
|
|
|
|
|
|
print(show(doc)) |
|
|
|
doc = doc.walk(transform) |
|
|
|
context = Context(doc) |
|
|
|
doc = doc.walk(transform, context) |
|
|
|
print("---------------------") |
|
|
|
#print(show(doc)) |
|
|
|
print(convert_text(doc, input_format="panflute", output_format="markdown")) |
|
|
|