From b049bf5ea060712a64d80b5128f74e8fa2d27d3d Mon Sep 17 00:00:00 2001 From: gd Date: Sat, 27 Mar 2021 00:00:58 +0300 Subject: [PATCH] init --- .gitignore | 7 ++++ LICENSE | 24 ++++++++++++++ README.md | 83 ++++++++++++++++++++++++++++++++++++++++++++++ markdown_alerts.py | 79 +++++++++++++++++++++++++++++++++++++++++++ setup.py | 23 +++++++++++++ 5 files changed, 216 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 markdown_alerts.py create mode 100644 setup.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e4cf7cb --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +__pycache__/ +*.egg-info/ +build/ +dist/ +*.pyc +*.swp +*~ diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..00d2e13 --- /dev/null +++ b/LICENSE @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..d460894 --- /dev/null +++ b/README.md @@ -0,0 +1,83 @@ +# markdown-alerts + +Python-Markdown Admonition alternative extension with a shortened syntax. Depends [Python-Markdown](https://pypi.org/project/Markdown/). + +This extension supports one-line and multi-line text. The end of the remark block is an empty line. + +Example: + +``` +:::info This is an one-line admonition! + +:::info This is a +multi-line +admonition! + +:::info +It works too! + +This paragraph is not an admonition's part. +``` + +There can be an arbitrary number of spaces between the admonition start character `:::` and the admonition type designation. + +Supported admonition types: + +``` +:::info +:::note +:::tip +:::success +:::warning +:::danger +``` + +## Installation and usage + +Installation: + +``` +pip install markdown-alerts +``` + +Usage: + +```python +from markdown import Markdown + +html = Markdown(extensions=['markdown_alerts']) +``` + +## Configuration + +By default, the extension installs the following CSS classes for div blocks. For example for `:::note`: + +```html +
+

This is note!

+
+``` + +You can override these classes by adding your own configuration. Example for **Bootstrap 5**: + +```python +ext_configs = { + 'markdown_alerts': { + 'info': 'alert alert-info', + 'note': 'alert alert-primary', + 'tip': 'alert alert-success', + 'success': 'alert alert-success', + 'warning': 'alert alert-warning', + 'danger': 'alert alert-danger' + } +} + +html = Markdown( + extensions=['markdown_alerts'], + extension_configs=ext_configs + ) +``` + +## License + +This software is provided under The Unlicense. See [LICENSE](LICENSE) for details. \ No newline at end of file diff --git a/markdown_alerts.py b/markdown_alerts.py new file mode 100644 index 0000000..482970f --- /dev/null +++ b/markdown_alerts.py @@ -0,0 +1,79 @@ +"""Python-Markdown Admonition alternative extension +with a shortened syntax. +""" + +__version__ = '0.1' + +import re +import xml.etree.ElementTree as etree + +from markdown.extensions import Extension +from markdown.blockprocessors import BlockProcessor + + +# Patterns +alerts = { + 'info': r'::: *info', + 'note': r'::: *note', + 'tip': r'::: *tip', + 'success': r'::: *success', + 'warning': r'::: *warning', + 'danger': r'::: *danger' +} + +default_config = { + 'info' : ['alert info', 'CSS class for Info block.'], + 'note' : ['alert note', 'CSS class for Note block.'], + 'tip' : ['alert tip', 'CSS class for Tip block.'], + 'success' : ['alert success', 'CSS class for Success block.'], + 'warning' : ['alert warning', 'CSS class for Warning block.'], + 'danger' : ['alert danger', 'CSS class for Danger block.'], +} + +class AlertsBlockProcessor(BlockProcessor): + + def __init__(self, parser, alert, alert_css_class): + self.parser = parser + self.tab_length = parser.md.tab_length + self.alert = alert + self.alert_css_class = alert_css_class + + def test(self, parent, block): + return re.match(alerts[self.alert], block) + + def run(self, parent, blocks): + original_block = blocks[0] + blocks[0] = re.sub(alerts[self.alert], '', blocks[0]) + + for block_num, block in enumerate(blocks): + if re.search(r' *\n?$', block): + e = etree.SubElement(parent, 'div') + e.set('class', self.alert_css_class) + self.parser.parseBlocks(e, blocks[0:block_num + 1]) + for i in range(0, block_num + 1): + blocks.pop(0) + return True + blocks[0] = original_block + return False + +class AlertsExtension(Extension): + + def __init__(self, **kwargs): + self.config = default_config + super(AlertsExtension, self).__init__(**kwargs) + + def extendMarkdown(self, md): + priority = 105 + for alert in alerts.keys(): + priority += 10 + md.parser.blockprocessors.register( + AlertsBlockProcessor(md.parser, alert, self.getConfig(alert)), + alert + '-alert', + priority + ) + +def makeExtension(**kwargs): + return AlertsExtension(**kwargs) + +if __name__ == '__main__': + pass \ No newline at end of file diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..3912ed1 --- /dev/null +++ b/setup.py @@ -0,0 +1,23 @@ +from setuptools import setup + + +with open('README.md', 'r') as description: + long_description = description.read() + +setup( + name='markdown-alerts', + version='0.1', + author='gd', + description='Python-Markdown Admonition alternative.', + long_description=long_description, + long_description_content_type='text/markdown', + url='https://gitea.gch.icu/gd/markdown-alerts/', + classifiers=[ + "Programming Language :: Python :: 3.9", + "License :: OSI Approved :: The Unlicense (Unlicense)", + "Operating System :: OS Independent", + ], + python_requires='>=3.6', + py_modules=['markdown_alerts'], + install_requires = ['markdown>=3.0'], +)