[英]Global include in restructured text
我正在为我的博客/网站使用reStructuredText,我想添加一个全局包含文件。 我有权访问并很乐意更改我用于生成html输出的设置文件,我无法弄清楚以下两者的语法:
我尝试阅读源代码和文档,发现它有点难以理解。 我希望我只是错过了一些非常明显的东西,但是我想做类似下面的事情(第一部分就是已经存在的东西 - 你可以在jekyll-rst插件中看到文件的其余部分来源(链接到它)
import sys
from docutils.core import publish_parts
from optparse import OptionParser
from docutils.frontend import OptionParser as DocutilsOptionParser
from docutils.parsers.rst import Parser
# sets up a writer that is then called to parse rst pages repeatedly
def transform(writer=None, part=None):
p = OptionParser(add_help_option=False)
# Collect all the command line options
docutils_parser = DocutilsOptionParser(components=(writer, Parser()))
for group in docutils_parser.option_groups:
p.add_option_group(group.title, None).add_options(group.option_list)
p.add_option('--part', default=part)
opts, args = p.parse_args()
# ... more settings, etc
# then I just tell the parser/writer to process specified file X.rst every time
# (or alternately a python file defining more roles...but nicer if in rst)
有一个简单的方法吗? 定义一个文件defaults.rst
并且每次都加载它会很棒。
编辑:以下是我希望能够全局包含的一些示例(自定义指令也会很好,但我可能会在代码中编写它们)
.. role:: raw-html(raw)
:format: html
.. |common-substitution| replace:: apples and orange
.. |another common substitution| replace:: etc
我不太确定我是否理解这个问题。 您是否要在某些文件中定义一些替换,并在所有其他reStructuredText文件中使用这些替换,或者是否要在输出文件中包含一些常见的HTML? 你能澄清一下你的问题吗?
如果它是你想要做的前者,你可以使用include
指令,正如我在这个答案中概述的那样。
或者,如果您想在生成的输出中包含一些常见的HTML,请尝试复制和编辑template.txt
文件,该文件包含在模块path/to/docutils/writers/html4css1/
。 您可以在此文件中包含任意HTML元素,并修改Docutils生成的HTML的布局。 这些方法都不需要您修改Docuitls源代码,这始终是一个优势。
编辑 :我认为不可能使用Docuitls设置标志来设置包含文件。 但是,如果你可以使用基于Docuitls但有大量扩展的Sphinx ,那么这个软件包有一个设置rst_prolog
,它可以完全满足你的需要(参见这个答案 )。 rst_prolog
是:
一串reStructuredText,它将包含在每个读取的源文件的开头。
我需要完全相同的东西:一种方法可以将一些全局的reStructuredText文件自动导入到每个reStructuredText文章中,而无需每次手动指定它们。
这个问题的一个解决方案是以下插件:
import os
from pelican import signals
from pelican.readers import RstReader
class RstReaderWrapper(RstReader):
enabled = RstReader.enabled
file_extensions = ['rst']
class FileInput(RstReader.FileInput):
def __init__(self, *args, **kwargs):
RstReader.FileInput_.__init__(self, *args, **kwargs)
self.source = RstReaderWrapper.SourceWrapper(self.source)
# Hook into RstReader
RstReader.FileInput_ = RstReader.FileInput
RstReader.FileInput = FileInput
class SourceWrapper():
"""
Mimics and wraps the result of a call to `open`
"""
content_to_prepend = None
def __init__(self, source):
self.source = source
def read(self):
content = self.source.read()
if self.content_to_prepend is not None:
content = "{}\n{}".format(self.content_to_prepend, content)
return content
def close(self):
self.source.close()
def process_settings(pelicanobj):
include_files = pelicanobj.settings.get('RST_GLOBAL_INCLUDES', []) or []
base_path = pelicanobj.settings.get('PATH', ".")
def read(fn):
with open(os.path.join(base_path, fn), 'r') as res:
content = res.read()
return ".. INLCUSION FROM {}\n{}\n".format(fn, content)
inclusion = "".join(map(read, include_files)) if include_files else None
RstReaderWrapper.SourceWrapper.content_to_prepend = inclusion
def register():
signals.initialized.connect(process_settings)
用法简述:
pelicanconf.py
调整PLUGINS
) RST_GLOBAL_INCLUDES
中设置变量RST_GLOBAL_INCLUDES
来pelicanconf.py
要包含的RST文件列表(项目根目录的相对路径) 请注意,鹈鹕和docutils都不是为了这个而设计的。 在处理开始之前,既没有提供信号提供对源文件的原始内容的干净访问,也没有可能以“正常方式”拦截读取文件的框架(如子类化,更改硬编码配置等) 。 此插件对RstReader
的内部类FileInput
进行子类化, RstReader
的类引用 RstReader.FileInput
为子类。 还通过SourceWrapper
模拟python文件对象。 然而,这种方法对我有用,并且在日常工作流程中并不麻烦。
我知道这个问题是从2012年开始的,但我认为这个答案对其他人来说仍然有用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.