You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

94 lines
2.9 KiB

from panflute import Doc, Div
from typing import Dict
import os
# This class is used to keep state while transforming the document using
# transform.py. For the context to be available to the html and TeX generators,
# individual keys must be manually assigned to the individual elements. This is
# done in transform.py.
#
# The context is also aware of its parent contexts and relevant data (such as
# metadata and commands) can be read from the closest parent context. Writing
# only happens to the current one.
#
# This class is basically an extension to panflute's doc, this is why metadata
# is read directly from it.
class Context:
def __init__(self, doc: Doc, path: str, parent: 'Context'=None, trusted: bool=True):
self.parent = parent
self._commands = {}
self.doc = doc
self.trusted = trusted
self.path = path
self.dir = os.path.dirname(path) if os.path.dirname(path) != "" else "."
self.filename = os.path.basename(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:
return self._commands[command]
elif self.parent:
return self.parent.get_command(command)
else:
return None
def set_command(self, command: str, val):
self._commands[command] = val
def unset_command(self, command: str):
del self._commands[command]
def is_flag_set(self, flag: str):
if self.get_metadata("flags."+flag):
if self.get_metadata("flags."+flag):
return True
else:
return False
elif self.parent:
return self.parent.is_flag_set(flag)
else:
return False
def set_flag(self, flag: str, val: bool):
self.set_metadata("flags."+flag, val)
def unset_flag(self, flag: str):
self.unset_metadata("flags."+flag)
def get_metadata(self, key: str, simple: bool=True, immediate: bool=False):
value = self.doc.get_metadata(key, None, simple)
if value is not None:
return value
elif self.parent and not immediate:
return self.parent.get_metadata(key)
else:
return None
def set_metadata(self, key: str, value):
if key == "language":
print("WARN: Setting language this way doesn't propagate to TeX. Either use the Front Matter or specify it additionally using the \\languagexx macro.")
meta = self.doc.metadata
key = key.split(".")
for k in key[:-1]:
meta = meta[k]
meta[key[-1]] = value
def unset_metadata(self, key: str):
meta = self.doc.metadata
key = key.split(".")
for k in key[:-1]:
meta = meta[k]
del meta.content[key[-1]] # A hack because MetaMap doesn't have a __delitem__
# This is a custom element which creates \begingroup \endgroup groups in TeX
# and also causes KaTeX math blocks to be isolated in a similar way.
#
# Whenever a new context is created, its content should be eclosed in a group and vice-versa.
class Group(Div):
def __init__(self, *args, metadata={}, **kwargs):
self.metadata = metadata
super().__init__(*args, **kwargs)