Browse Source

Syntax highlighting and miscellaneous fixes.

pull/28/head
Jan Černohorský 1 year ago
parent
commit
a5e87aefde
  1. 7
      command.py
  2. 24
      context.py
  3. 2
      formatitko.py
  4. 21
      html.py
  5. 4
      test-import.md
  6. 5
      test-partial.md
  7. 6
      test.md
  8. 13
      transform.py

7
command.py

@ -33,9 +33,10 @@ def handle_command_define(e: Element, c: Context):
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)
if "redefine" in e.attributes:
c.set_command(e.attributes["redefine"], compile(e.text, '<string>', 'exec'))
return nullify(e)
return e
def executeCommand(source, element: Element, ctx: Context) -> List[Element]:

24
context.py

@ -2,11 +2,13 @@
from panflute import Doc
class Context:
def __init__(self, doc: Doc=None, parent: 'Context'=None):
def __init__(self, doc: Doc, path: str, parent: 'Context'=None):
self.parent = parent
self._commands = {}
self._flags = {}
self.doc = doc
self.path = path
if self.get_metadata("flags", immediate=True) is None:
self.set_metadata("flags", {})
def get_command(self, command: str):
if command in self._commands:
@ -23,24 +25,27 @@ class Context:
del self._commands[command]
def is_flag_set(self, flag: str):
if flag in self._flags and self._flags[flag]:
return True
if self.get_metadata("flags."+flag):
if self.get_metadata("flags."+flag):
return True
else:
return False
elif self.parent:
return self.parent.is_set(flag)
return self.parent.is_flag_set(flag)
else:
return False
def set_flag(self, flag: str, val: bool):
self._flags[flag] = val
self.set_metadata("flags."+flag, val)
def unset_flag(self, flag):
del self._flags[flag]
self.unset_metadata("flags."+flag)
def get_metadata(self, key, simple=True):
def get_metadata(self, key, simple=True, immediate=False):
value = self.doc.get_metadata(key, None, simple)
if value is not None:
return value
elif self.parent:
elif self.parent and not immediate:
return self.parent.get_metadata(key)
else:
return None
@ -57,6 +62,5 @@ class Context:
key = key.split(".")
for k in key[:-1]:
meta = meta[k]
print(type(meta))
del meta.content[key[-1]] # A hack because MetaMap doesn't have a __delitem__

2
formatitko.py

@ -18,7 +18,7 @@ doc = import_md(open(sys.argv[1], "r").read())
print(show(doc))
context = Context(doc)
context = Context(doc, sys.argv[1])
doc = doc.walk(transform, context)
print("---------------------")
#print(show(doc))

21
html.py

@ -1,4 +1,9 @@
from panflute import *
from pygments import highlight
from pygments.lexers import get_lexer_by_name
from pygments.formatters import HtmlFormatter
from pygments.util import ClassNotFound
from whitespace import NBSP
from transform import FQuoted
from katex import KatexClient
@ -64,8 +69,20 @@ def html(e: Element, k: KatexClient, indent_level: int=0, indent_str: str="\t")
attributes += f' class="{" ".join(e.classes)}"'
if isinstance(e, CodeBlock):
# TODO: Syntax highlighting
tag = "pre"
if e.attributes["highlight"] == True or e.attributes["highlight"] == 'True':
for cl in e.classes:
try:
lexer = get_lexer_by_name(cl)
except ClassNotFound:
continue
break
formatter = HtmlFormatter(style=e.attributes["style"])
result = highlight(e.text, lexer, formatter)
style = formatter.get_style_defs(".highlight")
return f'<style>{style}</style>{result}'
else:
return f'<pre>{e.text}</pre>'
if isinstance(e, Figure):
content_foot = html(e.caption, k, indent_level+1, indent_str)

4
test-import.md

@ -1,7 +1,7 @@
``` {.python define=nop}
```python {define=nop}
appendChildren(element.content)
```
``` {.python define=opendatatask}
```python {define=opendatatask}
println("Toto je praktická open-data úloha. V [odevzdávátku](https://ksp.mff.cuni.cz/h/odevzdavatko/) si necháte vygenerovat vstupy a odevzdáte příslušné výstupy. Záleží jen na vás, jak výstupy vyrobíte.")
```

5
test-partial.md

@ -7,6 +7,10 @@ I am a little piece of content
And things...
:::{if=cat}
:::
``` {.python .run}
# I set my own flags!
ctx.set_flag("cat", True)
@ -40,3 +44,4 @@ I am a duck.
:::{if=cat}
This should be only shown to included cats.
:::

6
test.md

@ -16,18 +16,18 @@ This should only be shown to cats
:::
``` {.python .run}
```python {.run}
ctx.set_flag("cat", True)
```
``` {.python .run}
```python {.run}
println(f"The main document's title is '{ctx.get_metadata('title')}'")
ctx.set_metadata("a", {})
ctx.set_metadata("a.b", {})
ctx.set_metadata("a.b.c", "Bruh **bruh** bruh")
```
```python
```python {style=native}
def bruh(no):
wat
```

13
transform.py

@ -15,7 +15,6 @@ class FQuoted(Quoted):
def transform(e: Element, c: Context) -> Element: # Returns next sibling element to transform
"""Transform the AST, making format-agnostic changes."""
if isinstance(e, Whitespace) and bavlna(e, c):
e = NBSP()
@ -41,7 +40,7 @@ def transform(e: Element, c: Context) -> Element: # Returns next sibling element
# 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())
nContext = Context(includedDoc, c)
nContext = Context(includedDoc, e.attributes["partial"], c)
includedDoc = includedDoc.walk(transform, nContext)
e = Div(*includedDoc.content)
@ -60,9 +59,17 @@ def transform(e: Element, c: Context) -> Element: # Returns next sibling element
## Command defines
# 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")\
and ("define" in e.attributes or "redefine" in e.attributes):
e = handle_command_define(e, c)
# Pass down metadata 'highlight' and 'highlight_style' as attribute to CodeBlocks
if isinstance(e, CodeBlock):
if not "highlight" in e.attributes:
e.attributes["highlight"] = c.get_metadata("highlight") if c.get_metadata("highlight") is not None else True
if not "style" in e.attributes:
e.attributes["style"] = c.get_metadata("highlight_style") if c.get_metadata("highlight_style") is not None else "default"
## Shorthands
if isinstance(e, Span) and len(e.content) == 1 and isinstance(e.content[0], Str):
## Handle special command shorthand [!commandname]{}

Loading…
Cancel
Save