From c0b1dc5d315624799ac1ba380eced9838e7f4bca Mon Sep 17 00:00:00 2001 From: Waylan Limberg Date: Thu, 8 Oct 2020 13:18:28 -0400 Subject: [PATCH] Ensure consistent handling of classes by fenced_code and codehilite (#1033) * All non-language classes should always be assigned to the pre tag. * The language identifying class should never be included with the general list of classes. Fixes #1032 --- docs/change_log/index.md | 4 +++ docs/extensions/fenced_code_blocks.md | 4 +-- markdown/extensions/fenced_code.py | 15 ++++---- .../extensions/test_fenced_code.py | 34 +++++++++---------- 4 files changed, 30 insertions(+), 27 deletions(-) diff --git a/docs/change_log/index.md b/docs/change_log/index.md index 40f017e5e..554864480 100644 --- a/docs/change_log/index.md +++ b/docs/change_log/index.md @@ -3,6 +3,10 @@ title: Change Log Python-Markdown Change Log ========================= +Under development: version 3.3.1 (a bug-fix release). + +* Ensure consistent class handling by `fenced_code` and `codehilite` (#1032). + Oct 6, 2020: version 3.3 ([Notes](release-3.3.md)). May 8, 2020: version 3.2.2 (a bug-fix release). diff --git a/docs/extensions/fenced_code_blocks.md b/docs/extensions/fenced_code_blocks.md index c495475d1..fc5c9ca2d 100644 --- a/docs/extensions/fenced_code_blocks.md +++ b/docs/extensions/fenced_code_blocks.md @@ -130,13 +130,13 @@ In addition to the language, additional classes may be defined by prefixing them ```` When defining multiple classes, only the first class will be used as the "language" for the code block. All others are -assigned to the `` tag unaltered. Additionally, the curly braces and dot are required for all classes, including +assigned to the `
` tag unaltered. Additionally, the curly braces and dot are required for all classes, including
 the language class if more than one class is defined.
 
 The above example will output the following HTML:
 
 ```html
-
<p>HTML Document</p>
+
<p>HTML Document</p>
 
``` diff --git a/markdown/extensions/fenced_code.py b/markdown/extensions/fenced_code.py index e3b3f1bb8..716b46772 100644 --- a/markdown/extensions/fenced_code.py +++ b/markdown/extensions/fenced_code.py @@ -88,11 +88,10 @@ def run(self, lines): if m.group('attrs'): id, classes, config = self.handle_attrs(get_attrs(m.group('attrs'))) if len(classes): - lang = classes[0] + lang = classes.pop(0) else: if m.group('lang'): lang = m.group('lang') - classes.append(lang) if m.group('hl_lines'): # Support hl_lines outside of attrs for backward-compatibility config['hl_lines'] = parse_hl_lines(m.group('hl_lines')) @@ -119,12 +118,11 @@ def run(self, lines): code = highliter.hilite() else: - id_attr = class_attr = kv_pairs = '' + id_attr = lang_attr = class_attr = kv_pairs = '' + if lang: + lang_attr = ' class="{}{}"'.format(self.config.get('lang_prefix', 'language-'), lang) if classes: - class_attr = ' class="{}{}"'.format( - self.config.get('lang_prefix', 'language-'), - ' '.join(classes) - ) + class_attr = ' class="{}"'.format(' '.join(classes)) if id: id_attr = ' id="{}"'.format(id) if self.use_attr_list and config and not config.get('use_pygments', False): @@ -134,9 +132,10 @@ def run(self, lines): kv_pairs = ' ' + ' '.join( '{k}="{v}"'.format(k=k, v=v) for k, v in config.items() if k != 'use_pygments' ) - code = '{code}
'.format( + code = '{code}
'.format( id=id_attr, cls=class_attr, + lang=lang_attr, kv=kv_pairs, code=self._escape(m.group('code')) ) diff --git a/tests/test_syntax/extensions/test_fenced_code.py b/tests/test_syntax/extensions/test_fenced_code.py index 8fa75f7ec..c86a7332e 100644 --- a/tests/test_syntax/extensions/test_fenced_code.py +++ b/tests/test_syntax/extensions/test_fenced_code.py @@ -168,7 +168,7 @@ def testFencedCodeWithHighlightLines(self): def testFencedLanguageAndHighlightLines(self): if self.has_pygments: expected = ( - '
'
+                '
'
                 'line 1\n'
                 'line 2\n'
                 'line 3\n'
@@ -177,7 +177,7 @@ def testFencedLanguageAndHighlightLines(self):
         else:
             expected = self.dedent(
                     '''
-                    
line 1
+                    
line 1
                     line 2
                     line 3
                     
@@ -224,7 +224,7 @@ def testFencedLanguageAndPygmentsDisabled(self): def testFencedLanguageDoubleEscape(self): if self.has_pygments: expected = ( - '
'
+                '
'
                 '<span'
                 '>This&amp;'
                 'That</span'
@@ -233,7 +233,7 @@ def testFencedLanguageDoubleEscape(self):
             )
         else:
             expected = (
-                '
'
+                '
'
                 '<span>This&amp;That</span>\n'
                 '
' ) @@ -256,7 +256,7 @@ def testFencedAmps(self): if self.has_pygments: expected = self.dedent( ''' -
&
+                
&
                 &amp;
                 &amp;amp;
                 
@@ -265,7 +265,7 @@ def testFencedAmps(self): else: expected = self.dedent( ''' -
&
+                
&
                 &amp;
                 &amp;amp;
                 
@@ -341,7 +341,7 @@ def testFencedMultipleClassesInAttr(self): ), self.dedent( ''' -
# Some python code
+                
# Some python code
                 
''' ), @@ -395,7 +395,7 @@ def testFencedIdAndLangAndClassInAttr(self): ), self.dedent( ''' -
# Some python code
+                
# Some python code
                 
''' ), @@ -441,7 +441,7 @@ def testFencedCodeWithHighlightLinesInAttr(self): def testFencedLanguageAndHighlightLinesInAttr(self): if self.has_pygments: expected = ( - '
'
+                '
'
                 'line 1\n'
                 'line 2\n'
                 'line 3\n'
@@ -450,7 +450,7 @@ def testFencedLanguageAndHighlightLinesInAttr(self):
         else:
             expected = self.dedent(
                     '''
-                    
line 1
+                    
line 1
                     line 2
                     line 3
                     
@@ -552,13 +552,13 @@ def testFencedLanguageAttrCssclass(self): if self.has_pygments: expected = self.dedent( ''' -
# Some python code
+                
# Some python code
                 
''' ) else: expected = ( - '
# Some python code\n'
+                '
# Some python code\n'
                 '
' ) self.assertMarkdownRenders( @@ -576,16 +576,16 @@ def testFencedLanguageAttrCssclass(self): def testFencedLanguageAttrLinenums(self): if self.has_pygments: expected = ( - '' + '
' '' - '
1
'
+                '
'
                 '# Some python code\n'
                 '
\n' '
' ) else: expected = ( - '
# Some python code\n'
+                '
# Some python code\n'
                 '
' ) self.assertMarkdownRenders( @@ -628,14 +628,14 @@ def testFencedLanguageAttrGuesslang(self): def testFencedLanguageAttrNoclasses(self): if self.has_pygments: expected = ( - '
' + '
' '
'
                 '# Some python code\n'
                 '
' ) else: expected = ( - '
# Some python code\n'
+                '
# Some python code\n'
                 '
' ) self.assertMarkdownRenders(