summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md48
-rw-r--r--pyproject.toml3
-rw-r--r--requirements_dev.txt1
-rw-r--r--setup.cfg24
-rw-r--r--src/pymdvar/__init__.py9
-rw-r--r--src/pymdvar/pymdvar.py24
-rw-r--r--tests/conftest.py14
-rw-r--r--tests/test_pymdvar.py61
8 files changed, 153 insertions, 31 deletions
diff --git a/README.md b/README.md
index e844e38..dcc978b 100644
--- a/README.md
+++ b/README.md
@@ -1,2 +1,46 @@
-# pymdvar
-Python's Markdown extension to insert variables
+# pymdvar - Python-Markdown Variable extension
+
+Simple extension meant to be used to convert variables to their corresponding values. Works with environment variables too.
+
+It uses the `${variable}` syntax. For example, given `variable=value`, the following text:
+
+```md
+Foo ${variable} bar
+```
+
+Becomes:
+
+```html
+<p>Foo value bar</p>
+```
+
+## Install
+
+`pymdvar` can be installed via `pip`:
+
+```sh
+python -m pip install pymdvar
+```
+
+## Usage
+
+The basic usage requires a dictionary with the variables to be passed to the `VariableExtension`:
+
+```py
+>>> import markdown
+>>> from pymdvar import VariableExtension
+>>> markdown.markdown('foo *${test}* bar', extensions=[VariableExtension(variables={'test': 'value'})])
+'<p>foo <em>value</em> bar</p>'
+```
+
+if `enable_env=True` is passed, then it will read environment variables, too. Variables in `variables` take preference.
+
+Only `a-z`, `A-Z`, `_` and `0-9` characters are accepted.
+
+Passing the extension as a string is supported:
+
+```py
+>>> import markdown
+>>> markdown.markdown('foo *${test}* bar', extensions=['pymdvar'], extension_configs={'pymdvar': {'variables': {'test': 'value'}}})
+'<p>foo <em>value</em> bar</p>'
+``` \ No newline at end of file
diff --git a/pyproject.toml b/pyproject.toml
index dcaca35..7744d62 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -7,6 +7,9 @@ addopts = "--cov-report term-missing --cov=pymdvar"
testpaths = [
"tests",
]
+env = [
+ "PYMDVAR_TEST_1=1"
+]
[tool.mypy]
mypy_path = "src"
diff --git a/requirements_dev.txt b/requirements_dev.txt
index 9979866..87baa83 100644
--- a/requirements_dev.txt
+++ b/requirements_dev.txt
@@ -1,5 +1,6 @@
pytest>=7.2.1
pytest-cov>=4.0.0
+pytest-env>=0.8.1
mypy>=1.0.0
flake8>=6.0.0
types-Markdown>=3.4.2.4 \ No newline at end of file
diff --git a/setup.cfg b/setup.cfg
index 13f4adc..24c970c 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -2,19 +2,35 @@
name = pymdvar
author = David Luevano Alvarado
author_email = david@luevano.xyz
-summary = Python-Markdown extension to insert variables
+summary = Python-Markdown extension for key-value pair conversion
description_file = README.md
license = GPLv3
home_page = https://github.com/luevano/pymdvar
classifiers =
- Programming Language :: Python :: 3
License :: OSI Approved :: GNU General Public License v3 (GPLv3)
- Operating System :: Unix
- Topic :: Text Processing :: Markup :: HTML
+ Operating System :: OS Independent,
+ Programming Language :: Python,
+ Programming Language :: Python :: 3,
+ Programming Language :: Python :: 3.7,
+ Programming Language :: Python :: 3.8,
+ Programming Language :: Python :: 3.9,
+ Programming Language :: Python :: 3.10,
+ Programming Language :: Python :: 3.11,
+ Programming Language :: Python :: 3 :: Only,
+ Topic :: Communications :: Email :: Filters,
+ Topic :: Internet :: WWW/HTTP :: Dynamic Content :: CGI Tools/Libraries,
+ Topic :: Internet :: WWW/HTTP :: Site Management,
+ Topic :: Software Development :: Documentation,
+ Topic :: Software Development :: Libraries :: Python Modules,
+ Topic :: Text Processing :: Filters,
+ Topic :: Text Processing :: Markup :: HTML,
Topic :: Text Processing :: Markup :: Markdown
keywords =
python
+ extension
+ plugin
markdown
+ website
[files]
packages =
diff --git a/src/pymdvar/__init__.py b/src/pymdvar/__init__.py
index b64a3b6..d8d4d4e 100644
--- a/src/pymdvar/__init__.py
+++ b/src/pymdvar/__init__.py
@@ -1,3 +1,10 @@
+from typing import Any
from .pymdvar import VariableExtension
-__all__ = ['VariableExtension'] \ No newline at end of file
+__all__ = ['VariableExtension']
+
+
+# this should be in pymdvar.py, but since there is only one extension,
+# it is fine in here
+def makeExtension(*args: Any, **kwargs: Any):
+ return VariableExtension(*args, **kwargs)
diff --git a/src/pymdvar/pymdvar.py b/src/pymdvar/pymdvar.py
index d81f785..2dcdf96 100644
--- a/src/pymdvar/pymdvar.py
+++ b/src/pymdvar/pymdvar.py
@@ -1,4 +1,4 @@
-from os import getenv
+import os
from re import Match
from typing import Any
from xml.etree.ElementTree import Element
@@ -6,7 +6,7 @@ from markdown import Markdown
from markdown.extensions import Extension
from markdown.inlinepatterns import Pattern
-VAR_RE: str = r'(\$\{)([a-zA-Z_]*)(\})'
+VAR_RE: str = r'(\$\{)([a-zA-Z_0-9]*)(\})'
class VarPattern(Pattern):
@@ -22,14 +22,12 @@ class VarPattern(Pattern):
def handleMatch(self, m: Match[str]) -> str | Element | None:
# for some reason the group is offest by 1
var: str | Any = m.group(3)
- value: str = ''
-
if var in self.vars:
- value = self.vars[var]
- else:
- if self.enable_env:
- value = getenv(var, '')
- return value
+ return self.vars[var]
+ if self.enable_env:
+ if var in os.environ:
+ return os.environ[var]
+ return ''
class VariableExtension(Extension):
@@ -41,11 +39,7 @@ class VariableExtension(Extension):
super().__init__(**kwargs)
def extendMarkdown(self, md: Markdown) -> None:
- vars: dict[str, str] | Any = self.getConfig('variables', dict())
- enable_env: bool = self.getConfig('enable_env', False)
+ vars: dict[str, str] | Any = self.getConfig('variables')
+ enable_env: bool = self.getConfig('enable_env')
var_pattern: VarPattern = VarPattern(VAR_RE, vars, enable_env)
md.inlinePatterns.register(var_pattern, 'variable', 175)
-
-
-def makeExtension(*args: Any, **kwargs: Any):
- return VariableExtension(*args, **kwargs)
diff --git a/tests/conftest.py b/tests/conftest.py
new file mode 100644
index 0000000..df33848
--- /dev/null
+++ b/tests/conftest.py
@@ -0,0 +1,14 @@
+import pytest
+
+
+@pytest.fixture
+def single_var_dict():
+ return {'test': 'value'}
+
+
+@pytest.fixture
+def multi_var_dict():
+ return {'ext': 'jpg',
+ 'test': 'value',
+ 'TEST': 'VALUE',
+ 'SOMETHING_ELSE': 'something_else'}
diff --git a/tests/test_pymdvar.py b/tests/test_pymdvar.py
index 91a97d0..a4c4439 100644
--- a/tests/test_pymdvar.py
+++ b/tests/test_pymdvar.py
@@ -1,3 +1,4 @@
+import os
import pytest
from markdown import markdown
from pymdvar import VariableExtension
@@ -5,31 +6,73 @@ from pymdvar import VariableExtension
def test_empty_input():
in_str: str = ''
+ exp_str: str = markdown(in_str)
out_str: str = markdown(in_str, extensions=[VariableExtension()])
- assert in_str == out_str
+ assert out_str == exp_str
@pytest.mark.parametrize('in_str, exp_str', [
('foo bar', '<p>foo bar</p>'),
('foo *test* bar', '<p>foo <em>test</em> bar</p>'),
- ('foo **test** bar', '<p>foo <strong>test</strong> bar</p>'),
+ ('foo *PYMDVAR_TEST_1* bar', '<p>foo <em>PYMDVAR_TEST_1</em> bar</p>'),
('foo $test bar', '<p>foo $test bar</p>'),
- ('foo *${test* bar', '<p>foo <em>${test</em> bar</p>'),
('foo **$test}** bar', '<p>foo <strong>$test}</strong> bar</p>'),
+ ('foo **$PYMDVAR_TEST_2}** bar', '<p>foo <strong>$PYMDVAR_TEST_2}</strong> bar</p>'),
+ ('foo [link](${test/a.html) bar', '<p>foo <a href="${test/a.html">link</a> bar</p>'),
+ ('foo ![image]($test}/a.jpg) bar', '<p>foo <img alt="image" src="$test}/a.jpg" /> bar</p>')
+])
+def test_no_replacements_config(in_str: str, exp_str: str, single_var_dict: dict[str, str]):
+ out_str: str = markdown(in_str, extensions=[VariableExtension(variables=single_var_dict, enable_env=True)])
+ assert out_str == exp_str
+
+
+@pytest.mark.parametrize('in_str, exp_str', [
+ ('foo *${test}* bar', '<p>foo <em></em> bar</p>'),
+ ('foo *${PYMDVAR_TEST_1}* bar', '<p>foo <em></em> bar</p>'),
+ ('foo [link](${test}/a.html) bar', '<p>foo <a href="/a.html">link</a> bar</p>'),
])
-def test_non_replacements(in_str, exp_str):
+def test_replacements_no_config(in_str: str, exp_str: str):
out_str: str = markdown(in_str, extensions=[VariableExtension()])
assert out_str == exp_str
@pytest.mark.parametrize('in_str, exp_str', [
- ('foo ${test} bar', '<p>foo value bar</p>'),
('foo *${test}* bar', '<p>foo <em>value</em> bar</p>'),
- ('foo **${test}** bar', '<p>foo <strong>value</strong> bar</p>'),
+ ('foo *${PYMDVAR_TEST_1}* bar', '<p>foo <em>1</em> bar</p>'),
+ ('foo ${value} bar', '<p>foo bar</p>'),
+ ('foo **${PYMDVAR_TEST_2}** bar', '<p>foo <strong></strong> bar</p>'),
('foo [link](${test}/a.html) bar', '<p>foo <a href="value/a.html">link</a> bar</p>'),
- ('foo ![image](${test}/a.jpg) bar', '<p>foo <img alt="image" src="value/a.jpg" /> bar</p>'),
+ ('foo ![image](${PYMDVAR_TEST_1}/a.jpg) bar', '<p>foo <img alt="image" src="1/a.jpg" /> bar</p>'),
+ ('foo [link](${PYMDVAR_TEST_2}/a.html) bar', '<p>foo <a href="/a.html">link</a> bar</p>')
])
-def test_simple_replacements(in_str, exp_str):
- out_str: str = markdown(in_str, extensions=[VariableExtension(variables={'test':'value'})])
+def test_simple_replacements(in_str: str, exp_str: str, single_var_dict: dict[str, str]):
+ out_str: str = markdown(in_str, extensions=[VariableExtension(variables=single_var_dict, enable_env=True)])
assert out_str == exp_str
+
+@pytest.mark.parametrize('in_str, exp_str', [
+ ('foo *${test}* bar', '<p>foo <em>value</em> bar</p>'),
+ ('foo *${TEST}* bar', '<p>foo <em>VALUE</em> bar</p>'),
+ ('foo **${SOMETHING_ELSE}** bar', '<p>foo <strong>something_else</strong> bar</p>')
+])
+def test_multivar_replacements(in_str: str, exp_str: str, multi_var_dict: dict[str, str]):
+ out_str: str = markdown(in_str, extensions=[VariableExtension(variables=multi_var_dict)])
+ assert out_str == exp_str
+
+
+@pytest.mark.parametrize('in_str, exp_str', [
+ ('foo *${test}* and **${TEST}** bar', '<p>foo <em>value</em> and <strong>VALUE</strong> bar</p>'),
+ ('foo ![image](${PYMDVAR_TEST_1}/a.${ext}) bar', '<p>foo <img alt="image" src="/a.jpg" /> bar</p>')
+])
+def test_text_multivar_replacements(in_str: str, exp_str: str, multi_var_dict: dict[str, str]):
+ out_str: str = markdown(in_str, extensions=[VariableExtension(variables=multi_var_dict)])
+ assert out_str == exp_str
+
+
+@pytest.mark.parametrize('in_str, exp_str', [
+ ('foo *${test}* and **${TEST}** bar', '<p>foo <em>value</em> and <strong>VALUE</strong> bar</p>'),
+ ('foo ![image](${PYMDVAR_TEST_1}/a.${ext}) bar', '<p>foo <img alt="image" src="/a.jpg" /> bar</p>')
+])
+def test_extension_text_mode(in_str: str, exp_str: str, multi_var_dict: dict[str, str]):
+ out_str: str = markdown(in_str, extensions=['pymdvar'], extension_configs={'pymdvar': {'variables': multi_var_dict}})
+ assert out_str == exp_str