我正在为我的博客/网站使用reStructuredText,我想添加一个全局包含文件。我有权访问并很乐意更改我用于生成html输出的设置文件,我无法弄清楚其中的语法:
我尝试阅读源代码和文档,但发现它有点难以理解。我希望我只是错过了一些非常明显的东西,但是我想做类似下面的事情(第一部分就是已经存在的东西 - 你可以看到rest of the file in the jekyll-rst plugin source (links right to it)
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
答案 0 :(得分:2)
我不太确定我是否理解这个问题。您是否要在某些文件中定义一些替换,并在所有其他reStructuredText文件中使用这些替换,或者是否要在输出文件中包含一些常见的HTML?你能澄清一下你的问题吗?
如果您要做的是前者,可以使用include
指令,我在this answer中概述。
或者,如果您想在生成的输出中包含一些常见的HTML,请尝试复制和编辑模块template.txt
中包含的path/to/docutils/writers/html4css1/
文件。您可以在此文件中包含任意HTML元素,并修改Docutils生成的HTML的布局。这些方法都不需要您修改Docuitls源代码,这始终是一个优势。
编辑:我认为无法使用Docuitls设置标记来设置包含文件。但是,如果您可以使用基于Docuitls但有大量扩展名的Sphinx,那么此软件包的设置rst_prolog
可以完全满足您的需求(请参阅this answer)。 rst_prolog
是:
一串reStructuredText,它将包含在每个读取的源文件的开头。
答案 1 :(得分:1)
我需要完全相同的东西:将一些全局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)
简而言之:
PLUGINS
中调整pelicanconf.py
)RST_GLOBAL_INCLUDES
pelicanconf.py
来定义要包含的RST文件列表(项目根目录的相对路径)
请注意,鹈鹕和docutils的设计都不允许这样做。既没有提供信号,在处理开始之前提供对源文件的原始内容的干净访问,也没有可能以“正常方式”拦截读取文件的框架(如子类化,更改硬编码配置等) 。
此插件将FileInput
的内部类RstReader
子类化,将RstReader.FileInput
的类引用设置为子类。 python文件对象也通过SourceWrapper
模拟。
然而,这种方法对我有用,并且在日常工作流程中并不繁琐。
我知道这个问题是从2012年开始的,但我认为这个答案对其他人来说仍然有用。