如何在reST / Sphinx中记录字符串中的单个空格字符?

时间:2015-07-08 21:53:50

标签: python-sphinx restructuredtext docutils

我在一个边缘的情况下迷路了。我正在将一些旧的纯文本文档转换为reST / Sphinx格式,目的是从那里输出几种格式(包括HTML和文本)。一些记录的函数用于处理位串,其中一个常见的例子是如下句子:Starting character is the blank " " which has the value 0.

我尝试通过以下方式将其写为内联文字:Starting character is the blank `` `` which has the value 0.Starting character is the blank :literal:` ` which has the value 0.但是这些最终工作方式存在一些问题:

  1. 将语法对象直接复制到文字内部的空格中,并且它不会被识别。
  2. 以上内容可以修复" - 在HTML()和明文(" ")输出中看起来正确 - 文字中的一个不间断的空格字符,但从技术上讲,这是我们的情况,如果用户复制了这个字符,他们就不会复制他们期望的内容。
  3. 空格可以用常规引号括起来,这样可以正确识别文字,虽然HTML中的输出可能很好(" "),但在明文中它最终被双引号{{1 }}。
  4. 在上面的2/3中,如果文字落在包装边界上,明文写作者(使用"" "")将很乐意在文字中包裹并修剪空间,因为它在一开始/结束。
  5. 我觉得我错过了什么;是否有一个很好的方法来处理这个?

2 个答案:

答案 0 :(得分:4)

尝试使用unicode character codes。如果我理解你的问题,这应该有效。

EVENT-header
apple
orange
peach
blueberry

EVENT-header
bike
car
blueberry

EVENT-header
reddit
hacker news
stack overflow
slashdot?
voat

您应该看到:

这是一个“”和一个不间断的空格()

答案 1 :(得分:1)

我希望摆脱这个而不需要自定义代码来处理它,但是,唉,我还没有办法这样做。在我接受这个答案之前,我会再等几天,以防有人有更好的想法。下面的代码不完整,我也不确定它是“完成”(将在我们的审核过程中确切地说明它应该是什么样子),但基础知识是完整的。

该方法有两个主要组成部分:

  1. 引入一个char角色,该角色期望一个字符的unicode名称作为其参数,并在将该字符本身包装在内联文字节点中时生成该字符的内联描述。
  2. 修改Sphinx使用的文本包装器,以便它不会在空间中断。
  3. 以下是代码:

    class TextWrapperDeux(TextWrapper):
        _wordsep_re = re.compile(
        r'((?<!`)\s+(?!`)|'                       # whitespace not between backticks
        r'(?<=\s)(?::[a-z-]+:)`\S+|'              # interpreted text start
        r'[^\s\w]*\w+[a-zA-Z]-(?=\w+[a-zA-Z])|'   # hyphenated words
        r'(?<=[\w\!\"\'\&\.\,\?])-{2,}(?=\w))')   # em-dash
    
        @property
        def wordsep_re(self):
            return self._wordsep_re
    
    def char_role(name, rawtext, text, lineno, inliner, options={}, content=[]):
        """Describe a character given by unicode name.
    
        e.g., :char:`SPACE` -> "char:` `(U+00020 SPACE)"
        """
        try:
            character = nodes.unicodedata.lookup(text)
        except KeyError:
            msg = inliner.reporter.error(
                ':char: argument %s must be valid unicode name at line %d' % (text, lineno))
            prb = inliner.problematic(rawtext, rawtext, msg)
            return [prb], [msg]
        app = inliner.document.settings.env.app
        describe_char = "(U+%05X %s)" % (ord(character), text)
        char = nodes.inline("char:", "char:", nodes.literal(character, character))
        char += nodes.inline(describe_char, describe_char)
        return [char], []
    
    def setup(app):
        app.add_role('char', char_role)
    

    上面的代码缺少一些粘合剂来实际强制使用新的TextWrapper,导入等。当完整版本结束时,我可能会尝试找到一种有意义的方式来重新发布它;如果是的话我会把它链接到这里。

    标记:Starting character is the :char:`SPACE` which has the value 0.

    它会产生如下明文输出:Starting character is the char:` `(U+00020 SPACE) which has the value 0.

    HTML输出如:Starting character is the <span>char:<code class="docutils literal"> </code><span>(U+00020 SPACE)</span></span> which has the value 0.

    HTML输出最终看起来大致如下:起始字符是char:(U + 00020 SPACE),其值为0.