Sphinx inline code highlight

前端 未结 6 1607
暖寄归人
暖寄归人 2021-02-07 11:03

I use Sphinx to make a website that contains code samples. I\'m successful using the .. code-block directive to get syntax highlighting. But I can\'t get inline syn

相关标签:
6条回答
  • 2021-02-07 11:34

    OK I used this workaround: I generate a css file that contains both short and long names. I'm still interested in the "good" answer.

    #!/usr/bin/env python
    
    """Generate a css file thanks to pygments that will contain both short
    and long class names."""
    
    
    import subprocess
    import sys
    
    
    PYGMENTIZE = 'pygmentize'
    
    
    def parse_command_line():
        import argparse
        parser = argparse.ArgumentParser(description=__doc__)
        parser.add_argument('-s', '--style', default='colorful')
        parser.add_argument('-p', '--prefix', default='.highlight')
        return parser.parse_args()
    
    
    def pygmentize(style, prefix='.highlight'):
        cmd = '{0} -f html -S {1} -a {2}'.format(PYGMENTIZE, style, prefix)
        # This will fail if pygmentize does not exist.
        try:
            p = subprocess.Popen(cmd.split(), stdout=subprocess.PIPE)
        except OSError:
            print >> sys.stderr, '{0}: command not found'.format(PYGMENTIZE)
            exit(1)
    
        out, err = p.communicate()
        if p.returncode != 0:
            exit(p.returncode)
        return out
    
    
    def main():
        args = parse_command_line()
        style = args.style
        prefix = args.prefix
    
        # Print new css header.
        header = """\
    /* 
     * This is pygment css style {0} generated with
     *     {1}
     */""".format(style, ' '.join(sys.argv))
        print header
    
        # Parse pygmentize output.
        # Find long names based on comments.
        content = pygmentize(style, prefix)
        s = content.splitlines()
        out = ''
        for line in s:
            start = line.find("/* ") + 3
            end = line.find(" */")
            # if line has a comment
            if start != 2:
                comment = line[start:end]
                name = '.' + comment.lower()
                arg = line[line.find('{ '): start - 4]
                out += '%(prefix)s %(name)s %(arg)s\n' % vars()
    
        print content
        print out
    
    
    if __name__ == '__main__':
        main()
    
    0 讨论(0)
  • 2021-02-07 11:38

    Here's a better than previous workaround:

    Change default --syntax-highlight option of docuitls. In

    docutils/parsers/rst/__init__.py
    

    Find

             ('Token name set for parsing code with Pygments: one of '
              '"long", "short", or "none (no parsing)". Default is "short".',
              ['--syntax-highlight'],
              {'choices': ['long', 'short', 'none'],
               'default': 'long', 'metavar': '<format>'}),
    

    and chage the default to short:

               'default': 'short', 'metavar': '<format>'}),
    

    The method to highlight inline code in sphnix is to register a new role:

    .. role:: py(code)
       :language: py
       :class: highlight
    

    This construct is from docutils, not from sphinx. Then one can change the docutils's default, to get the desired output (short classes). A better solution would be to set the value during the init of the class in sphinx. But where that happens might not be easy to find.

    This solution is much better than the previous since it doesn't double the number of css rules to match to color the code.

    0 讨论(0)
  • 2021-02-07 11:43

    When a sphinx theme has static/pygments.css -- then the file is not overwritten. So I just keep the file which contains both short and long names (which I obtained using regexp in emacs):

    .highlight .hll { background-color: #ffffcc }
    /* .highlight  { background: #eeffcc; } */
    .highlight .c { color: #408090; font-style: italic } /* comment */
    .highlight .comment { color: #408090; font-style: italic }
    .highlight .err { border: 1px solid #ff0000 } /* error */
    .highlight .error { border: 1px solid #ff0000 }
    .highlight .k { color: #007020; font-weight: bold } /* keyword */
    .highlight .keyword { color: #007020; font-weight: bold }
    .highlight .o { color: #666666 } /* operator */
    .highlight .operator { color: #666666 }
    .highlight .cm { color: #408090; font-style: italic } /* comment.multiline */
    .highlight .comment.multiline { color: #408090; font-style: italic }
    .highlight .cp { color: #007020 } /* comment.preproc */
    .highlight .comment.preproc { color: #007020 }
    .highlight .c1 { color: #408090; font-style: italic } /* comment.single */
    .highlight .comment.single { color: #408090; font-style: italic }
    .highlight .cs { color: #408090; background-color: #fff0f0 } /* comment.special */
    .highlight .comment.special { color: #408090; background-color: #fff0f0 }
    .highlight .gd { color: #a00000 } /* generic.deleted */
    .highlight .generic.deleted { color: #a00000 }
    .highlight .ge { font-style: italic } /* generic.emph */
    .highlight .generic.emph { font-style: italic }
    .highlight .gr { color: #ff0000 } /* generic.error */
    .highlight .generic.error { color: #ff0000 }
    .highlight .gh { color: #000080; font-weight: bold } /* generic.heading */
    .highlight .generic.heading { color: #000080; font-weight: bold }
    .highlight .gi { color: #00a000 } /* generic.inserted */
    .highlight .generic.inserted { color: #00a000 }
    .highlight .go { color: #333333 } /* generic.output */
    .highlight .generic.output { color: #333333 }
    .highlight .gp { color: #c65d09; font-weight: bold } /* generic.prompt */
    .highlight .generic.prompt { color: #c65d09; font-weight: bold }
    .highlight .gs { font-weight: bold } /* generic.strong */
    .highlight .generic.strong { font-weight: bold }
    .highlight .gu { color: #800080; font-weight: bold } /* generic.subheading */
    .highlight .generic.subheading { color: #800080; font-weight: bold }
    .highlight .gt { color: #0044dd } /* generic.traceback */
    .highlight .generic.traceback { color: #0044dd }
    .highlight .kc { color: #007020; font-weight: bold } /* keyword.constant */
    .highlight .keyword.constant { color: #007020; font-weight: bold }
    .highlight .kd { color: #007020; font-weight: bold } /* keyword.declaration */
    .highlight .keyword.declaration { color: #007020; font-weight: bold }
    .highlight .kn { color: #007020; font-weight: bold } /* keyword.namespace */
    .highlight .keyword.namespace { color: #007020; font-weight: bold }
    .highlight .kp { color: #007020 } /* keyword.pseudo */
    .highlight .keyword.pseudo { color: #007020 }
    .highlight .kr { color: #007020; font-weight: bold } /* keyword.reserved */
    .highlight .keyword.reserved { color: #007020; font-weight: bold }
    .highlight .kt { color: #902000 } /* keyword.type */
    .highlight .keyword.type { color: #902000 }
    .highlight .m { color: #208050 } /* literal.number */
    .highlight .literal.number { color: #208050 }
    .highlight .s { color: #4070a0 } /* literal.string */
    .highlight .literal.string { color: #4070a0 }
    .highlight .na { color: #4070a0 } /* name.attribute */
    .highlight .name.attribute { color: #4070a0 }
    .highlight .nb { color: #007020 } /* name.builtin */
    .highlight .name.builtin { color: #007020 }
    .highlight .nc { color: #0e84b5; font-weight: bold } /* name.class */
    .highlight .name.class { color: #0e84b5; font-weight: bold }
    .highlight .no { color: #60add5 } /* name.constant */
    .highlight .name.constant { color: #60add5 }
    .highlight .nd { color: #555555; font-weight: bold } /* name.decorator */
    .highlight .name.decorator { color: #555555; font-weight: bold }
    .highlight .ni { color: #d55537; font-weight: bold } /* name.entity */
    .highlight .name.entity { color: #d55537; font-weight: bold }
    .highlight .ne { color: #007020 } /* name.exception */
    .highlight .name.exception { color: #007020 }
    .highlight .nf { color: #06287e } /* name.function */
    .highlight .name.function { color: #06287e }
    .highlight .nl { color: #002070; font-weight: bold } /* name.label */
    .highlight .name.label { color: #002070; font-weight: bold }
    .highlight .nn { color: #0e84b5; font-weight: bold } /* name.namespace */
    .highlight .name.namespace { color: #0e84b5; font-weight: bold }
    .highlight .nt { color: #062873; font-weight: bold } /* name.tag */
    .highlight .name.tag { color: #062873; font-weight: bold }
    .highlight .nv { color: #bb60d5 } /* name.variable */
    .highlight .name.variable { color: #bb60d5 }
    .highlight .ow { color: #007020; font-weight: bold } /* operator.word */
    .highlight .operator.word { color: #007020; font-weight: bold }
    .highlight .w { color: #bbbbbb } /* text.whitespace */
    .highlight .text.whitespace { color: #bbbbbb }
    .highlight .mf { color: #208050 } /* literal.number.float */
    .highlight .literal.number.float { color: #208050 }
    .highlight .mh { color: #208050 } /* literal.number.hex */
    .highlight .literal.number.hex { color: #208050 }
    .highlight .mi { color: #208050 } /* literal.number.integer */
    .highlight .literal.number.integer { color: #208050 }
    .highlight .mo { color: #208050 } /* literal.number.oct */
    .highlight .literal.number.oct { color: #208050 }
    .highlight .sb { color: #4070a0 } /* literal.string.backtick */
    .highlight .literal.string.backtick { color: #4070a0 }
    .highlight .sc { color: #4070a0 } /* literal.string.char */
    .highlight .literal.string.char { color: #4070a0 }
    .highlight .sd { color: #4070a0; font-style: italic } /* literal.string.doc */
    .highlight .literal.string.doc { color: #4070a0; font-style: italic }
    .highlight .s2 { color: #4070a0 } /* literal.string.double */
    .highlight .literal.string.double { color: #4070a0 }
    .highlight .se { color: #4070a0; font-weight: bold } /* literal.string.escape */
    .highlight .literal.string.escape { color: #4070a0; font-weight: bold }
    .highlight .sh { color: #4070a0 } /* literal.string.heredoc */
    .highlight .literal.string.heredoc { color: #4070a0 }
    .highlight .si { color: #70a0d0; font-style: italic } /* literal.string.interpol */
    .highlight .literal.string.interpol { color: #70a0d0; font-style: italic }
    .highlight .sx { color: #c65d09 } /* literal.string.other */
    .highlight .literal.string.other { color: #c65d09 }
    .highlight .sr { color: #235388 } /* literal.string.regex */
    .highlight .literal.string.regex { color: #235388 }
    .highlight .s1 { color: #4070a0 } /* literal.string.single */
    .highlight .literal.string.single { color: #4070a0 }
    .highlight .ss { color: #517918 } /* literal.string.symbol */
    .highlight .literal.string.symbol { color: #517918 }
    .highlight .bp { color: #007020 } /* name.builtin.pseudo */
    .highlight .name.builtin.pseudo { color: #007020 }
    .highlight .vc { color: #bb60d5 } /* name.variable.class */
    .highlight .name.variable.class { color: #bb60d5 }
    .highlight .vg { color: #bb60d5 } /* name.variable.global */
    .highlight .name.variable.global { color: #bb60d5 }
    .highlight .vi { color: #bb60d5 } /* name.variable.instance */
    .highlight .name.variable.instance { color: #bb60d5 }
    .highlight .il { color: #208050 } /* literal.number.integer.long */
    .highlight .literal.number.integer.long { color: #208050 }
    

    I run into another issue -- I'm using bootstrap theme, and it defines label too...

    0 讨论(0)
  • 2021-02-07 11:44

    syntax_highlight is an ordinary docutils setting, which can be set in docutils.conf. This file is respected by Sphinx too, if placed in the Sphinx's configuration directory (where conf.py resides):

    [restructuredtext parser]
    syntax_highlight = short
    

    This is much better than patching docutils or sphinx code or creating a long name CSS file.

    0 讨论(0)
  • 2021-02-07 11:52

    Found a better (sphinx-only) solution: in sphinx/builders/html.py find a line

    from docutils.core import Publisher
    

    and change it to:

    from docutils.core import Publisher
    def process_programmatic_settings(self, settings_spec,
                                      settings_overrides,
                                      config_section):
        if self.settings is None:
            defaults = (settings_overrides or {}).copy()
            # Propagate exceptions by default when used programmatically:
            defaults.setdefault('traceback', True)
            defaults.setdefault('syntax_highlight', 'short') # ADDED THIS LINE
            self.get_settings(settings_spec=settings_spec,
                              config_section=config_section,
                              **defaults)
    Publisher.process_programmatic_settings = process_programmatic_settings
    

    This solution is better then previous ones: since it doesn't double the amount of css rules, and doesn't modify docutils.

    Still, ideal solution would only change conf.py. So there's a plenty space for improvement.

    0 讨论(0)
  • 2021-02-07 11:54

    This can be fixed by adding 'sphinxcontrib.inlinesyntaxhighlight' extension in conf.py:

    extensions = [ 'sphinxcontrib.inlinesyntaxhighlight' ]
    
    # use language set by highlight directive if no language is set by role
    inline_highlight_respect_highlight = False
    
    # use language set by highlight directive if no role is set
    inline_highlight_literals = False
    

    Extension documentation

    The extension is available here and on PyPi.

    0 讨论(0)
提交回复
热议问题