繁体   English   中英

全局包括重组文本

[英]Global include in restructured text

我正在为我的博客/网站使用reStructuredText,我想添加一个全局包含文件。 我有权访问并很乐意更改我用于生成html输出的设置文件,我无法弄清楚以下两者的语法:

  1. 将默认包含文件添加到解析器
  2. 使用python中的docutils在python中定义指令/内联角色等

我尝试阅读源代码和文档,发现它有点难以理解。 我希望我只是错过了一些非常明显的东西,但是我想做类似下面的事情(第一部分就是已经存在的东西 - 你可以在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)

用法简述:

  • 从上面的代码创建一个插件(最好从GitHub克隆存储库
  • 导入插件(在pelicanconf.py调整PLUGINS
  • 通过在RST_GLOBAL_INCLUDES中设置变量RST_GLOBAL_INCLUDESpelicanconf.py要包含的RST文件列表(项目根目录的相对路径)

请注意,鹈鹕和docutils都不是为了这个而设计的。 在处理开始之前,既没有提供信号提供对源文件的原始内容的干净访问,也没有可能以“正常方式”拦截读取文件的框架(如子类化,更改硬编码配置等) 。 此插件对RstReader的内部类FileInput进行子类化, RstReader 的类引用 RstReader.FileInput为子类。 还通过SourceWrapper模拟python文件对象。 然而,这种方法对我有用,并且在日常工作流程中并不麻烦。

我知道这个问题是从2012年开始的,但我认为这个答案对其他人来说仍然有用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM