Skip to content

Commit 6a480bc

Browse files
committed
feat: add own table caption extension
1 parent 3995af5 commit 6a480bc

File tree

5 files changed

+115
-4
lines changed

5 files changed

+115
-4
lines changed

mdx_extensions/__init__.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
from .remove_include import RemoveIncludeExtension
22
from .remove_references import RemoveReferencesExtension
33
from .replace_variables import ReplaceVariablesExtension
4+
from .table_captions import TableCaptionExtension
45

5-
__all__ = ['RemoveIncludeExtension', 'RemoveReferencesExtension', 'ReplaceVariablesExtension']
6+
__all__ = [
7+
'RemoveIncludeExtension',
8+
'RemoveReferencesExtension',
9+
'ReplaceVariablesExtension',
10+
'TableCaptionExtension'
11+
]

mdx_extensions/table_captions.py

+106
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
from markdown.treeprocessors import Treeprocessor
2+
from markdown.extensions import Extension
3+
from markdown.extensions.attr_list import AttrListTreeprocessor, AttrListExtension
4+
5+
from typing import Any
6+
from markdown import Markdown
7+
from xml.etree.ElementTree import Element
8+
9+
class TableCaptionTreeProcessor(Treeprocessor):
10+
def __init__(self, md: Markdown, config: dict[str, Any]):
11+
super().__init__(md)
12+
self.config = config
13+
self.checked_for_deps = False
14+
self.use_attr_list = False
15+
self.attr_list_processor = AttrListTreeprocessor(md)
16+
17+
def isTable(self, elem: Element):
18+
return elem.tag == 'table' and not any(child.tag == 'caption' for child in elem)
19+
20+
def isTableCaption(self, elem: Element):
21+
return elem.tag == 'p' and elem.text and elem.text.strip().startswith(('Table:', 'table:', ':'))
22+
23+
def getCaptionAndAttrs(self, elem: Element):
24+
caption_text = elem.text.strip().split(':', 1)[1].strip()
25+
attrs_string = ''
26+
27+
if self.use_attr_list and caption_text.endswith('}'):
28+
attrs_start = caption_text.rfind('{')
29+
if attrs_start != -1:
30+
attrs_string = caption_text[attrs_start + 1 : -1]
31+
caption_text = caption_text[:attrs_start].strip()
32+
33+
return (caption_text, attrs_string)
34+
35+
36+
def insertCaptionToTable(self, table: Element, caption: Element):
37+
caption_text, attrs_string = self.getCaptionAndAttrs(caption)
38+
39+
if caption_text:
40+
caption = Element('caption')
41+
caption.text = caption_text
42+
table.insert(0, caption)
43+
44+
if self.use_attr_list and attrs_string:
45+
self.attr_list_processor.assign_attrs(table, attrs_string)
46+
47+
48+
def run(self, doc: Element) -> None:
49+
# Check for dependent extensions
50+
if not self.checked_for_deps:
51+
for ext in self.md.registeredExtensions:
52+
if isinstance(ext, AttrListExtension):
53+
self.use_attr_list = True
54+
55+
self.checked_for_deps = True
56+
57+
need_to_remove = []
58+
59+
last_is_caption = False
60+
last_is_table = False
61+
last_elem = None
62+
63+
for elem in doc:
64+
if self.isTableCaption(elem):
65+
if last_is_table:
66+
self.insertCaptionToTable(last_elem, elem)
67+
need_to_remove.append(elem)
68+
69+
last_elem = None
70+
last_is_caption = False
71+
last_is_table = False
72+
73+
else:
74+
last_elem = elem
75+
last_is_caption = True
76+
last_is_table = False
77+
78+
elif self.isTable(elem):
79+
if last_is_caption:
80+
self.insertCaptionToTable(elem, last_elem)
81+
need_to_remove.append(last_elem)
82+
83+
last_elem = None
84+
last_is_caption = False
85+
last_is_table = False
86+
87+
else:
88+
last_elem = elem
89+
last_is_caption = False
90+
last_is_table = True
91+
92+
else:
93+
last_elem = None
94+
last_is_caption = False
95+
last_is_table = False
96+
97+
for elem in need_to_remove:
98+
doc.remove(elem)
99+
100+
101+
class TableCaptionExtension(Extension):
102+
def extendMarkdown(self, md):
103+
md.treeprocessors.register(TableCaptionTreeProcessor(md, self.getConfigs()), 'table_captions', 25)
104+
105+
def makeExtension(**kwargs):
106+
return TableCaptionExtension(**kwargs)

mkdocs-base.yml

+1-2
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,7 @@ markdown_extensions:
2929
- def_list
3030
- markdown_grid_tables
3131
- markdown_captions # for image caption, use alt as caption
32-
- table_captions: # for table caption, use Table: xxxx
33-
numbering: false
32+
- table_captions # for table caption, use Table: xxxx
3433
- remove_references
3534
- remove_include
3635
- replace_variables:

pyproject.toml

+1
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,4 @@ packages = ["mdx_extensions"]
2323
remove_include = "mdx_extensions:RemoveIncludeExtension"
2424
remove_references = "mdx_extensions:RemoveReferencesExtension"
2525
replace_variables = "mdx_extensions:ReplaceVariablesExtension"
26+
table_captions = "mdx_extensions:TableCaptionExtension"

requirements.txt

-1
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,4 @@ mkdocs-material~=9.5.0
22
markdown_grid_tables>=0.4.0
33
markdown-captions~=2.1.0
44
jieba~=0.42.0
5-
git+https://github.com/flywire/caption
65
git+https://github.com/OpenXiangShan/docs-utils.git

0 commit comments

Comments
 (0)