Skip to content

Commit

Permalink
Merge pull request #25 from elkirby/fenced-code-blocks-835
Browse files Browse the repository at this point in the history
Fenced code blocks 835
  • Loading branch information
jemerick authored Apr 20, 2021
2 parents 425332c + 637ac3f commit eebdc53
Show file tree
Hide file tree
Showing 12 changed files with 369 additions and 9 deletions.
1 change: 1 addition & 0 deletions Authors.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,4 @@ Contributors

* Dave MacNamara <[email protected]>
* Justin Michalicek <[email protected]>
* Erin Kirby <[email protected]>
2 changes: 1 addition & 1 deletion CONTRIBUTING.rst
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ Before you submit a pull request, check that it meets these guidelines:
2. If the pull request adds functionality, the docs should be updated. Put
your new functionality into a function with a docstring, and add the
feature to the list in README.rst.
3. The pull request should work for Python 2.7, 3.2, 3.3, 3.4 and 3.5, and for PyPy. Check
3. The pull request should work for Python 2.7, 3.4, 3.5, 3.6 and 3.7, and for PyPy. Check
https://travis-ci.org/livio/DocDown-Python/pull_requests
and make sure that the tests pass for all supported Python versions.

Expand Down
10 changes: 10 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@
History
=======

0.3.1 (2021-04-20)
------------------

* Place a hard cap below 3.0 on Markdown to address compatibility issues

0.3.0 (2021-04-19)
------------------

* Add Scoped Code Tabs Markdown Extension

0.2.7 (2019-11-20)
------------------

Expand Down
2 changes: 1 addition & 1 deletion docdown/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

__author__ = """Jason Emerick"""
__email__ = '[email protected]'
__version__ = '0.2.7'
__version__ = '0.3.1'
95 changes: 95 additions & 0 deletions docdown/scoped_code_tabs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# -*- coding: utf-8 -*-

"""
scoped_code_tabs
----------------------------------
docdown.scoped_code_tabs Markdown extension module
"""
import re

from markdown.preprocessors import Preprocessor
from markdown_fenced_code_tabs import CodeTabsExtension


class ScopedCodeTabsPreprocessor(Preprocessor):
RE_FENCE_START = r'^ *\|\~\s*$' # start line, e.g., ` |~ `
RE_FENCE_END = r'^\s*\~\|\s*$' # last non-blank line, e.g, '~|\n \n\n'

def __init__(self, md, code_tabs_preprocessor):
self.code_tabs_preprocessor = code_tabs_preprocessor
super(ScopedCodeTabsPreprocessor, self).__init__(md)

def run(self, lines):
new_lines = []
fenced_code_tab = []
starting_line = None
in_tab = False

for line in lines:
if re.search(self.RE_FENCE_START, line):
# Start block pattern, save line in case of no end fence
in_tab = True
starting_line = line
elif re.search(self.RE_FENCE_END, line):
# End of code block, run through fenced code tabs pre-processor and reset code tab list
new_lines += self.code_tabs_preprocessor.run(fenced_code_tab)
fenced_code_tab = []
in_tab = False
elif in_tab:
# Still in tab -- append to tab list
fenced_code_tab.append(line)
else:
# Not in a fenced code tab, and not starting/ending one -- pass as usual
new_lines.append(line)

# Non-terminated code tab block, append matching starting fence and remaining lines without processing
if fenced_code_tab:
new_lines += [starting_line] + fenced_code_tab
return new_lines


class ScopedCodeTabExtension(CodeTabsExtension):

def __init__(self, **kwargs):
"""
A Markdown extension that serves to scope where Fenced Code Tabs are rendered by way of |~ ... ~| fences.
Example:
## A set of code tabs in Python and Java
|~
```python
def main():
print("This would be passed through markdown_fenced_code_tabs")
```
```java
public static void main(String[] args) {
System.out.println("This would be passed through markdown_fenced_code_tabs");
}
```
~|
## A regular, non-tabbed code block in Bash
```bash
codeblockinfo() {
echo("This would NOT be passed through markdown_fenced_code tabs");
}
```
"""
super(ScopedCodeTabExtension, self).__init__(**kwargs)

def extendMarkdown(self, md, md_globals):
super(ScopedCodeTabExtension, self).extendMarkdown(md, md_globals)
md.registerExtension(self)

md.preprocessors.add('scoped_code_tabs',
ScopedCodeTabsPreprocessor(md,
code_tabs_preprocessor=md.preprocessors['fenced_code_block']),
">normalize_whitespace")
del md.preprocessors['fenced_code_block']


def makeExtension(*args, **kwargs):
return ScopedCodeTabExtension(*args, **kwargs)
8 changes: 8 additions & 0 deletions docs/docdown.rst
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,14 @@ docdown.platform_section module
:undoc-members:
:show-inheritance:

docdown.scoped_code_tabs module
-------------------------------

.. automodule:: docdown.scoped_code_tabs
:members:
:undoc-members:
:show-inheritance:

