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 [ ]