mirror of
				https://github.com/encode/django-rest-framework.git
				synced 2025-11-04 09:57:55 +03:00 
			
		
		
		
	Docstrings highlighting with pygments (#5462)
* add 'docstrings-with-pygments' feature without packages checks and tests
* move syntax_highlight doc filter in compatibility module and define it conditionally
* typo fixed
* add test for optional code highlight ('pygments' and 'markdown' packages must be installed)
			
			
This commit is contained in:
		
							parent
							
								
									62ecbf2817
								
							
						
					
					
						commit
						063534ae50
					
				| 
						 | 
				
			
			@ -244,6 +244,7 @@ try:
 | 
			
		|||
        md = markdown.Markdown(
 | 
			
		||||
            extensions=extensions, extension_configs=extension_configs
 | 
			
		||||
        )
 | 
			
		||||
        md_filter_add_syntax_highlight(md)
 | 
			
		||||
        return md.convert(text)
 | 
			
		||||
except ImportError:
 | 
			
		||||
    apply_markdown = None
 | 
			
		||||
| 
						 | 
				
			
			@ -273,6 +274,38 @@ except ImportError:
 | 
			
		|||
    def pygments_css(style):
 | 
			
		||||
        return None
 | 
			
		||||
 | 
			
		||||
if markdown is not None and pygments is not None:
 | 
			
		||||
    # starting from this blogpost and modified to support current markdown extensions API
 | 
			
		||||
    # https://zerokspot.com/weblog/2008/06/18/syntax-highlighting-in-markdown-with-pygments/
 | 
			
		||||
 | 
			
		||||
    from markdown.preprocessors import Preprocessor
 | 
			
		||||
    import re
 | 
			
		||||
 | 
			
		||||
    class CodeBlockPreprocessor(Preprocessor):
 | 
			
		||||
        pattern = re.compile(
 | 
			
		||||
            r'^\s*@@ (.+?) @@\s*(.+?)^\s*@@', re.M|re.S)
 | 
			
		||||
 | 
			
		||||
        formatter = HtmlFormatter()
 | 
			
		||||
 | 
			
		||||
        def run(self, lines):
 | 
			
		||||
            def repl(m):
 | 
			
		||||
                try:
 | 
			
		||||
                    lexer = get_lexer_by_name(m.group(1))
 | 
			
		||||
                except (ValueError, NameError):
 | 
			
		||||
                    lexer = TextLexer()
 | 
			
		||||
                code = m.group(2).replace('\t','    ')
 | 
			
		||||
                code = pygments.highlight(code, lexer, self.formatter)
 | 
			
		||||
                code = code.replace('\n\n', '\n \n').replace('\n', '<br />').replace('\\@','@')
 | 
			
		||||
                return '\n\n%s\n\n' % code
 | 
			
		||||
            ret = self.pattern.sub(repl, "\n".join(lines))
 | 
			
		||||
            return ret.split("\n")
 | 
			
		||||
 | 
			
		||||
    def md_filter_add_syntax_highlight(md):
 | 
			
		||||
        md.preprocessors.add('highlight', CodeBlockPreprocessor(), "_begin")
 | 
			
		||||
        return True
 | 
			
		||||
else:
 | 
			
		||||
    def md_filter_add_syntax_highlight(md):
 | 
			
		||||
        return False
 | 
			
		||||
 | 
			
		||||
try:
 | 
			
		||||
    import pytz
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,11 +24,36 @@ another header
 | 
			
		|||
 | 
			
		||||
indented
 | 
			
		||||
 | 
			
		||||
# hash style header #"""
 | 
			
		||||
# hash style header #
 | 
			
		||||
 | 
			
		||||
@@ json @@
 | 
			
		||||
[{
 | 
			
		||||
    "alpha": 1,
 | 
			
		||||
    "beta: "this is a string"
 | 
			
		||||
}]
 | 
			
		||||
@@"""
 | 
			
		||||
 | 
			
		||||
# If markdown is installed we also test it's working
 | 
			
		||||
# (and that our wrapped forces '=' to h2 and '-' to h3)
 | 
			
		||||
 | 
			
		||||
MARKED_DOWN_HILITE = """
 | 
			
		||||
<div class="highlight"><pre><span></span><span \
 | 
			
		||||
class="p">[{</span><br />    <span class="nt">"alpha"</span><span\
 | 
			
		||||
 class="p">:</span> <span class="mi">1</span><span class="p">,</span><br />\
 | 
			
		||||
    <span class="nt">"beta: "</span><span class="err">this</span>\
 | 
			
		||||
 <span class="err">is</span> <span class="err">a</span> <span class="err">\
 | 
			
		||||
string"</span><br /><span class="p">}]</span><br /></pre></div>
 | 
			
		||||
 | 
			
		||||
<p><br /></p>"""
 | 
			
		||||
 | 
			
		||||
MARKED_DOWN_NOT_HILITE = """
 | 
			
		||||
<p>@@ json @@
 | 
			
		||||
[{
 | 
			
		||||
    "alpha": 1,
 | 
			
		||||
    "beta: "this is a string"
 | 
			
		||||
}]
 | 
			
		||||
@@</p>"""
 | 
			
		||||
 | 
			
		||||
# We support markdown < 2.1 and markdown >= 2.1
 | 
			
		||||
MARKED_DOWN_lt_21 = """<h2>an example docstring</h2>
 | 
			
		||||
<ul>
 | 
			
		||||
| 
						 | 
				
			
			@ -39,7 +64,7 @@ MARKED_DOWN_lt_21 = """<h2>an example docstring</h2>
 | 
			
		|||
<pre><code>code block
 | 
			
		||||
</code></pre>
 | 
			
		||||
<p>indented</p>
 | 
			
		||||
<h2 id="hash_style_header">hash style header</h2>"""
 | 
			
		||||
<h2 id="hash_style_header">hash style header</h2>%s"""
 | 
			
		||||
 | 
			
		||||
MARKED_DOWN_gte_21 = """<h2 id="an-example-docstring">an example docstring</h2>
 | 
			
		||||
<ul>
 | 
			
		||||
| 
						 | 
				
			
			@ -50,7 +75,7 @@ MARKED_DOWN_gte_21 = """<h2 id="an-example-docstring">an example docstring</h2>
 | 
			
		|||
<pre><code>code block
 | 
			
		||||
</code></pre>
 | 
			
		||||
<p>indented</p>
 | 
			
		||||
<h2 id="hash-style-header">hash style header</h2>"""
 | 
			
		||||
<h2 id="hash-style-header">hash style header</h2>%s"""
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestViewNamesAndDescriptions(TestCase):
 | 
			
		||||
| 
						 | 
				
			
			@ -78,7 +103,14 @@ class TestViewNamesAndDescriptions(TestCase):
 | 
			
		|||
 | 
			
		||||
            indented
 | 
			
		||||
 | 
			
		||||
            # hash style header #"""
 | 
			
		||||
            # hash style header #
 | 
			
		||||
 | 
			
		||||
            @@ json @@
 | 
			
		||||
            [{
 | 
			
		||||
                "alpha": 1,
 | 
			
		||||
                "beta: "this is a string"
 | 
			
		||||
            }]
 | 
			
		||||
            @@"""
 | 
			
		||||
 | 
			
		||||
        assert MockView().get_view_description() == DESCRIPTION
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -118,8 +150,16 @@ class TestViewNamesAndDescriptions(TestCase):
 | 
			
		|||
        Ensure markdown to HTML works as expected.
 | 
			
		||||
        """
 | 
			
		||||
        if apply_markdown:
 | 
			
		||||
            gte_21_match = apply_markdown(DESCRIPTION) == MARKED_DOWN_gte_21
 | 
			
		||||
            lt_21_match = apply_markdown(DESCRIPTION) == MARKED_DOWN_lt_21
 | 
			
		||||
            gte_21_match = (
 | 
			
		||||
                apply_markdown(DESCRIPTION) == (
 | 
			
		||||
                    MARKED_DOWN_gte_21 % MARKED_DOWN_HILITE) or
 | 
			
		||||
                apply_markdown(DESCRIPTION) == (
 | 
			
		||||
                    MARKED_DOWN_gte_21 % MARKED_DOWN_NOT_HILITE))
 | 
			
		||||
            lt_21_match = (
 | 
			
		||||
                apply_markdown(DESCRIPTION) == (
 | 
			
		||||
                    MARKED_DOWN_lt_21 % MARKED_DOWN_HILITE) or
 | 
			
		||||
                apply_markdown(DESCRIPTION) == (
 | 
			
		||||
                    MARKED_DOWN_lt_21 % MARKED_DOWN_NOT_HILITE))
 | 
			
		||||
            assert gte_21_match or lt_21_match
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user