如何控制 pandoc 生成的乳胶中的表?
How to control tables in pandoc generated latex?
我正在使用 pandoc 将 Markdown 文档转换为 LaTeX。我保存了默认的 LaTeX 模板 (pandoc -D latex
) 并根据需要对其进行了修改。
我现在需要更改 table 的外观:
- 更改 table 字幕的文本颜色;
- 将字幕位置从 table 上方更改为 table 下方;
- 在单元格边界可见的地方使用 "grid" table;
- 将 headers 更改为灰色背景的粗体文本。
我能够使用以下方法更改 table 字幕(第 1 点)的颜色:
\usepackage{caption}
\DeclareCaptionFont{myColor}{\color[RGB]{40,70,119}}
\captionsetup{labelfont=myColor,textfont=myColor,position=bottom}
但 position
选项被忽略(第 2 点。)
我希望能够控制 pandoc 生成的 LaTeX 的样式 table。那可能吗?有什么建议吗?
谢谢!
实际上可以更改表格的生成方式,而不是稍后尝试修复它们。需要的是 pandoc 过滤器。
与其告诉 pandoc 生成最终文档,还需要将其 AST 提供给过滤器,以便生成所需的格式而不是默认格式。然后将修改后的 AST 发送回 pandoc 进行最终转换。
这个 AST 是 JSON 格式。
流程如下:
pandoc -t json -s | ./filter.py | pandoc -f json
其中 filter.py
是一个过滤器,将 JSON 数据作为 stdin
并将 JSON 修改为 stdout
。
这可以在没有管道的情况下通过告诉 pandoc 来完成:
pandoc --filter ./filter.py -s
这是我使用的过滤器:
#!/usr/bin/env python2
import pandocfilters as pf
def latex(s):
return pf.RawBlock('latex', s)
def inlatex(s):
return pf.RawInline('latex', s)
def tbl_caption(s):
return pf.Para([inlatex(r'\caption{')] + s + [inlatex('}')])
def tbl_alignment(s):
aligns = {
"AlignDefault": 'l',
"AlignLeft": 'l',
"AlignCenter": 'c',
"AlignRight": 'r',
}
return ''.join([aligns[e['t']] for e in s])
def tbl_headers(s):
result = s[0][0]['c'][:]
# Build the columns. Note how the every column value is bold.
# We are still missing "\textbf{" for the first column
# and a "}" for the last column.
for i in range(1, len(s)):
result.append(inlatex(r'} & \textbf{'))
result.extend(s[i][0]['c'])
# Don't forget to close the last column's "\textbf{" before newline
result.append(inlatex(r'} \ \hline'))
# Put the missing "\textbf{" in front of the list
result.insert(0, inlatex(r'\textbf{'))
# Preprend the command to set the row color in front of everything
result.insert(0, inlatex(r'\rowcolor{grey} '))
return pf.Para(result)
def tbl_contents(s):
result = []
for row in s:
para = []
for col in row:
para.extend(col[0]['c'])
para.append(inlatex(' & '))
result.extend(para)
result[-1] = inlatex(r' \ \hline' '\n')
return pf.Para(result)
def do_filter(k, v, f, m):
if k == "Table":
# Ensure every alignment characters is surrounded by a pipes.
# Get the string of the alignment characters
# and split into an array for every characters.
split_alignment = [c for c in tbl_alignment(v[1])]
# Join this list into a single string with pipe symbols
# between them, plus pipes at start and end.
# This results in a boxed table.
new_alignment = "|" + "|".join(split_alignment) + "|"
return [latex(r'\begin{table}[h]'),
latex(r'\centering'),
latex(r'\begin{tabular}{%s} \hline' % new_alignment),
tbl_headers(v[3]),
tbl_contents(v[4]),
latex(r'\end{tabular}'),
# Put the caption after the tabular so it appears under table.
tbl_caption(v[0]),
latex(r'\end{table}')]
if __name__ == "__main__":
pf.toJSONFilter(do_filter)
请注意,它正在使用 pandocfilters
python 模块。使用 pip
:
安装
pip install pandocfilters
来源:
我正在使用 pandoc 将 Markdown 文档转换为 LaTeX。我保存了默认的 LaTeX 模板 (pandoc -D latex
) 并根据需要对其进行了修改。
我现在需要更改 table 的外观:
- 更改 table 字幕的文本颜色;
- 将字幕位置从 table 上方更改为 table 下方;
- 在单元格边界可见的地方使用 "grid" table;
- 将 headers 更改为灰色背景的粗体文本。
我能够使用以下方法更改 table 字幕(第 1 点)的颜色:
\usepackage{caption}
\DeclareCaptionFont{myColor}{\color[RGB]{40,70,119}}
\captionsetup{labelfont=myColor,textfont=myColor,position=bottom}
但 position
选项被忽略(第 2 点。)
我希望能够控制 pandoc 生成的 LaTeX 的样式 table。那可能吗?有什么建议吗?
谢谢!
实际上可以更改表格的生成方式,而不是稍后尝试修复它们。需要的是 pandoc 过滤器。
与其告诉 pandoc 生成最终文档,还需要将其 AST 提供给过滤器,以便生成所需的格式而不是默认格式。然后将修改后的 AST 发送回 pandoc 进行最终转换。
这个 AST 是 JSON 格式。
流程如下:
pandoc -t json -s | ./filter.py | pandoc -f json
其中 filter.py
是一个过滤器,将 JSON 数据作为 stdin
并将 JSON 修改为 stdout
。
这可以在没有管道的情况下通过告诉 pandoc 来完成:
pandoc --filter ./filter.py -s
这是我使用的过滤器:
#!/usr/bin/env python2
import pandocfilters as pf
def latex(s):
return pf.RawBlock('latex', s)
def inlatex(s):
return pf.RawInline('latex', s)
def tbl_caption(s):
return pf.Para([inlatex(r'\caption{')] + s + [inlatex('}')])
def tbl_alignment(s):
aligns = {
"AlignDefault": 'l',
"AlignLeft": 'l',
"AlignCenter": 'c',
"AlignRight": 'r',
}
return ''.join([aligns[e['t']] for e in s])
def tbl_headers(s):
result = s[0][0]['c'][:]
# Build the columns. Note how the every column value is bold.
# We are still missing "\textbf{" for the first column
# and a "}" for the last column.
for i in range(1, len(s)):
result.append(inlatex(r'} & \textbf{'))
result.extend(s[i][0]['c'])
# Don't forget to close the last column's "\textbf{" before newline
result.append(inlatex(r'} \ \hline'))
# Put the missing "\textbf{" in front of the list
result.insert(0, inlatex(r'\textbf{'))
# Preprend the command to set the row color in front of everything
result.insert(0, inlatex(r'\rowcolor{grey} '))
return pf.Para(result)
def tbl_contents(s):
result = []
for row in s:
para = []
for col in row:
para.extend(col[0]['c'])
para.append(inlatex(' & '))
result.extend(para)
result[-1] = inlatex(r' \ \hline' '\n')
return pf.Para(result)
def do_filter(k, v, f, m):
if k == "Table":
# Ensure every alignment characters is surrounded by a pipes.
# Get the string of the alignment characters
# and split into an array for every characters.
split_alignment = [c for c in tbl_alignment(v[1])]
# Join this list into a single string with pipe symbols
# between them, plus pipes at start and end.
# This results in a boxed table.
new_alignment = "|" + "|".join(split_alignment) + "|"
return [latex(r'\begin{table}[h]'),
latex(r'\centering'),
latex(r'\begin{tabular}{%s} \hline' % new_alignment),
tbl_headers(v[3]),
tbl_contents(v[4]),
latex(r'\end{tabular}'),
# Put the caption after the tabular so it appears under table.
tbl_caption(v[0]),
latex(r'\end{table}')]
if __name__ == "__main__":
pf.toJSONFilter(do_filter)
请注意,它正在使用 pandocfilters
python 模块。使用 pip
:
pip install pandocfilters
来源: