@ -72,18 +72,30 @@ def transform(e: Element, doc: Doc) -> Element: # Returns next sibling element t
# `c` attribute. Execute a command with the name saved in this attribute.
# `c` attribute. Execute a command with the name saved in this attribute.
if ( isinstance ( e , Div ) or isinstance ( e , Span ) ) and " c " in e . attributes :
if ( isinstance ( e , Div ) or isinstance ( e , Span ) ) and " c " in e . attributes :
if isinstance ( e , Div ) :
if isinstance ( e , Div ) :
e = Multiline Command( * e . content , identifier = e . identifier , classes = e . classes , attributes = e . attributes )
e = Block Command( * e . content , identifier = e . identifier , classes = e . classes , attributes = e . attributes )
else :
else :
e = InlineCommand ( * e . content , identifier = e . identifier , classes = e . classes , attributes = e . attributes )
e = InlineCommand ( * e . content , identifier = e . identifier , classes = e . classes , attributes = e . attributes )
# `partial` attribute.
# This is for including content from files with their own flags
# and commands without affecting the state of the current
# 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
e = Div ( * includedDoc . content )
# Execute python code inside source code block
# 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 :
if isinstance ( e , CodeBlock ) and hasattr ( e , " classes " ) and " python " in e . classes and " run " in e . classes :
exec ( e . text )
exec ( e . text )
return nullify ( e )
return nullify ( e )
## Define commands
## Command define s
# TODO: def/longdef?
# possible TODO: def/longdef?
if isinstance ( e , CodeBlock ) and hasattr ( e , " classes " ) and " python " in e . classes and hasattr ( e , " attributes " ) :
if isinstance ( e , CodeBlock ) and hasattr ( e , " classes " ) and " python " in e . classes and hasattr ( e , " attributes " ) :
if " define " in e . attributes :
if " define " in e . attributes :
if not e . attributes [ " define " ] in commands :
if not e . attributes [ " define " ] in commands :
@ -95,30 +107,17 @@ def transform(e: Element, doc: Doc) -> Element: # Returns next sibling element t
commands [ e . attributes [ " redefine " ] ] = compile ( e . text , ' <string> ' , ' exec ' )
commands [ e . attributes [ " redefine " ] ] = compile ( e . text , ' <string> ' , ' exec ' )
return nullify ( e )
return nullify ( e )
## Shorthands
if isinstance ( e , Span ) and len ( e . content ) == 1 and isinstance ( e . content [ 0 ] , Str ) :
if isinstance ( e , Span ) and len ( e . content ) == 1 and isinstance ( e . content [ 0 ] , Str ) :
print ( isinstance ( e , Span ) )
## Handle special command shorthand [!commandname]{}
## Handle special command shorthand [!commandname]{}
if re . match ( r " ^![ \ w.]+$ " , e . content [ 0 ] . text ) :
if re . match ( r " ^![ \ w.]+$ " , e . content [ 0 ] . text ) :
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 : ] } )
## Handle include [>path/file.md]{} TODO: implement properly as commands
## Handle import [#path/file.md]{}
# This is for including content from files with their own flags
# and commands without affecting the state of the current
# document.
elif re . match ( r " ^>.+$ " , e . content [ 0 ] . text ) :
includedDoc = convert_text ( open ( e . content [ 0 ] . text [ 1 : ] , " r " ) . read ( ) , standalone = True ) # TODO: Put into function
oCommands = commands . copy ( )
oFlags = flags [ : ]
includedDoc = includedDoc . walk ( transform )
commands = oCommands
flags = oFlags
#e = Div(*includedDoc.content)
## Handle import [#path/file.md]{} TODO: implement properly as commands
# This is the exact opposite of include. We take the commands
# This is the exact opposite of include. We take the commands
# and flags but drop the content.
# and flags but drop the content.
elif re . match ( r " ^#.+$ " , e . content [ 0 ] . text ) :
elif re . match ( r " ^#.+$ " , e . content [ 0 ] . text ) :
importedDoc = convert_text ( open ( e . content [ 0 ] . text [ 1 : ] , " r " ) . read ( ) , standalone = True ) # TODO: Put into function
importedDoc = import_md ( open ( e . content [ 0 ] . text [ 1 : ] , " r " ) . read ( ) )
importedDoc . walk ( transform )
importedDoc . walk ( transform )
return nullify ( e )
return nullify ( e )
@ -126,16 +125,16 @@ def transform(e: Element, doc: Doc) -> Element: # Returns next sibling element t
# Walk transforms the children first, then the root element,
# Walk transforms the children first, then the root element,
# so the content of the element the command receives is
# so the content of the element the command receives is
# already transformed.
# already transformed.
# TODO: Transform content that comes out of commands.
if isinstance ( e , Command ) :
if isinstance ( e , Command ) :
if not e . attributes [ " c " ] in commands :
if not e . attributes [ " c " ] in commands :
raise NameError ( f " Command not defined ' { e . attributes [ ' c ' ] } ' . " )
raise NameError ( f " Command not defined ' { e . attributes [ ' c ' ] } ' . " )
e = e . replaceSelf ( executeCommand ( commands [ e . attributes [ " c " ] ] , e ) )
e = e . replaceSelf ( executeCommand ( commands [ e . attributes [ " c " ] ] , e ) )
e . walk ( transform )
return e
return e
doc = import_md ( open ( sys . argv [ 1 ] , " r " ) . read ( ) )
doc = convert_text ( open ( sys . argv [ 1 ] , " r " ) . read ( ) , standalone = True ) # TODO: Put into function so we can specify extensions and parameters globally.
print ( show ( doc ) )
print ( show ( doc ) )