diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml new file mode 100644 index 0000000..cef489a --- /dev/null +++ b/.github/workflows/tests.yaml @@ -0,0 +1,25 @@ +name: tests + +on: [push, pull_request] + +jobs: + pytest: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + python-version: ["3.8", "3.9", "3.10"] + + steps: + - uses: actions/checkout@v3 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install .[tests] + - name: Test with pytest + run: | + pytest -v diff --git a/README.rst b/README.rst deleted file mode 100644 index 44d1744..0000000 --- a/README.rst +++ /dev/null @@ -1,54 +0,0 @@ -Markdown-Include -================ - -This is an extension to -`Python-Markdown `__ which provides -an "include" function, similar to that found in LaTeX (and also the C -pre-processor and Fortran). I originally wrote it for my -`FORD `__ Fortran auto-documentation -generator. - -Installation ------------- - -This module can now be installed using ``pip``. - -:: - - pip install markdown-include - -Usage ------ - -This module can be used in a program in the following way: - -:: - - import markdown - html = markdown.markdown(source, extensions=[markdown_include.include']) - -The syntax for use within your Markdown files is ``{!filename!}``. This -statement will be replaced by the contents of ``filename``. -Markdown-Include will work recursively, so any included files within -``filename`` wil also be included. This replacement is done prior to any -other Markdown processing, so any Markdown syntax that you want can be used -within your included files. Note that this is a change from the previous -version. It was felt that this syntax was less likely to conflict with any code -fragments present in the Markdown. - -By default, all file-names are evaluated relative to the location from -which Markdown is being called. If you would like to change the -directory relative to which paths are evaluated, then this can be done -by specifying the extension setting ``base_path``. - -:: - - import markdown - from markdown_include.include import MarkdownInclude - - # Markdown Extensions - markdown_include = MarkdownInclude( - configs={'base_path':'/srv/content/', 'encoding': 'iso-8859-1'} - ) - html = markdown.markdown(source, extensions=[markdown_include]) - diff --git a/pyproject.toml b/pyproject.toml index c13bb83..b79f277 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,6 +30,11 @@ dependencies = [ ] dynamic = ["version"] +[project.optional-dependencies] +tests = [ + "pytest", +] + [tool.setuptools] packages = ["markdown_include"] diff --git a/unittests/resources/header.md b/tests/resources/header.md similarity index 100% rename from unittests/resources/header.md rename to tests/resources/header.md diff --git a/unittests/resources/simple.md b/tests/resources/simple.md similarity index 100% rename from unittests/resources/simple.md rename to tests/resources/simple.md diff --git a/unittests/resources/simple_2.md b/tests/resources/simple_2.md similarity index 100% rename from unittests/resources/simple_2.md rename to tests/resources/simple_2.md diff --git a/unittests/resources/template_inside.md b/tests/resources/template_inside.md similarity index 100% rename from unittests/resources/template_inside.md rename to tests/resources/template_inside.md diff --git a/tests/test_include.py b/tests/test_include.py new file mode 100644 index 0000000..d9ba59e --- /dev/null +++ b/tests/test_include.py @@ -0,0 +1,144 @@ +from markdown_include.include import IncludePreprocessor, MarkdownInclude + +import markdown +import pathlib +from textwrap import dedent + +import pytest + + +RESOURCE_DIR = pathlib.Path(__file__).parent.absolute() + + +@pytest.fixture(scope="module") +def markdown_include(): + return MarkdownInclude(configs={"base_path": RESOURCE_DIR}) + + +@pytest.fixture(scope="module") +def markdown_include_inherit_heading_depth(): + return MarkdownInclude( + configs={"base_path": RESOURCE_DIR, "inheritHeadingDepth": True} + ) + + +def test_single_include(markdown_include): + source = "{!resources/simple.md!}" + html = markdown.markdown(source, extensions=[markdown_include]) + + assert html == "

This is a simple template

" + + +def test_double_include(markdown_include): + source = "{!resources/simple.md!} and {!resources/simple_2.md!}" + html = markdown.markdown(source, extensions=[markdown_include]) + + assert ( + html == "

This is a simple template and This is another simple template

" + ) + + +def test_headers(markdown_include): + source = ( + "Source file\n" + "# Heading Level 1 of main file\n" + "{!resources/header.md!}\n" + "## Heading Level 2 of main file\n" + "{!resources/header.md!}" + ) + + html = markdown.markdown(source, extensions=[markdown_include]) + + assert html == dedent( + """\ +

Source file

+

Heading Level 1 of main file

+

This heading will be one level deeper from the previous heading

+

More included file content. + End of included content.

+

Heading Level 2 of main file

+

This heading will be one level deeper from the previous heading

+

More included file content. + End of included content.

""" + ) + + +def test_embedded_template(markdown_include): + source = "{!resources/template_inside.md!}" + html = markdown.markdown(source, extensions=[markdown_include]) + + assert ( + html + == "

This is a simple template

\n

This is a template with a template.

" + ) + + +def test_single_include_inherit_heading_depth(markdown_include_inherit_heading_depth): + source = "{!resources/simple.md!}" + html = markdown.markdown( + source, extensions=[markdown_include_inherit_heading_depth] + ) + + assert html == "

This is a simple template

" + + +def test_double_include_inherit_heading_depth(markdown_include_inherit_heading_depth): + source = "{!resources/simple.md!} and {!resources/simple_2.md!}" + html = markdown.markdown( + source, extensions=[markdown_include_inherit_heading_depth] + ) + + assert ( + html == "

This is a simple template and This is another simple template

" + ) + + +def test_headers_inherit_heading_depth(markdown_include_inherit_heading_depth): + source = ( + "Source file\n" + "# Heading Level 1 of main file\n" + "{!resources/header.md!}\n" + "## Heading Level 2 of main file\n" + "{!resources/header.md!}" + ) + + html = markdown.markdown( + source, extensions=[markdown_include_inherit_heading_depth] + ) + + assert html == dedent( + """\ +

Source file

+

Heading Level 1 of main file

+

This heading will be one level deeper from the previous heading

+

More included file content.

+

End of included content.

+

Heading Level 2 of main file

+

This heading will be one level deeper from the previous heading

+

More included file content.

+

End of included content.

""" + ) + + +def test_processor_lines(): + processor = IncludePreprocessor( + None, + { + "base_path": RESOURCE_DIR, + "encoding": "utf-8", + "inheritHeadingDepth": False, + "headingOffset": 0, + "throwException": False, + }, + ) + + source = [ + "Source file", + "# Heading Level 1 of main file", + "{!resources/header.md!}", + "## Heading Level 2 of main file", + "{!resources/header.md!}", + ] + result_lines = processor.run(source) + + assert len(result_lines) == 9 diff --git a/unittests/test_embedded.py b/unittests/test_embedded.py deleted file mode 100644 index a5e7d94..0000000 --- a/unittests/test_embedded.py +++ /dev/null @@ -1,20 +0,0 @@ -import os -from unittest import TestCase - -import markdown - -from markdown_include.include import IncludePreprocessor, MarkdownInclude - - -class TestEmbedded(TestCase): - def setUp(self) -> None: - self.maxDiff = None - self.markdown_include = MarkdownInclude( - configs={'base_path': os.path.dirname(os.path.realpath(__file__))} - ) - - def test_embedded_template(self): - source = "{!resources/template_inside.md!}" - html = markdown.markdown(source, extensions=[self.markdown_include]) - - self.assertEqual(html, "

This is a simple template

\n

This is a template with a template.

") diff --git a/unittests/test_include.py b/unittests/test_include.py deleted file mode 100644 index 62bb6c7..0000000 --- a/unittests/test_include.py +++ /dev/null @@ -1,45 +0,0 @@ -import os -from unittest import TestCase - -import markdown - -from markdown_include.include import MarkdownInclude - - -class TestInclude(TestCase): - def setUp(self) -> None: - self.maxDiff = None - self.markdown_include = MarkdownInclude( - configs={'base_path': os.path.dirname(os.path.realpath(__file__))} - ) - - def test_single_include(self): - source = "{!resources/simple.md!}" - html = markdown.markdown(source, extensions=[self.markdown_include]) - - self.assertEqual(html, '

This is a simple template

') - - def test_double_include(self): - source = "{!resources/simple.md!} and {!resources/simple_2.md!}" - html = markdown.markdown(source, extensions=[self.markdown_include]) - - self.assertEqual(html, '

This is a simple template and This is another simple template

') - - def test_headers(self): - source = "Source file\n" \ - "# Heading Level 1 of main file\n" \ - "{!resources/header.md!}\n" \ - "## Heading Level 2 of main file\n" \ - "{!resources/header.md!}" - - html = markdown.markdown(source, extensions=[self.markdown_include]) - - self.assertEqual(html, "

Source file

\n" - "

Heading Level 1 of main file

\n" - "

This heading will be one level deeper from the previous heading

\n" - "

More included file content.\n" - "End of included content.

\n" - "

Heading Level 2 of main file

\n" - "

This heading will be one level deeper from the previous heading

\n" - "

More included file content.\n" - "End of included content.

") diff --git a/unittests/test_include_header_indent.py b/unittests/test_include_header_indent.py deleted file mode 100644 index 35f651d..0000000 --- a/unittests/test_include_header_indent.py +++ /dev/null @@ -1,45 +0,0 @@ -import os -from unittest import TestCase - -import markdown - -from markdown_include.include import MarkdownInclude - - -class TestInclude(TestCase): - def setUp(self) -> None: - self.maxDiff = None - self.markdown_include = MarkdownInclude( - configs={'base_path': os.path.dirname(os.path.realpath(__file__)), 'inheritHeadingDepth': True} - ) - - def test_single_include(self): - source = "{!resources/simple.md!}" - html = markdown.markdown(source, extensions=[self.markdown_include]) - - self.assertEqual(html, '

This is a simple template

') - - def test_double_include(self): - source = "{!resources/simple.md!} and {!resources/simple_2.md!}" - html = markdown.markdown(source, extensions=[self.markdown_include]) - - self.assertEqual(html, '

This is a simple template and This is another simple template

') - - def test_headers(self): - source = "Source file\n" \ - "# Heading Level 1 of main file\n" \ - "{!resources/header.md!}\n" \ - "## Heading Level 2 of main file\n" \ - "{!resources/header.md!}" - - html = markdown.markdown(source, extensions=[self.markdown_include]) - - self.assertEqual(html, "

Source file

\n" - "

Heading Level 1 of main file

\n" - "

This heading will be one level deeper from the previous heading

\n" - "

More included file content.

\n" - "

End of included content.

\n" - "

Heading Level 2 of main file

\n" - "

This heading will be one level deeper from the previous heading

\n" - "

More included file content.

\n" - "

End of included content.

") diff --git a/unittests/test_lines.py b/unittests/test_lines.py deleted file mode 100644 index a97f1fe..0000000 --- a/unittests/test_lines.py +++ /dev/null @@ -1,26 +0,0 @@ -import os -from unittest import TestCase - -from markdown_include.include import IncludePreprocessor - - -class TestProcessor(TestCase): - def setUp(self) -> None: - self.maxDiff = None - self.processor = IncludePreprocessor(None, { - "base_path": os.path.dirname(os.path.realpath(__file__)), - "encoding": "utf-8", - "inheritHeadingDepth": False, - "headingOffset": 0, - "throwException": False, - }) - - def test_lines(self): - source = ["Source file", - "# Heading Level 1 of main file", - "{!resources/header.md!}", - "## Heading Level 2 of main file", - "{!resources/header.md!}"] - result_lines = self.processor.run(source) - - self.assertEqual(9, len(result_lines))