-
Notifications
You must be signed in to change notification settings - Fork 0
/
mdx_attr_cols.py
89 lines (69 loc) · 2.72 KB
/
mdx_attr_cols.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
""" Bootstrap 3 grid extension fo Python Markdown
"""
from xml.etree import ElementTree as etree
from markdown import Extension
from markdown.treeprocessors import Treeprocessor
class AttrColTreeProcessor(Treeprocessor):
""" The attr_cols element tree processor. """
CONF_DEFAULTS = {
'columns': 12,
'attr': 'cols',
'tags': ['section'],
}
def __init__(self, md, conf):
super(AttrColTreeProcessor, self).__init__(md)
conf_vars = self.CONF_DEFAULTS.copy()
conf_vars.update(conf or {})
self.columns = int(conf_vars.get('columns'))
self.attr = str(conf_vars.get('attr'))
self.tags = set(conf_vars.get('tags'))
def create_rows(self, node):
row, row_cols = None, 0
for i, child in enumerate(list(node)):
if child.tag.lower() not in self.tags:
continue
if self.attr not in child.attrib:
if row is None:
# if there currently isn't a row, search sub-sections
self.create_rows(child)
else:
row, row_cols = None, 0
continue
cols = int(child.attrib[self.attr])
del child.attrib[self.attr]
if row is None:
row = etree.Element("div", {"class": "row"})
node.insert(i, row)
col = etree.SubElement(row, "div", {
"class": "col-md-%d" % (cols,),
})
row_cols += cols
col.append(child)
node.remove(child)
if row_cols >= self.columns:
row, row_cols = None, 0
def run(self, root):
self.create_rows(root)
return root
class AttrColExtension(Extension):
""" The attr_cols markdown extension. """
REQUIRED_EXTENSIONS = ('attr_list', 'mdx_outline')
REQUIRED_EXTENSION_INTERNAL_NAMES = ('attr_list', 'outline')
def __init__(self, configs):
self.conf = configs
def extendMarkdown(self, md, md_globals=None):
"""Initializes markdown extension components."""
if any(
x not in md.treeprocessors
for x in self.REQUIRED_EXTENSION_INTERNAL_NAMES):
raise RuntimeError(
"The attr_cols markdown extension depends the following"
" extensions which must preceded it in the extension"
" list: %s" % ", ".join(self.REQUIRED_EXTENSIONS))
processor = AttrColTreeProcessor(md, self.conf)
md.treeprocessors.register(
processor, 'attr_cols',
5) # 5 is the lowest priority
def makeExtension(**kwargs):
""" Initialize the attr_cols extension. """
return AttrColExtension(configs=kwargs)