docdown.sequence module
-----------------------

Expand Down
109 changes: 109 additions & 0 deletions docs/extensions/scoped_code_tabs.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
######################
Scoped Code Tabs
######################

Scoped Code Tabs allows for the explicit annotation of when and where to tabulate a set of code blocks versus rendering them
separately.

A scoped code tab is delimited by an opening ``|~`` fence and closing ``~|`` fence. The code blocks within the fences
are defined as typical code blocks, using backticks, with the opening backtick fence specifying the code language contained
within the block.

The configuration for rendering the tabs is as directly defined by the `markdown_fenced_code_tabs`_ extension.


=============
Dependencies
=============
The ``docdown.scoped_code_tabs`` extension requires the third-party extension `markdown_fenced_code_tabs`_ in order to process
the tabulated fenced code blocks.

==============
Configuration
==============

single_block_as_tab
Whether a single code block should still be rendered as a code tab. Default: ``False``
active_class
The CSS class to apply to the active tab. Default: ``active``
template
Which template to use to render code tabs. One of: [``default``, ``bootstrap3``, ``bootstrap4``]. Default: ``default``
Please see the *-template.html files in the `markdown_fenced_code_tabs`_ extension.

=======
Usage
=======
In documents
-------------

.. code-block:: md
### Hello World Examples
|~
```bash
helloWorld() {
greeting=${1:-World}
echo(`Hello ${greeting}`)
}
```
~|
```python
def hello_world(greeting: str = "World") -> None:
print(f"Hello {greeting}")
```
Python
--------------

.. code-block:: python
config = {
'docdown.scoped_code_tabs': {
'single_block_as_tab': True,
'template': 'bootstrap4',
'active_class': 'tab-active'
}
}
text = """\
### Hello World Examples
|~
```bash
helloWorld() {
greeting=${1:-World}
echo(`Hello ${greeting}`)
}
```
~|
```python
def hello_world(greeting: str = "World") -> None:
print(f"Hello {greeting}")
```
"""
html = markdown.markdown(
text,
extensions=['docdown.scoped_code_tabs'],
extension_configs=config,
output_format='html5')
=======
Output
=======
Note the extra classes and divs for tabulation around the ``|~`` ``~|`` code block.

.. code-block:: html

<h3>Hello World Examples</h3>
<p> <div class=md-fenced-code-tabs id=tab-tab-group-0><ul class="nav nav-tabs"><li class=nav-item><a class="nav-link tab-active" href=#tab-group-0-0_bash-panel role=tab id=tab-group-0-0_bash-tab data-toggle=tab data-lang=bash aria-controls=tab-group-0-0_bash-panel aria-selected=true>Bash</a></li></ul><div class=tab-content><div id=tab-group-0-0_bash-panel class="tab-pane show tab-active" role=tabpanel aria-labelledby=tab-group-0-0_bash-tab><pre><code class=bash>helloWorld() {
greeting=${1:-World}
echo(`Hello ${greeting}`)
}
</code></pre></div></div></div></p>
<p><code>python
def hello_world(greeting: str = "World") -&gt; None:
print(f"Hello {greeting}")</code></p>

.. _`markdown_fenced_code_tabs`: https://github.com/yacir/markdown-fenced-code-tabs
5 changes: 3 additions & 2 deletions requirements_dev.txt
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
pip==9.0.1
bumpversion==0.5.3
wheel==0.29.0
watchdog==0.8.3
#watchdog==0.8.3
flake8==2.6.0
tox==2.5.0
coverage==4.1
Sphinx==1.4.8
twine==1.13.0

Markdown==2.6.6
Markdown<3.0.0
markdown-fenced-code-tabs==1.0.5
unicodecsv==0.14.1

# note_block templating
Expand Down
2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 0.2.7
current_version = 0.3.1
commit = True
tag = True

Expand Down
7 changes: 5 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@

requirements = [
# TODO: put package requirements here
'Markdown < 3.0.0',
'unicodecsv >= 0.14.1',
'markdown-fenced-code-tabs >= 1.0.5',
]

test_requirements = [
Expand All @@ -20,7 +22,7 @@

setup(
name='docdown',
version='0.2.7',
version='0.3.1',
description="DocDown is a Markdown extension for source code documentation.",
long_description=readme + '\n\n' + history,
author="Jason Emerick, Justin Michalicek",
Expand All @@ -42,9 +44,10 @@
"Programming Language :: Python :: 2",
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
],
test_suite='tests',
tests_require=test_requirements
Expand Down
4 changes: 2 additions & 2 deletions tests/test_platform_section_extension.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# -*- coding: utf-8 -*-

"""
test_note_blocks_extension
test_platform_section_extension
----------------------------------
Tests for `docdown.note_blocks` module.
Tests for `docdown.platform_section` module.
"""

from __future__ import absolute_import, print_function, unicode_literals
Expand Down
Loading

0 comments on commit eebdc53

Please sign in to comment.