From c536b90097d934d1e425c7756aa4e147ba622a4a Mon Sep 17 00:00:00 2001 From: pyup-bot Date: Wed, 17 May 2017 07:52:37 +1200 Subject: [PATCH 01/12] Update sphinx from 1.5.5 to 1.6.1 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 41beef12..ddebf19e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,5 +6,5 @@ python-slugify==1.2.4 setuptools==35.0.2 # Required dependencies for building documentation -sphinx==1.5.5 +sphinx==1.6.1 sphinx_rtd_theme==0.2.4 From f3944d1e188fee617e02289b1df397f363ffc0cc Mon Sep 17 00:00:00 2001 From: ravenmaster001 Date: Mon, 22 May 2017 10:13:44 +1200 Subject: [PATCH 02/12] Remove BS4 from dependencies. --- requirements.txt | 1 - setup.py | 1 - 2 files changed, 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index ddebf19e..1251f000 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,5 @@ # Required dependencies for Verto (installed automatically in setup.py) markdown==2.6.8 -beautifulsoup4==4.5.3 Jinja2==2.9.6 python-slugify==1.2.4 setuptools==35.0.2 diff --git a/setup.py b/setup.py index 875892ac..30b37318 100644 --- a/setup.py +++ b/setup.py @@ -31,7 +31,6 @@ include_package_data=True, install_requires=[ 'markdown>=2.6.8', - 'beautifulsoup4>=4.5.3', 'Jinja2>=2.9.6', 'python-slugify>=1.2.4' ] From feff115912a37dd9da01afeb9761ec7888a15f27 Mon Sep 17 00:00:00 2001 From: ravenmaster001 Date: Mon, 22 May 2017 13:12:57 +1200 Subject: [PATCH 03/12] Inline images feature. --- docs/source/processors/image-inline.rst | 78 ++++++ docs/source/processors/index.rst | 1 + verto/VertoExtension.py | 2 + verto/html-templates/image-inline.html | 13 + verto/processor-info.json | 36 ++- verto/processors/ImageBlockProcessor.py | 1 - verto/processors/ImageInlinePattern.py | 56 +++++ verto/tests/ImageInlineTest.py | 236 ++++++++++++++++++ .../tests/assets/image-inline/argument_alt.md | 1 + .../image-inline/argument_alt_expected.html | 3 + .../assets/image-inline/argument_caption.md | 1 + .../argument_caption_expected.html | 4 + .../image-inline/argument_caption_link.md | 1 + .../argument_caption_link_expected.html | 4 + .../image-inline/argument_hover_text.md | 1 + .../argument_hover_text_expected.html | 3 + .../image-inline/argument_source_link.md | 1 + .../argument_source_link_expected.html | 4 + .../image-inline/doc_example_basic_usage.md | 1 + .../doc_example_basic_usage_expected.html | 3 + .../image-inline/doc_example_override_html.md | 1 + .../doc_example_override_html_expected.html | 3 + .../doc_example_override_html_template.html | 3 + .../assets/image-inline/external_image.md | 1 + .../image-inline/external_image_expected.html | 3 + .../assets/image-inline/internal_image.md | 1 + .../image-inline/internal_image_expected.html | 3 + .../image-inline/multiple_internal_images.md | 1 + .../multiple_internal_images_expected.html | 5 + .../assets/image-inline/numbered_list.md | 9 + .../image-inline/numbered_list_expected.html | 21 ++ .../tests/assets/image-inline/table_embed.md | 4 + .../image-inline/table_embed_expected.html | 26 ++ verto/tests/start_tests.py | 2 + 34 files changed, 529 insertions(+), 4 deletions(-) create mode 100644 docs/source/processors/image-inline.rst create mode 100644 verto/html-templates/image-inline.html create mode 100644 verto/processors/ImageInlinePattern.py create mode 100644 verto/tests/ImageInlineTest.py create mode 100644 verto/tests/assets/image-inline/argument_alt.md create mode 100644 verto/tests/assets/image-inline/argument_alt_expected.html create mode 100644 verto/tests/assets/image-inline/argument_caption.md create mode 100644 verto/tests/assets/image-inline/argument_caption_expected.html create mode 100644 verto/tests/assets/image-inline/argument_caption_link.md create mode 100644 verto/tests/assets/image-inline/argument_caption_link_expected.html create mode 100644 verto/tests/assets/image-inline/argument_hover_text.md create mode 100644 verto/tests/assets/image-inline/argument_hover_text_expected.html create mode 100644 verto/tests/assets/image-inline/argument_source_link.md create mode 100644 verto/tests/assets/image-inline/argument_source_link_expected.html create mode 100644 verto/tests/assets/image-inline/doc_example_basic_usage.md create mode 100644 verto/tests/assets/image-inline/doc_example_basic_usage_expected.html create mode 100644 verto/tests/assets/image-inline/doc_example_override_html.md create mode 100644 verto/tests/assets/image-inline/doc_example_override_html_expected.html create mode 100644 verto/tests/assets/image-inline/doc_example_override_html_template.html create mode 100644 verto/tests/assets/image-inline/external_image.md create mode 100644 verto/tests/assets/image-inline/external_image_expected.html create mode 100644 verto/tests/assets/image-inline/internal_image.md create mode 100644 verto/tests/assets/image-inline/internal_image_expected.html create mode 100644 verto/tests/assets/image-inline/multiple_internal_images.md create mode 100644 verto/tests/assets/image-inline/multiple_internal_images_expected.html create mode 100644 verto/tests/assets/image-inline/numbered_list.md create mode 100644 verto/tests/assets/image-inline/numbered_list_expected.html create mode 100644 verto/tests/assets/image-inline/table_embed.md create mode 100644 verto/tests/assets/image-inline/table_embed_expected.html diff --git a/docs/source/processors/image-inline.rst b/docs/source/processors/image-inline.rst new file mode 100644 index 00000000..73886744 --- /dev/null +++ b/docs/source/processors/image-inline.rst @@ -0,0 +1,78 @@ +Inline Image +####################################### + +**Processor name:** ``image-inline`` + +.. note:: + + The inline image tag allows for the use of images inside tables, *etc* without causing style errors. The tag functions almost exactly the same as the ``image`` tag except for not excluding the alignment argument. + +You can include an inline image using the following text tag: + +.. literalinclude:: ../../../verto/tests/assets/image-inline/doc_example_basic_usage.md + :language: none + +Required Tag Parameters +*************************************** + +- ``file-path`` - The path to the image. + + - Each file-path provided is added to the ``images`` set in required files stored by Verto. The set of filepaths can be accessed after conversion, see :ref:`accessing_verto_data`. + - **Note:** If the given link is a relative (a link that doesn't start with ``http:``), the link will be rendered with a Django static command. For example, the link ``images/example.png`` would be rendered as ``{% static 'images/example.png' %}`` This can be overriden, see the override section below. + +Optional Tag Parameters +*************************************** + +- ``alt`` - Description text of the image used when an image is not displayed, or can be read when using a screen reader (for those with reading difficulties). +- ``caption`` - Lists the given text as a caption under the image. +- ``caption-link`` (requires caption parameter) - Converts the caption text into a link to the given caption link URL. +- ``source`` (optional) - Adds the text 'Source' under the image with a link to the given source URL. Displays after the caption if a caption is given. +- ``hover-text`` - Additional text to be displayed when the user hovers their cursor over the image (note this won't appear on touch devices so use sparingly). + +The default HTML for image is: + +.. literalinclude:: ../../../verto/html-templates/image-inline.html + :language: css+jinja + +Using the following example tag: + +.. literalinclude:: ../../../verto/tests/assets/image-inline/doc_example_basic_usage.md + :language: none + +The resulting HTML would be: + +.. literalinclude:: ../../../verto/tests/assets/image-inline/doc_example_basic_usage_expected.html + :language: html + +Overriding HTML for Images +*************************************** + +When overriding the HTML for images, the following Jinja2 placeholders are available: + +- ``{{ file_path }}`` - The location for the path to the URL. +- ``{{ alt }}`` - The alternative text for the image. +- ``{{ hover_text }}`` - The text to display when the user hovers over the image (see `image title attribute `_). +- ``{{ caption }}`` - The text for the image caption. +- ``{{ caption_link }}`` - The URL for the caption link . +- ``{{ source_link }}`` - The URL for the source . + +If the ``file_path`` provided is a relative link, the link is passed through the ``relative-file-link.html`` template. +The default HTML for relative images is: + +.. literalinclude:: ../../../verto/html-templates/relative-file-link.html + :language: css+jinja + +For example, providing the following HTML: + +.. literalinclude:: ../../../verto/tests/assets/image-inline/doc_example_override_html_template.html + :language: css+jinja + +with the following tag: + +.. literalinclude:: ../../../verto/tests/assets/image-inline/doc_example_override_html.md + :language: none + +would result in: + +.. literalinclude:: ../../../verto/tests/assets/image-inline/doc_example_override_html_expected.html + :language: html diff --git a/docs/source/processors/index.rst b/docs/source/processors/index.rst index 9a4ace0a..ecc40ce8 100644 --- a/docs/source/processors/index.rst +++ b/docs/source/processors/index.rst @@ -21,6 +21,7 @@ The following pages covers how to use the available processors within Markdown t glossary-link heading image + image-inline interactive panel relative-link diff --git a/verto/VertoExtension.py b/verto/VertoExtension.py index 5774ce66..3d662ebb 100644 --- a/verto/VertoExtension.py +++ b/verto/VertoExtension.py @@ -3,6 +3,7 @@ from verto.processors.CommentPreprocessor import CommentPreprocessor from verto.processors.VideoBlockProcessor import VideoBlockProcessor +from verto.processors.ImageInlinePattern import ImageInlinePattern from verto.processors.ImageBlockProcessor import ImageBlockProcessor from verto.processors.InteractiveBlockProcessor import InteractiveBlockProcessor from verto.processors.RelativeLinkPattern import RelativeLinkPattern @@ -181,6 +182,7 @@ def buildProcessors(self, md, md_globals): self.inlinepatterns = [ # A special treeprocessor ['relative-link', RelativeLinkPattern(self, md), '_begin'], ['glossary-link', GlossaryLinkPattern(self, md), '_begin'], + ['image-inline', ImageInlinePattern(self, md), '_begin'] ] scratch_ordering = '>inline' if 'hilite' not in self.compatibility else ' + +{% if caption and caption_link -%} +

{{ caption }}

+{%- elif caption -%} +

{{ caption }}

+{%- endif -%} +{%- if source_link -%} +

Source

+{%- endif -%} + diff --git a/verto/processor-info.json b/verto/processor-info.json index d9066277..d7b56c9b 100644 --- a/verto/processor-info.json +++ b/verto/processor-info.json @@ -155,6 +155,36 @@ } } }, + "image-inline": { + "class": "custom", + "pattern": "\\{image-inline (?P[^\\}]*)\\}", + "arguments": { + "file-path": { + "required": true, + "dependencies": [] + }, + "alt": { + "required": false, + "dependencies": [] + }, + "caption": { + "required": false, + "dependencies": [] + }, + "caption-link": { + "required": false, + "dependencies": ["caption"] + }, + "source": { + "required": false, + "dependencies": [] + }, + "hover-text": { + "required": false, + "dependencies": [] + } + } + }, "interactive": { "class": "custom", "arguments": { @@ -234,10 +264,10 @@ }, "style": { "class": "custom", - "block_pattern": "\\{{{block} ?([^\\}}]*)\\}}", - "inline_pattern": "\\{{{inline} ?([^\\}}]*)\\}}", + "block_pattern": "\\{{{block}( ([^\\}}]*))?\\}}", + "inline_pattern": "\\{{{inline}( ([^\\}}]*))?\\}}", "strings": { - "inline": ["glossary-link"], + "inline": ["glossary-link", "image-inline"], "block": ["boxed-text", "button-link", "comment", "conditional", "iframe", "image", "interactive", "panel", "table-of-contents", "video"] } }, diff --git a/verto/processors/ImageBlockProcessor.py b/verto/processors/ImageBlockProcessor.py index 6720724f..3c3bbdf9 100644 --- a/verto/processors/ImageBlockProcessor.py +++ b/verto/processors/ImageBlockProcessor.py @@ -66,7 +66,6 @@ def run(self, parent, blocks): context = dict() context['file_path'] = file_path context['alt'] = argument_values.get('alt', None) - context['title'] = argument_values.get('title', None) context['caption'] = argument_values.get('caption', None) context['caption_link'] = argument_values.get('caption-link', None) context['source_link'] = argument_values.get('source', None) diff --git a/verto/processors/ImageInlinePattern.py b/verto/processors/ImageInlinePattern.py new file mode 100644 index 00000000..3c34c75c --- /dev/null +++ b/verto/processors/ImageInlinePattern.py @@ -0,0 +1,56 @@ +from verto.utils.HtmlParser import HtmlParser +from verto.processors.utils import parse_arguments +from markdown.inlinepatterns import Pattern +from html import escape +import re + + +class ImageInlinePattern(Pattern): + '''Return a link element from the given match.''' + + def __init__(self, ext, *args, **kwargs): + '''Create a inline image pattern. + + Args: + ext: An instance of the Markdown class. + ''' + self.processor = 'image-inline' + self.arguments = ext.processor_info[self.processor]['arguments'] + self.pattern = ext.processor_info[self.processor]['pattern'] + self.compiled_re = re.compile('^(.*?){}(.*)$'.format(self.pattern), re.DOTALL | re.UNICODE) + template_name = ext.processor_info.get('template_name', self.processor) + self.template = ext.jinja_templates[template_name] + self.relative_image_template = ext.jinja_templates['relative-file-link'] + self.required = ext.required_files['images'] + + def handleMatch(self, match): + ''' Inherited from Pattern. Accepts a match and returns an + ElementTree element of a internal link. + + Args: + match: The string of text where the match was found. + Returns: + An element tree node to be appended to the html tree. + ''' + arguments = match.group('args') + argument_values = parse_arguments(self.processor, arguments, self.arguments) + + # check if internal or external image + file_path = argument_values['file-path'] + external_path_match = re.search(r'^http', file_path) + if external_path_match is None: # internal image + self.required.add(file_path) + file_path = self.relative_image_template.render({'file_path': file_path}) + + context = dict() + context['file_path'] = file_path + context['alt'] = argument_values.get('alt', None) + context['caption'] = argument_values.get('caption', None) + context['caption_link'] = argument_values.get('caption-link', None) + context['source_link'] = argument_values.get('source', None) + context['hover_text'] = argument_values.get('hover-text', None) + + html_string = self.template.render(context) + parser = HtmlParser() + parser.feed(html_string).close() + return parser.get_root() diff --git a/verto/tests/ImageInlineTest.py b/verto/tests/ImageInlineTest.py new file mode 100644 index 00000000..ce0aa86c --- /dev/null +++ b/verto/tests/ImageInlineTest.py @@ -0,0 +1,236 @@ +import markdown +import re +from unittest.mock import Mock +from collections import defaultdict +from verto.VertoExtension import VertoExtension +from verto.processors.ImageInlinePattern import ImageInlinePattern +from verto.tests.ProcessorTest import ProcessorTest + +class ImageInlineTest(ProcessorTest): + '''Tests to check the 'image-inline' pattern works as intended.''' + + def __init__(self, *args, **kwargs): + '''Set processor name in class for asset file retrieval.''' + ProcessorTest.__init__(self, *args, **kwargs) + self.processor_name = 'image-inline' + self.ext = Mock() + self.ext.processor_info = ProcessorTest.loadProcessorInfo(self) + self.ext.required_files = defaultdict(set) + self.ext.jinja_templates = { + self.processor_name: ProcessorTest.loadJinjaTemplate(self, self.processor_name), + 'relative-file-link': ProcessorTest.loadJinjaTemplate(self, 'relative-file-link') + } + + def test_basic_usage(self): + '''Test common usage case.''' + test_string = self.read_test_file(self.processor_name, 'doc_example_basic_usage.md') + + processor = ImageInlinePattern(self.ext, self.md.parser) + self.assertIsNotNone(re.search(processor.compiled_re, test_string)) + + converted_test_string = markdown.markdown(test_string, extensions=[self.verto_extension]) + expected_string = self.read_test_file(self.processor_name, 'doc_example_basic_usage_expected.html', strip=True).strip() + self.assertEqual(expected_string, converted_test_string) + + images = self.verto_extension.required_files['images'] + expected_images = { + 'img/example.png' + } + self.assertSetEqual(expected_images, images) + + + def test_doc_example_override_html(self): + '''Basic example showing how to override the html-template.''' + test_string = self.read_test_file(self.processor_name, 'doc_example_override_html.md') + + processor = ImageInlinePattern(self.ext, self.md.parser) + self.assertIsNotNone(re.search(processor.compiled_re, test_string)) + + html_template = self.read_test_file(self.processor_name, 'doc_example_override_html_template.html', strip=True) + verto_extension = VertoExtension([self.processor_name], html_templates={self.processor_name: html_template}) + + converted_test_string = markdown.markdown(test_string, extensions=[verto_extension]) + expected_string = self.read_test_file(self.processor_name, 'doc_example_override_html_expected.html', strip=True).strip() + self.assertEqual(expected_string, converted_test_string) + + images = verto_extension.required_files['images'] + expected_images = set() + self.assertSetEqual(expected_images, images) + + #~ + # Image locations tests + #~ + + def test_internal_image(self): + '''Test to ensure that an internally reference image produces + the desired output, including changing the expected images of + the verto extension. + ''' + test_string = self.read_test_file(self.processor_name, 'internal_image.md') + + processor = ImageInlinePattern(self.ext, self.md.parser) + self.assertIsNotNone(re.search(processor.compiled_re, test_string)) + + converted_test_string = markdown.markdown(test_string, extensions=[self.verto_extension]) + expected_string = self.read_test_file(self.processor_name, 'internal_image_expected.html', strip=True).strip() + self.assertEqual(expected_string, converted_test_string) + + images = self.verto_extension.required_files['images'] + expected_images = { + 'img/example.png' + } + self.assertSetEqual(expected_images, images) + + def test_external_image(self): + '''Test that external images are processed and that the + expected images are unchanged. + ''' + test_string = self.read_test_file(self.processor_name, 'external_image.md') + + processor = ImageInlinePattern(self.ext, self.md.parser) + self.assertIsNotNone(re.search(processor.compiled_re, test_string)) + + converted_test_string = markdown.markdown(test_string, extensions=[self.verto_extension]) + expected_string = self.read_test_file(self.processor_name, 'external_image_expected.html', strip=True).strip() + self.assertEqual(expected_string, converted_test_string) + + images = self.verto_extension.required_files['images'] + expected_images = set() + self.assertSetEqual(expected_images, images) + + def test_multiple_internal_images(self): + '''Test to ensure that an internally reference images produces + the desired output, including changing the expected images of + the verto extension. + ''' + test_string = self.read_test_file(self.processor_name, 'multiple_internal_images.md') + + processor = ImageInlinePattern(self.ext, self.md.parser) + self.assertIsNotNone(re.search(processor.compiled_re, test_string)) + + converted_test_string = markdown.markdown(test_string, extensions=[self.verto_extension]) + expected_string = self.read_test_file(self.processor_name, 'multiple_internal_images_expected.html', strip=True).strip() + self.assertEqual(expected_string, converted_test_string) + + images = self.verto_extension.required_files['images'] + expected_images = { + 'img/example.png', + 'img/placeholder.jpg' + } + self.assertSetEqual(expected_images, images) + + #~ + # Argument tests + #~ + + def test_argument_alt(self): + '''Test that the alt argument is correctly rendered.''' + test_string = self.read_test_file(self.processor_name, 'argument_alt.md') + + processor = ImageInlinePattern(self.ext, self.md.parser) + self.assertIsNotNone(re.search(processor.compiled_re, test_string)) + + converted_test_string = markdown.markdown(test_string, extensions=[self.verto_extension]) + expected_string = self.read_test_file(self.processor_name, 'argument_alt_expected.html', strip=True).strip() + self.assertEqual(expected_string, converted_test_string) + + images = self.verto_extension.required_files['images'] + expected_images = set() + self.assertSetEqual(expected_images, images) + + def test_argument_caption(self): + '''Test that the caption argument is correctly rendered.''' + test_string = self.read_test_file(self.processor_name, 'argument_caption.md') + + processor = ImageInlinePattern(self.ext, self.md.parser) + self.assertIsNotNone(re.search(processor.compiled_re, test_string)) + + converted_test_string = markdown.markdown(test_string, extensions=[self.verto_extension]) + expected_string = self.read_test_file(self.processor_name, 'argument_caption_expected.html', strip=True).strip() + self.assertEqual(expected_string, converted_test_string) + + images = self.verto_extension.required_files['images'] + expected_images = set() + self.assertSetEqual(expected_images, images) + + def test_argument_caption_link(self): + '''Test that the caption-link argument is correctly rendered.''' + test_string = self.read_test_file(self.processor_name, 'argument_caption_link.md') + + processor = ImageInlinePattern(self.ext, self.md.parser) + self.assertIsNotNone(re.search(processor.compiled_re, test_string)) + + converted_test_string = markdown.markdown(test_string, extensions=[self.verto_extension]) + expected_string = self.read_test_file(self.processor_name, 'argument_caption_link_expected.html', strip=True).strip() + self.assertEqual(expected_string, converted_test_string) + + images = self.verto_extension.required_files['images'] + expected_images = set() + self.assertSetEqual(expected_images, images) + + def test_argument_source_link(self): + '''Test that the source-link argument is correctly rendered.''' + test_string = self.read_test_file(self.processor_name, 'argument_source_link.md') + + processor = ImageInlinePattern(self.ext, self.md.parser) + self.assertIsNotNone(re.search(processor.compiled_re, test_string)) + + converted_test_string = markdown.markdown(test_string, extensions=[self.verto_extension]) + expected_string = self.read_test_file(self.processor_name, 'argument_source_link_expected.html', strip=True).strip() + self.assertEqual(expected_string, converted_test_string) + + images = self.verto_extension.required_files['images'] + expected_images = set() + self.assertSetEqual(expected_images, images) + + def test_argument_hover_text(self): + '''Test that the hover-text argument is correctly rendered.''' + test_string = self.read_test_file(self.processor_name, 'argument_hover_text.md') + + processor = ImageInlinePattern(self.ext, self.md.parser) + self.assertIsNotNone(re.search(processor.compiled_re, test_string)) + + converted_test_string = markdown.markdown(test_string, extensions=[self.verto_extension]) + expected_string = self.read_test_file(self.processor_name, 'argument_hover_text_expected.html', strip=True).strip() + self.assertEqual(expected_string, converted_test_string) + + images = self.verto_extension.required_files['images'] + expected_images = set() + self.assertSetEqual(expected_images, images) + + #~ + # Embed test. + #~ + + def test_numbered_list(self): + '''Test that image-inline functions within a numbered list.''' + test_string = self.read_test_file(self.processor_name, 'numbered_list.md') + + processor = ImageInlinePattern(self.ext, self.md.parser) + self.assertIsNotNone(re.search(processor.compiled_re, test_string)) + + converted_test_string = markdown.markdown(test_string, extensions=[self.verto_extension]) + expected_string = self.read_test_file(self.processor_name, 'numbered_list_expected.html', strip=True).strip() + self.assertEqual(expected_string, converted_test_string) + + images = self.verto_extension.required_files['images'] + expected_images = set() + self.assertSetEqual(expected_images, images) + + def test_table_embed(self): + '''Test that image-inline functions within a table.''' + test_string = self.read_test_file(self.processor_name, 'table_embed.md') + + processor = ImageInlinePattern(self.ext, self.md.parser) + self.assertIsNotNone(re.search(processor.compiled_re, test_string)) + + converted_test_string = markdown.markdown(test_string, extensions=[self.verto_extension, 'markdown.extensions.tables']) + expected_string = self.read_test_file(self.processor_name, 'table_embed_expected.html', strip=True).strip() + self.assertEqual(expected_string, converted_test_string) + + images = self.verto_extension.required_files['images'] + expected_images = { + 'img/example1.png', + 'img/example2.png' + } + self.assertSetEqual(expected_images, images) diff --git a/verto/tests/assets/image-inline/argument_alt.md b/verto/tests/assets/image-inline/argument_alt.md new file mode 100644 index 00000000..c5bbcae0 --- /dev/null +++ b/verto/tests/assets/image-inline/argument_alt.md @@ -0,0 +1 @@ +An inline image: {image-inline file-path="http://placehold.it/350x150" alt="Lipsum"}. diff --git a/verto/tests/assets/image-inline/argument_alt_expected.html b/verto/tests/assets/image-inline/argument_alt_expected.html new file mode 100644 index 00000000..cd24ec04 --- /dev/null +++ b/verto/tests/assets/image-inline/argument_alt_expected.html @@ -0,0 +1,3 @@ +

An inline image:

+Lipsum +
.

diff --git a/verto/tests/assets/image-inline/argument_caption.md b/verto/tests/assets/image-inline/argument_caption.md new file mode 100644 index 00000000..79ddbbed --- /dev/null +++ b/verto/tests/assets/image-inline/argument_caption.md @@ -0,0 +1 @@ +An inline image: {image-inline file-path="http://placehold.it/350x150" caption="Lipsum Lorem"}. diff --git a/verto/tests/assets/image-inline/argument_caption_expected.html b/verto/tests/assets/image-inline/argument_caption_expected.html new file mode 100644 index 00000000..4ce5ee90 --- /dev/null +++ b/verto/tests/assets/image-inline/argument_caption_expected.html @@ -0,0 +1,4 @@ +

An inline image:

+ +

Lipsum Lorem

+
.

diff --git a/verto/tests/assets/image-inline/argument_caption_link.md b/verto/tests/assets/image-inline/argument_caption_link.md new file mode 100644 index 00000000..49b3a6f3 --- /dev/null +++ b/verto/tests/assets/image-inline/argument_caption_link.md @@ -0,0 +1 @@ +An inline image: {image-inline file-path="http://placehold.it/350x150" caption="Lipsum Lorem" caption-link="http://www.example.com"}. diff --git a/verto/tests/assets/image-inline/argument_caption_link_expected.html b/verto/tests/assets/image-inline/argument_caption_link_expected.html new file mode 100644 index 00000000..518067a8 --- /dev/null +++ b/verto/tests/assets/image-inline/argument_caption_link_expected.html @@ -0,0 +1,4 @@ +

An inline image:

.

diff --git a/verto/tests/assets/image-inline/argument_hover_text.md b/verto/tests/assets/image-inline/argument_hover_text.md new file mode 100644 index 00000000..e9f7c1f2 --- /dev/null +++ b/verto/tests/assets/image-inline/argument_hover_text.md @@ -0,0 +1 @@ +An inline image: {image-inline file-path="http://placehold.it/350x150" hover-text="Lipsum Lorem"}. diff --git a/verto/tests/assets/image-inline/argument_hover_text_expected.html b/verto/tests/assets/image-inline/argument_hover_text_expected.html new file mode 100644 index 00000000..a1ee85e3 --- /dev/null +++ b/verto/tests/assets/image-inline/argument_hover_text_expected.html @@ -0,0 +1,3 @@ +

An inline image:

+ +
.

diff --git a/verto/tests/assets/image-inline/argument_source_link.md b/verto/tests/assets/image-inline/argument_source_link.md new file mode 100644 index 00000000..e4ab1fe3 --- /dev/null +++ b/verto/tests/assets/image-inline/argument_source_link.md @@ -0,0 +1 @@ +An inline image: {image-inline file-path="http://placehold.it/350x150" source="http://www.example.com"}. diff --git a/verto/tests/assets/image-inline/argument_source_link_expected.html b/verto/tests/assets/image-inline/argument_source_link_expected.html new file mode 100644 index 00000000..2b48541c --- /dev/null +++ b/verto/tests/assets/image-inline/argument_source_link_expected.html @@ -0,0 +1,4 @@ +

An inline image:

+ +

Source

+
.

diff --git a/verto/tests/assets/image-inline/doc_example_basic_usage.md b/verto/tests/assets/image-inline/doc_example_basic_usage.md new file mode 100644 index 00000000..b026c2d8 --- /dev/null +++ b/verto/tests/assets/image-inline/doc_example_basic_usage.md @@ -0,0 +1 @@ +An inline image: {image-inline file-path="img/example.png"}. diff --git a/verto/tests/assets/image-inline/doc_example_basic_usage_expected.html b/verto/tests/assets/image-inline/doc_example_basic_usage_expected.html new file mode 100644 index 00000000..5889401f --- /dev/null +++ b/verto/tests/assets/image-inline/doc_example_basic_usage_expected.html @@ -0,0 +1,3 @@ +

An inline image:

+ +
.

diff --git a/verto/tests/assets/image-inline/doc_example_override_html.md b/verto/tests/assets/image-inline/doc_example_override_html.md new file mode 100644 index 00000000..f1fe58dd --- /dev/null +++ b/verto/tests/assets/image-inline/doc_example_override_html.md @@ -0,0 +1 @@ +An inline image: {image-inline file-path="http://placehold.it/350x150" caption="Placeholder image" source="https://placehold.it/"}. diff --git a/verto/tests/assets/image-inline/doc_example_override_html_expected.html b/verto/tests/assets/image-inline/doc_example_override_html_expected.html new file mode 100644 index 00000000..74e3ca2a --- /dev/null +++ b/verto/tests/assets/image-inline/doc_example_override_html_expected.html @@ -0,0 +1,3 @@ +

An inline image:

+ +
.

diff --git a/verto/tests/assets/image-inline/doc_example_override_html_template.html b/verto/tests/assets/image-inline/doc_example_override_html_template.html new file mode 100644 index 00000000..1ea96063 --- /dev/null +++ b/verto/tests/assets/image-inline/doc_example_override_html_template.html @@ -0,0 +1,3 @@ +
+ +
diff --git a/verto/tests/assets/image-inline/external_image.md b/verto/tests/assets/image-inline/external_image.md new file mode 100644 index 00000000..6e542791 --- /dev/null +++ b/verto/tests/assets/image-inline/external_image.md @@ -0,0 +1 @@ +An external image: {image-inline file-path="http://placehold.it/350x150"}. diff --git a/verto/tests/assets/image-inline/external_image_expected.html b/verto/tests/assets/image-inline/external_image_expected.html new file mode 100644 index 00000000..331d87ca --- /dev/null +++ b/verto/tests/assets/image-inline/external_image_expected.html @@ -0,0 +1,3 @@ +

An external image:

+ +
.

diff --git a/verto/tests/assets/image-inline/internal_image.md b/verto/tests/assets/image-inline/internal_image.md new file mode 100644 index 00000000..9b87edd6 --- /dev/null +++ b/verto/tests/assets/image-inline/internal_image.md @@ -0,0 +1 @@ +An internal image: {image-inline file-path="img/example.png"}. diff --git a/verto/tests/assets/image-inline/internal_image_expected.html b/verto/tests/assets/image-inline/internal_image_expected.html new file mode 100644 index 00000000..39561c40 --- /dev/null +++ b/verto/tests/assets/image-inline/internal_image_expected.html @@ -0,0 +1,3 @@ +

An internal image:

+ +
.

diff --git a/verto/tests/assets/image-inline/multiple_internal_images.md b/verto/tests/assets/image-inline/multiple_internal_images.md new file mode 100644 index 00000000..6b2e9495 --- /dev/null +++ b/verto/tests/assets/image-inline/multiple_internal_images.md @@ -0,0 +1 @@ +An internal image: {image-inline file-path="img/example.png"} and some other related image {image-inline file-path="img/placeholder.jpg"}. diff --git a/verto/tests/assets/image-inline/multiple_internal_images_expected.html b/verto/tests/assets/image-inline/multiple_internal_images_expected.html new file mode 100644 index 00000000..a4d96d7b --- /dev/null +++ b/verto/tests/assets/image-inline/multiple_internal_images_expected.html @@ -0,0 +1,5 @@ +

An internal image:

+ +
and some other related image
+ +
.

diff --git a/verto/tests/assets/image-inline/numbered_list.md b/verto/tests/assets/image-inline/numbered_list.md new file mode 100644 index 00000000..86ade6c2 --- /dev/null +++ b/verto/tests/assets/image-inline/numbered_list.md @@ -0,0 +1,9 @@ +1. Lipsum + + * Ichi + * Ni + * San + +2. Lorem {image-inline file-path="http://placehold.it/350x150" caption="Placeholder image" source="https://placehold.it/" hover-text="This is hover text"} + +3. Ipsem diff --git a/verto/tests/assets/image-inline/numbered_list_expected.html b/verto/tests/assets/image-inline/numbered_list_expected.html new file mode 100644 index 00000000..d93521fd --- /dev/null +++ b/verto/tests/assets/image-inline/numbered_list_expected.html @@ -0,0 +1,21 @@ +
    +
  1. +

    Lipsum

    +
      +
    • Ichi
    • +
    • Ni
    • +
    • San
    • +
    +
  2. +
  3. +

    Lorem

    + +

    Placeholder image

    +

    Source

    +
    +

    +
  4. +
  5. +

    Ipsem

    +
  6. +
diff --git a/verto/tests/assets/image-inline/table_embed.md b/verto/tests/assets/image-inline/table_embed.md new file mode 100644 index 00000000..62912681 --- /dev/null +++ b/verto/tests/assets/image-inline/table_embed.md @@ -0,0 +1,4 @@ +| Input | Output | +| ----- | ------------------------------------------- | +| 31 | {image-inline file-path="img/example1.png"} | +| 11 | {image-inline file-path="img/example2.png"} | diff --git a/verto/tests/assets/image-inline/table_embed_expected.html b/verto/tests/assets/image-inline/table_embed_expected.html new file mode 100644 index 00000000..7054919e --- /dev/null +++ b/verto/tests/assets/image-inline/table_embed_expected.html @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + +
InputOutput
31 +
+ +
+
11 +
+ +
+
diff --git a/verto/tests/start_tests.py b/verto/tests/start_tests.py index 069dd019..3dce654f 100644 --- a/verto/tests/start_tests.py +++ b/verto/tests/start_tests.py @@ -11,6 +11,7 @@ from verto.tests.FrameTest import FrameTest from verto.tests.GlossaryLinkTest import GlossaryLinkTest from verto.tests.HeadingTest import HeadingTest +from verto.tests.ImageInlineTest import ImageInlineTest from verto.tests.ImageTest import ImageTest from verto.tests.JinjaTest import JinjaTest from verto.tests.InteractiveTest import InteractiveTest @@ -71,6 +72,7 @@ def unit_suite(): unittest.makeSuite(FrameTest), unittest.makeSuite(GlossaryLinkTest), unittest.makeSuite(HeadingTest), + unittest.makeSuite(ImageInlineTest), unittest.makeSuite(ImageTest), unittest.makeSuite(InteractiveTest), unittest.makeSuite(JinjaTest), From a7cca74a8dfcbf3133ac498f6d92df27ec8affbc Mon Sep 17 00:00:00 2001 From: ravenmaster001 Date: Mon, 22 May 2017 13:16:21 +1200 Subject: [PATCH 04/12] flake8 fix. --- verto/processors/ImageInlinePattern.py | 1 - 1 file changed, 1 deletion(-) diff --git a/verto/processors/ImageInlinePattern.py b/verto/processors/ImageInlinePattern.py index 3c34c75c..eadeafc1 100644 --- a/verto/processors/ImageInlinePattern.py +++ b/verto/processors/ImageInlinePattern.py @@ -1,7 +1,6 @@ from verto.utils.HtmlParser import HtmlParser from verto.processors.utils import parse_arguments from markdown.inlinepatterns import Pattern -from html import escape import re From 2664d493284b8db3b0ebd3f1ba86dec418ace9d7 Mon Sep 17 00:00:00 2001 From: ravenmaster001 Date: Mon, 22 May 2017 14:22:49 +1200 Subject: [PATCH 05/12] Inline scratch tests and documentation. --- docs/source/images/scratch_inline_example.png | Bin 0 -> 2492 bytes docs/source/processors/index.rst | 1 + docs/source/processors/scratch-inline.rst | 87 ++++++++++++ docs/source/processors/scratch.rst | 4 +- verto/html-templates/scratch-inline.html | 1 + verto/tests/ScratchInlineTest.py | 134 ++++++++++++++++++ .../scratch-inline/doc_example_basic_usage.md | 1 + .../doc_example_basic_usage_expected.html | 1 + .../doc_example_override_html.md | 1 + .../doc_example_override_html_expected.html | 1 + .../doc_example_override_html_template.html | 1 + .../assets/scratch-inline/mixed_codeblocks.md | 1 + .../mixed_codeblocks_expected.html | 1 + .../scratch-inline/multiple_codeblocks.md | 1 + .../multiple_codeblocks_expected.html | 1 + verto/tests/start_tests.py | 2 + 16 files changed, 236 insertions(+), 2 deletions(-) create mode 100644 docs/source/images/scratch_inline_example.png create mode 100644 docs/source/processors/scratch-inline.rst create mode 100644 verto/html-templates/scratch-inline.html create mode 100644 verto/tests/ScratchInlineTest.py create mode 100644 verto/tests/assets/scratch-inline/doc_example_basic_usage.md create mode 100644 verto/tests/assets/scratch-inline/doc_example_basic_usage_expected.html create mode 100644 verto/tests/assets/scratch-inline/doc_example_override_html.md create mode 100644 verto/tests/assets/scratch-inline/doc_example_override_html_expected.html create mode 100644 verto/tests/assets/scratch-inline/doc_example_override_html_template.html create mode 100644 verto/tests/assets/scratch-inline/mixed_codeblocks.md create mode 100644 verto/tests/assets/scratch-inline/mixed_codeblocks_expected.html create mode 100644 verto/tests/assets/scratch-inline/multiple_codeblocks.md create mode 100644 verto/tests/assets/scratch-inline/multiple_codeblocks_expected.html diff --git a/docs/source/images/scratch_inline_example.png b/docs/source/images/scratch_inline_example.png new file mode 100644 index 0000000000000000000000000000000000000000..358f04208017a8340290e9845c6e9420bfeda63c GIT binary patch literal 2492 zcmV;t2}AaYP)X1^@s6{i61L000StNklbyIr=NzOT zHurBlxa|QyY!%QI3Frzf)D^sxw!nfm-$HG^8BOk8_T;pq*>L~ZLLrzh|B9AJua28K zr<=;`->FD9{hV;79^CeT16!=<3asqQwX!!$pk_m?sxvKUGR;(NxQ8<9Hku5}k@+Cl zmut!U;Y$k#O0Cr8&z*lo%cJT{3+l}KRIcw}hx`)T|8eQpn1R~A?OtT27Femxwo<)b zK$9+@R>YS|Zb6;?0CnblG}*oE&Ff)bQ4iXv9rdCs>1BWEeGY8tV}GdyU6B=S-oo;) zXnCZRo2is{u|sBHOX>+?LD<@Zu1H{CZe)-al2j$PpjKE=ueVT>ZDC(t#DcW>uUeBp zUA}-eFOs`v!)yRfojQeHug7RKVltU%Z*O06nM@{(M&q(K`B=HY<pZ6bJ>y* z7cjkEPe(@wf*@eG+Zh}jTyoj%b_8L08+@_36NAA(M@I){vl*MshTU$*ZntBz*)W^U z+|>W^o`BHJHz`*sSrf+*>Pma4E3iKTGkRkt7LG6ytv1dUF!VALfi|_^s+cRxV&L80hWoWq5cPQ55m}{Ya8T zAP^uB2p~xke!m}46d4{Key7XCdkaE)dpm=JgZO+tg25nHu3TaB=FPl_@$qp!`sgDP z#o@z;XDMC;gF$>gU(B~_v#bDI(7ydF{q1x&9UUDw91cWLWM*atr_;%&pMJ`^b?f-# zlTR2O9VHYBF*7rRD2nvm@c#8csNG=YVW$ttA7*kQ5N%p*RzCyXk>5R|5>4MlC?7IU z(cdwNS|Om#=_ee5^R**O0)p4;MJ|`KapOj^va*<*oQwg%<#HjH%gM{jBP}frr_-4b zgz-nuqTe}R`xw)yaeS@-)7~KWE_tOEC7VVVI)by?RLlHNz~_Gsz;ca3Zcuj(V`k=dNN2& zhBZ=G7*2dUh~e-kl0WipqCATRp|Q+CI0T~){oHJs;80Pd8Hb7o7&1>GIwhvPK_({x zQ6eROn5OTBxOdrurEP8-d=p0~EG#4?C57zlY}Tz?hf=AG0b$doO|-YS17I?l*tBU= zLJ+js{Q#U%57T+hh3J%`e;XF2v6#G35Dpa&#I3*W_nQn13?Pakfj}Ty_r$~m85tQE zjmBBaR3H$*GZ9-$qCR(DbQ2E2v#Aizra}azF#q|No!jSJc*dj!=UFreYK1_O$Kb*Bc!uir0=Ldg;By6{&p)^>(s|B>dsL#OYVJ+gn}DEFsc3F) z2Egfb;&QoSKv1bvG&VK@(Ad~WRaMo3K)C%H2qV^MENw4A(B<0V*8lr?Ym6g!y&Jn~NS_d`7O1o8Vqvx-M~L?f|Vvov0N8CwC6=)DzjjoYf5D_XX*`4{&%4lkF3bypS|M;#@0fLJ2!%qk_6p%}IC^SGB-2ltl$4+-aHEiLAwOUM{Rb0WTy=@mO0*Q5SCJ1hR5^XBh0s7 z`ZM(6ia8+&+Ty!t^ZTgIT-=9@$D9Oa!gQRSSkUu}y--?+=DJW?N;Q=a(Rahk*yHi& z&7$afilxmPcR6?$Qp(L#$hz2`Y@j&lcq|AtMYpNVyN@Q*^8BAke@`CjTeC;j1TBE0M^^sT*_T*hho!f;fvzID`nJW2%In;+r-uFhpsN@mAs^opoHCO%> zEwz+#Gkel{sgQM2meR_Wq!#j4*T;gO$*_J=k=07&`djQu>tvVg4!dOCaaEaimpy5{ zDCOqoP|OWP1b_$ZN$aID?H-k~y9slzXgPF;3RxHBYj07O(#n@f=P3BNflYrqZj1q8 z)v8sil%MtG>`>_0Au~{xdWEu-t9%oqYwSq9PWjrK?2_GKPul%CVNl8YP|EL9DZ9&e zYdiQh^#)}rt#R_MXgRe#*}zw8^lV9Lq2S{N3O{bT78imSu`~I0;g;0nl%|}dWX%bR zUs1`Lla#J$W@~Z_U#DJVr|der(mL6l*7MvQ64}umcBZ!Rb@Fd)O*%_S(kY6Qnr7u* z(K0LPIEAZ^khi)%u@k&)C_n4V*{Qh3_wt)m#4IN-?Py1ek!@=(P_+64rGGzjc}a^{ ziT5LvpY`Q@BagqF%(A1^N9MPqmH2B%!sTQ+?Pw*IH2wz_0AyLDe diff --git a/verto/tests/ScratchInlineTest.py b/verto/tests/ScratchInlineTest.py new file mode 100644 index 00000000..4479ad4a --- /dev/null +++ b/verto/tests/ScratchInlineTest.py @@ -0,0 +1,134 @@ +import markdown +from unittest.mock import Mock +from collections import defaultdict + +from verto.VertoExtension import VertoExtension +from verto.processors.ScratchInlineTest import ScratchInlineTest +from verto.tests.ProcessorTest import ProcessorTest + +class ScratchInlineTest(ProcessorTest): + '''Scratch blocks are unique in that they override behaviour in markdown. + ''' + def __init__(self, *args, **kwargs): + '''Sets name for loading test assets.''' + ProcessorTest.__init__(self, *args, **kwargs) + self.processor_name = 'scratch-inline' + + def setUp(self): + '''Overrides the generic setup to load the fenced_code + extension by default (as this is the desired usecase). + ''' + self.verto_extension = VertoExtension([self.processor_name], {}, ['markdown.extensions.fenced_code']) + + def test_doc_example_basic(self): + '''An example of common useage.''' + test_string = self.read_test_file(self.processor_name, 'doc_example_basic_usage.md') + + converted_test_string = markdown.markdown(test_string, extensions=['markdown.extensions.fenced_code', self.verto_extension]) + expected_string = self.read_test_file(self.processor_name, 'doc_example_basic_usage_expected.html', strip=True) + self.assertEqual(expected_string, converted_test_string) + + actual_scratch_images = self.verto_extension.required_files['scratch_images'] + expected_scratch_images = { + ScratchImageMetaData( + hash='', + text='say [Hello] for (2) secs' + ), + } + self.assertSetEqual(actual_scratch_images, expected_scratch_images) + + def test_doc_example_override_html(self): + '''An example showing how to override the html-template.''' + test_string = self.read_test_file(self.processor_name, 'doc_example_override_html.md') + + html_template = self.read_test_file(self.processor_name, 'doc_example_override_html_template.html', strip=True) + verto_extension = VertoExtension([self.processor_name], html_templates={self.processor_name: html_template}, extensions=['markdown.extensions.fenced_code']) + + converted_test_string = markdown.markdown(test_string, extensions=['markdown.extensions.fenced_code', verto_extension]) + expected_string = self.read_test_file(self.processor_name, 'doc_example_override_html_expected.html', strip=True) + self.assertEqual(expected_string, converted_test_string) + + actual_scratch_images = verto_extension.required_files['scratch_images'] + expected_scratch_images = { + ScratchImageMetaData( + hash='', + text='when flag clicked' + ), + } + self.assertSetEqual(actual_scratch_images, expected_scratch_images) + + #~ + # Other Tests + #~ + + def test_multiple_codeblocks(self): + '''Tests that multiple codeblocks are processed independently.''' + test_string = self.read_test_file(self.processor_name, 'multiple_codeblocks.md') + + converted_test_string = markdown.markdown(test_string, extensions=['markdown.extensions.fenced_code', self.verto_extension]) + expected_string = self.read_test_file(self.processor_name, 'multiple_codeblocks_expected.html', strip=True) + self.assertEqual(expected_string, converted_test_string) + + actual_scratch_images = self.verto_extension.required_files['scratch_images'] + expected_scratch_images = { + ScratchImageMetaData( + hash='', + text='say [Hello] for (2) secs' + ), + ScratchImageMetaData( + hash='', + text='when flag clicked' + ), + ScratchImageMetaData( + hash='', + text='turn ccw (9) degrees' + ), + } + self.assertSetEqual(actual_scratch_images, expected_scratch_images) + + def test_mixed_codeblocks(self): + '''Tests that normal codeblocks are not inadvertently effected.''' + extensions = ['markdown.extensions.fenced_code'] + verto_extension = VertoExtension([self.processor_name], {}, extensions) + test_string = self.read_test_file(self.processor_name, 'mixed_codeblocks.md') + + converted_test_string = markdown.markdown(test_string, extensions=extensions + [verto_extension]) + expected_string = self.read_test_file(self.processor_name, 'mixed_codeblocks_expected.html', strip=True) + self.assertEqual(expected_string, converted_test_string) + + actual_scratch_images = verto_extension.required_files['scratch_images'] + expected_scratch_images = { + ScratchImageMetaData( + hash='', + text='say [Hello]' + ) + } + self.assertSetEqual(actual_scratch_images, expected_scratch_images) + + + def test_codeblocks_compatibility(self): + '''Test the codehilite and fenced_code do not causes any issues.''' + extensions = ['markdown.extensions.codehilite', 'markdown.extensions.fenced_code'] + verto_extension = VertoExtension([self.processor_name], {}, extensions) + test_string = self.read_test_file(self.processor_name, 'multiple_codeblocks.md') + + converted_test_string = markdown.markdown(test_string, extensions=extensions + [verto_extension]) + expected_string = self.read_test_file(self.processor_name, 'multiple_codeblocks_expected.html', strip=True) + self.assertEqual(expected_string, converted_test_string) + + actual_scratch_images = verto_extension.required_files['scratch_images'] + expected_scratch_images = { + ScratchImageMetaData( + hash='', + text='say [Hello] for (2) secs' + ), + ScratchImageMetaData( + hash='', + text='when flag clicked' + ), + ScratchImageMetaData( + hash='', + text='turn ccw (9) degrees' + ), + } + self.assertSetEqual(actual_scratch_images, expected_scratch_images) diff --git a/verto/tests/assets/scratch-inline/doc_example_basic_usage.md b/verto/tests/assets/scratch-inline/doc_example_basic_usage.md new file mode 100644 index 00000000..4a863585 --- /dev/null +++ b/verto/tests/assets/scratch-inline/doc_example_basic_usage.md @@ -0,0 +1 @@ +Lipsum Lorem `scratch:say [Hello] for (2) secs` ipsem. diff --git a/verto/tests/assets/scratch-inline/doc_example_basic_usage_expected.html b/verto/tests/assets/scratch-inline/doc_example_basic_usage_expected.html new file mode 100644 index 00000000..5ff4a776 --- /dev/null +++ b/verto/tests/assets/scratch-inline/doc_example_basic_usage_expected.html @@ -0,0 +1 @@ +

Lipsum Lorem ipsem.

diff --git a/verto/tests/assets/scratch-inline/doc_example_override_html.md b/verto/tests/assets/scratch-inline/doc_example_override_html.md new file mode 100644 index 00000000..548e1327 --- /dev/null +++ b/verto/tests/assets/scratch-inline/doc_example_override_html.md @@ -0,0 +1 @@ +How about some scratch: `scratch:when flag clicked` diff --git a/verto/tests/assets/scratch-inline/doc_example_override_html_expected.html b/verto/tests/assets/scratch-inline/doc_example_override_html_expected.html new file mode 100644 index 00000000..969d9740 --- /dev/null +++ b/verto/tests/assets/scratch-inline/doc_example_override_html_expected.html @@ -0,0 +1 @@ +

How about some scratch:

diff --git a/verto/tests/assets/scratch-inline/doc_example_override_html_template.html b/verto/tests/assets/scratch-inline/doc_example_override_html_template.html new file mode 100644 index 00000000..eede164d --- /dev/null +++ b/verto/tests/assets/scratch-inline/doc_example_override_html_template.html @@ -0,0 +1 @@ + diff --git a/verto/tests/assets/scratch-inline/mixed_codeblocks.md b/verto/tests/assets/scratch-inline/mixed_codeblocks.md new file mode 100644 index 00000000..55144aa3 --- /dev/null +++ b/verto/tests/assets/scratch-inline/mixed_codeblocks.md @@ -0,0 +1 @@ +How about some scratch: `scratch:say [Hello]` which is the same as the python expression: `print('Hello')` diff --git a/verto/tests/assets/scratch-inline/mixed_codeblocks_expected.html b/verto/tests/assets/scratch-inline/mixed_codeblocks_expected.html new file mode 100644 index 00000000..4f8df677 --- /dev/null +++ b/verto/tests/assets/scratch-inline/mixed_codeblocks_expected.html @@ -0,0 +1 @@ +

How about some scratch: which is the same as the python expression: print('Hello')

diff --git a/verto/tests/assets/scratch-inline/multiple_codeblocks.md b/verto/tests/assets/scratch-inline/multiple_codeblocks.md new file mode 100644 index 00000000..644f86c0 --- /dev/null +++ b/verto/tests/assets/scratch-inline/multiple_codeblocks.md @@ -0,0 +1 @@ +How about some scratch: `scratch:say [Hello] for (2) secs` which will lead into the expression `|scratch|when flag clicked` which causes the avatar to `|scratch|turn ccw (9) degrees`. diff --git a/verto/tests/assets/scratch-inline/multiple_codeblocks_expected.html b/verto/tests/assets/scratch-inline/multiple_codeblocks_expected.html new file mode 100644 index 00000000..fd486fa5 --- /dev/null +++ b/verto/tests/assets/scratch-inline/multiple_codeblocks_expected.html @@ -0,0 +1 @@ +

How about some scratch: which will lead into the expression which causes the avatar to .

diff --git a/verto/tests/start_tests.py b/verto/tests/start_tests.py index 069dd019..3e187d31 100644 --- a/verto/tests/start_tests.py +++ b/verto/tests/start_tests.py @@ -20,6 +20,7 @@ from verto.tests.RemoveTitleTest import RemoveTitleTest from verto.tests.SaveTitleTest import SaveTitleTest from verto.tests.ScratchTest import ScratchTest +from verto.tests.ScratchInlineTest import ScratchInlineTest from verto.tests.StyleTest import StyleTest from verto.tests.TableOfContentsTest import TableOfContentsTest from verto.tests.VideoTest import VideoTest @@ -77,6 +78,7 @@ def unit_suite(): unittest.makeSuite(PanelTest), unittest.makeSuite(SaveTitleTest), unittest.makeSuite(ScratchTest), + unittest.makeSuite(ScratchInlineTest), unittest.makeSuite(StyleTest), unittest.makeSuite(RelativeLinkTest), unittest.makeSuite(RemoveTest), From 3392e9f9699f0e81b39fc332ea766eb7d26dda21 Mon Sep 17 00:00:00 2001 From: ravenmaster001 Date: Mon, 22 May 2017 16:07:27 +1200 Subject: [PATCH 06/12] Inline scratch images, implementation. --- verto/Verto.py | 1 + verto/VertoExtension.py | 2 + verto/processor-info.json | 4 ++ .../processors/ScratchInlineTreeprocessor.py | 63 +++++++++++++++++++ verto/processors/ScratchTreeprocessor.py | 6 +- verto/tests/ScratchInlineTest.py | 21 ++++--- .../doc_example_basic_usage_expected.html | 2 +- .../doc_example_override_html_expected.html | 2 +- .../mixed_codeblocks_expected.html | 2 +- .../scratch-inline/multiple_codeblocks.md | 2 +- .../multiple_codeblocks_expected.html | 2 +- 11 files changed, 91 insertions(+), 16 deletions(-) create mode 100644 verto/processors/ScratchInlineTreeprocessor.py diff --git a/verto/Verto.py b/verto/Verto.py index 3cc5aa62..e72a3e0b 100644 --- a/verto/Verto.py +++ b/verto/Verto.py @@ -16,6 +16,7 @@ 'relative-link', 'save-title', 'scratch', + 'scratch-inline', 'table-of-contents', 'video' }) diff --git a/verto/VertoExtension.py b/verto/VertoExtension.py index 5774ce66..ebc14c69 100644 --- a/verto/VertoExtension.py +++ b/verto/VertoExtension.py @@ -15,6 +15,7 @@ from verto.processors.JinjaPostprocessor import JinjaPostprocessor from verto.processors.HeadingBlockProcessor import HeadingBlockProcessor from verto.processors.ScratchTreeprocessor import ScratchTreeprocessor +from verto.processors.ScratchInlineTreeprocessor import ScratchInlineTreeprocessor from verto.processors.ScratchCompatibilityPreprocessor import ScratchCompatibilityPreprocessor from verto.processors.ScratchCompatibilityPreprocessor import FENCED_BLOCK_RE_OVERRIDE from verto.processors.GenericTagBlockProcessor import GenericTagBlockProcessor @@ -185,6 +186,7 @@ def buildProcessors(self, md, md_globals): scratch_ordering = '>inline' if 'hilite' not in self.compatibility else 'inline'], ] self.postprocessors = [] self.buildGenericProcessors(md, md_globals) diff --git a/verto/processor-info.json b/verto/processor-info.json index d9066277..f16da6cc 100644 --- a/verto/processor-info.json +++ b/verto/processor-info.json @@ -232,6 +232,10 @@ "pattern": "(?P^(?:~{3,}|`{3,}))[ ]*scratch(?P(:[^:\\n$]+)*)[ ]*(hl_lines=(?P\"|')(?P.*?)(?P=quot))?[ ]*}?[ ]*\n(?P.*?)(?<=\n)(?P=fence)[ ]*$" } }, + "scratch-inline": { + "class": "custom", + "pattern": "^scratch:" + }, "style": { "class": "custom", "block_pattern": "\\{{{block} ?([^\\}}]*)\\}}", diff --git a/verto/processors/ScratchInlineTreeprocessor.py b/verto/processors/ScratchInlineTreeprocessor.py new file mode 100644 index 00000000..7cfcfd64 --- /dev/null +++ b/verto/processors/ScratchInlineTreeprocessor.py @@ -0,0 +1,63 @@ +from verto.processors.ScratchTreeprocessor import ScratchTreeprocessor +from verto.utils.HtmlParser import HtmlParser +import re + + +class ScratchInlineTreeprocessor(ScratchTreeprocessor): + ''' Searches a Document for codeblocks with the scratch language. + These are then processed into the verto result and hashed for + another program in the pipeline to retrieve or create into images. + ''' + + def __init__(self, ext, *args, **kwargs): + ''' + Args: + ext: The parent node of the element tree that children will + reside in. + ''' + super().__init__(ext, *args, **kwargs) + self.processor = 'scratch-inline' + self.pattern = re.compile(ext.processor_info[self.processor]['pattern']) + self.template = ext.jinja_templates[self.processor] + self.scratch_images = ext.required_files['scratch_images'] + self.fenced_compatibility = 'fenced_code_block' in ext.compatibility + + def run(self, root): + ''' Processes the html tree finding code tags outside pre tags + where scratch code is used and replaces with template html. + + Args: + root: The root of the document element tree. + ''' + code_elements = set() + pre_code_elements = set() + for node in root.iterfind('.//code'): + code_elements.add(node) + for node in root.iterfind('.//pre/code'): + pre_code_elements.add(node) + + for node in (code_elements - pre_code_elements): + self.process_html(node) + + def process_html(self, node): + ''' Checks if given node is a scratch code tag and replaces + with the given html template. + + Args: + node: The possible pre node of a code block. + ''' + content = node.text.strip() + match = self.pattern.match(content) + + if match is not None: + block = content[match.end():] + content_hash = self.hash_content(block) + self.update_required_images(content_hash, block) + + parser = HtmlParser() + html_string = self.template.render({'hash': content_hash}) + new_node = parser.feed(html_string).close().get_root() + + node.tag = 'remove' + node.text = '' + node.append(new_node) diff --git a/verto/processors/ScratchTreeprocessor.py b/verto/processors/ScratchTreeprocessor.py index 363b4642..a9c315e0 100644 --- a/verto/processors/ScratchTreeprocessor.py +++ b/verto/processors/ScratchTreeprocessor.py @@ -44,7 +44,11 @@ def run(self, root): Args: root: The root of the document element tree. ''' - for node in root.iter('pre'): + code_elements = [] + for node in root.iterfind('.//pre'): # A modified tree will leave the iterator undefined. + code_elements.append(node) + + for node in code_elements: self.process_html(node) if self.fenced_compatibility: diff --git a/verto/tests/ScratchInlineTest.py b/verto/tests/ScratchInlineTest.py index 4479ad4a..3b5e3256 100644 --- a/verto/tests/ScratchInlineTest.py +++ b/verto/tests/ScratchInlineTest.py @@ -3,7 +3,8 @@ from collections import defaultdict from verto.VertoExtension import VertoExtension -from verto.processors.ScratchInlineTest import ScratchInlineTest +from verto.processors.ScratchTreeprocessor import ScratchImageMetaData +from verto.processors.ScratchInlineTreeprocessor import ScratchInlineTreeprocessor from verto.tests.ProcessorTest import ProcessorTest class ScratchInlineTest(ProcessorTest): @@ -31,7 +32,7 @@ def test_doc_example_basic(self): actual_scratch_images = self.verto_extension.required_files['scratch_images'] expected_scratch_images = { ScratchImageMetaData( - hash='', + hash='3dfa73663a21d295e1e5c1e5583d8d01edd68ec53ad3050597de126076c44ea5', text='say [Hello] for (2) secs' ), } @@ -51,7 +52,7 @@ def test_doc_example_override_html(self): actual_scratch_images = verto_extension.required_files['scratch_images'] expected_scratch_images = { ScratchImageMetaData( - hash='', + hash='2f3ea223b778227287b8935bc5d209e25d3e8a25ef46ff85f6c44818159601d7', text='when flag clicked' ), } @@ -72,15 +73,15 @@ def test_multiple_codeblocks(self): actual_scratch_images = self.verto_extension.required_files['scratch_images'] expected_scratch_images = { ScratchImageMetaData( - hash='', + hash='3dfa73663a21d295e1e5c1e5583d8d01edd68ec53ad3050597de126076c44ea5', text='say [Hello] for (2) secs' ), ScratchImageMetaData( - hash='', + hash='2f3ea223b778227287b8935bc5d209e25d3e8a25ef46ff85f6c44818159601d7', text='when flag clicked' ), ScratchImageMetaData( - hash='', + hash='1c95862744e873cc87e4cadf6174257ce6e8a237b29b5c41f241e98e0d78eb14', text='turn ccw (9) degrees' ), } @@ -99,7 +100,7 @@ def test_mixed_codeblocks(self): actual_scratch_images = verto_extension.required_files['scratch_images'] expected_scratch_images = { ScratchImageMetaData( - hash='', + hash='9dabe0bac28bc3a143cfb19c2e5d7f46aae62b3d793166a56665a789d0df5bf7', text='say [Hello]' ) } @@ -119,15 +120,15 @@ def test_codeblocks_compatibility(self): actual_scratch_images = verto_extension.required_files['scratch_images'] expected_scratch_images = { ScratchImageMetaData( - hash='', + hash='3dfa73663a21d295e1e5c1e5583d8d01edd68ec53ad3050597de126076c44ea5', text='say [Hello] for (2) secs' ), ScratchImageMetaData( - hash='', + hash='2f3ea223b778227287b8935bc5d209e25d3e8a25ef46ff85f6c44818159601d7', text='when flag clicked' ), ScratchImageMetaData( - hash='', + hash='1c95862744e873cc87e4cadf6174257ce6e8a237b29b5c41f241e98e0d78eb14', text='turn ccw (9) degrees' ), } diff --git a/verto/tests/assets/scratch-inline/doc_example_basic_usage_expected.html b/verto/tests/assets/scratch-inline/doc_example_basic_usage_expected.html index 5ff4a776..09960caa 100644 --- a/verto/tests/assets/scratch-inline/doc_example_basic_usage_expected.html +++ b/verto/tests/assets/scratch-inline/doc_example_basic_usage_expected.html @@ -1 +1 @@ -

Lipsum Lorem ipsem.

+

Lipsum Lorem ipsem.

diff --git a/verto/tests/assets/scratch-inline/doc_example_override_html_expected.html b/verto/tests/assets/scratch-inline/doc_example_override_html_expected.html index 969d9740..b1146b16 100644 --- a/verto/tests/assets/scratch-inline/doc_example_override_html_expected.html +++ b/verto/tests/assets/scratch-inline/doc_example_override_html_expected.html @@ -1 +1 @@ -

How about some scratch:

+

How about some scratch:

diff --git a/verto/tests/assets/scratch-inline/mixed_codeblocks_expected.html b/verto/tests/assets/scratch-inline/mixed_codeblocks_expected.html index 4f8df677..71e4cde0 100644 --- a/verto/tests/assets/scratch-inline/mixed_codeblocks_expected.html +++ b/verto/tests/assets/scratch-inline/mixed_codeblocks_expected.html @@ -1 +1 @@ -

How about some scratch: which is the same as the python expression: print('Hello')

+

How about some scratch: which is the same as the python expression: print('Hello')

diff --git a/verto/tests/assets/scratch-inline/multiple_codeblocks.md b/verto/tests/assets/scratch-inline/multiple_codeblocks.md index 644f86c0..40c25c3a 100644 --- a/verto/tests/assets/scratch-inline/multiple_codeblocks.md +++ b/verto/tests/assets/scratch-inline/multiple_codeblocks.md @@ -1 +1 @@ -How about some scratch: `scratch:say [Hello] for (2) secs` which will lead into the expression `|scratch|when flag clicked` which causes the avatar to `|scratch|turn ccw (9) degrees`. +How about some scratch: `scratch:say [Hello] for (2) secs` which will lead into the expression `scratch:when flag clicked` which causes the avatar to `scratch:turn ccw (9) degrees`. diff --git a/verto/tests/assets/scratch-inline/multiple_codeblocks_expected.html b/verto/tests/assets/scratch-inline/multiple_codeblocks_expected.html index fd486fa5..30f7cc1f 100644 --- a/verto/tests/assets/scratch-inline/multiple_codeblocks_expected.html +++ b/verto/tests/assets/scratch-inline/multiple_codeblocks_expected.html @@ -1 +1 @@ -

How about some scratch: which will lead into the expression which causes the avatar to .

+

How about some scratch: which will lead into the expression which causes the avatar to .

From 076b2fd4381aa1b30adcc26a2a9611fa9134d1f0 Mon Sep 17 00:00:00 2001 From: ravenmaster001 Date: Mon, 22 May 2017 16:09:32 +1200 Subject: [PATCH 07/12] PR fixes, added image-inline to defaults. --- docs/source/processors/image-inline.rst | 2 +- verto/Verto.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/source/processors/image-inline.rst b/docs/source/processors/image-inline.rst index 73886744..a30fff53 100644 --- a/docs/source/processors/image-inline.rst +++ b/docs/source/processors/image-inline.rst @@ -5,7 +5,7 @@ Inline Image .. note:: - The inline image tag allows for the use of images inside tables, *etc* without causing style errors. The tag functions almost exactly the same as the ``image`` tag except for not excluding the alignment argument. + The inline image tag allows for the use of images inside tables, *etc* without causing style errors. The tag functions almost exactly the same as the ``image`` tag except for the alignment argument. You can include an inline image using the following text tag: diff --git a/verto/Verto.py b/verto/Verto.py index 3cc5aa62..3b3f8ef5 100644 --- a/verto/Verto.py +++ b/verto/Verto.py @@ -11,6 +11,7 @@ 'heading', 'iframe', 'image', + 'image-inline', 'interactive', 'panel', 'relative-link', From 3a2feeded83ab1cc8d8df2a60473a1817956825f Mon Sep 17 00:00:00 2001 From: ravenmaster001 Date: Mon, 22 May 2017 16:17:00 +1200 Subject: [PATCH 08/12] Document that html-templates must have a single root level node after rendering. --- docs/source/contributing.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/source/contributing.rst b/docs/source/contributing.rst index 45336790..d0b7b0a1 100644 --- a/docs/source/contributing.rst +++ b/docs/source/contributing.rst @@ -104,7 +104,7 @@ The items of interest are: - ``processors/`` - There is a different processor for each tag. A processor uses it's corresponding description loaded from ``processor-info.json`` to find matches in the text, and uses the given arguments in the matched tag to populate and output it's html template. -- ``html-templates/`` - The html templates (using the Jinja2 template engine) with variable arguments to be populated by processors. +- ``html-templates/`` - The html templates (using the Jinja2 template engine) with variable arguments to be populated by processors. - ``errors/`` - Contains all the errors exposed by the Verto module. Where an Error is an exception that is caused by user input. New errors should be created in here inheriting from the base ``Error`` class. @@ -141,7 +141,7 @@ There are two types of generic processors: - tags (``generic_tag``): which match ``{ }`` in the markdown text replacing with the given html-template. - containers (``generic_container``): which are a pair of tags which capture the content between the tags for the html-template. A generic container's opening tag specifies the arguments, while the closing tag only has the ``end`` argument allowing for the content to contain generic containers. -To create a new processor that uses the generic processors the processor must be added to the ``processor-info.json`` file and an associated html-template must be created. +To create a new processor that uses the generic processors the processor must be added to the ``processor-info.json`` file and an associated html-template must be created. Where the template must only have one root level node after rendering. How to make a JSON Definition ++++++++++++++++++++++++++++++++++++++ @@ -286,7 +286,7 @@ The logic for each processor belongs in the ``processors/`` directory, and there - The processor's relevant information (regex pattern, required parameters etc) should be included in ``processor-info.json``. - If it should be a default processor, it should be added to the frozenset of ``DEFAULT_PROCESSORS`` in ``Verto.py``. - The relevant list in ``extendMarkdown()`` in ``VertoExtension.py`` (see `OrderedDict in the Markdown API docs`_ for manipulating processor order). -- The processor's template should be added to ``html-templates`` using the Jinja2 template engine syntax for variable parameters. +- The processor's template should be added to ``html-templates`` using the Jinja2 template engine syntax for variable parameters. A valid template will only have one root level node after rendering. - Any errors should have appropriate classes in the ``errors\`` directory, they should be well described by their class name such that for an expert knows immediately what to do to resolve the issue, otherwise a message should be used to describe the exact causation of the error for a novice. From 3cdb6610bbf1daafc4c117a3e4fe1f98684ea573 Mon Sep 17 00:00:00 2001 From: ravenmaster001 Date: Mon, 22 May 2017 16:18:48 +1200 Subject: [PATCH 09/12] Document using remove to allow for multiple root level nodes. --- docs/source/contributing.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/source/contributing.rst b/docs/source/contributing.rst index d0b7b0a1..9f849392 100644 --- a/docs/source/contributing.rst +++ b/docs/source/contributing.rst @@ -104,7 +104,7 @@ The items of interest are: - ``processors/`` - There is a different processor for each tag. A processor uses it's corresponding description loaded from ``processor-info.json`` to find matches in the text, and uses the given arguments in the matched tag to populate and output it's html template. -- ``html-templates/`` - The html templates (using the Jinja2 template engine) with variable arguments to be populated by processors. +- ``html-templates/`` - The html templates (using the Jinja2 template engine) with variable arguments to be populated by processors. - ``errors/`` - Contains all the errors exposed by the Verto module. Where an Error is an exception that is caused by user input. New errors should be created in here inheriting from the base ``Error`` class. @@ -286,7 +286,7 @@ The logic for each processor belongs in the ``processors/`` directory, and there - The processor's relevant information (regex pattern, required parameters etc) should be included in ``processor-info.json``. - If it should be a default processor, it should be added to the frozenset of ``DEFAULT_PROCESSORS`` in ``Verto.py``. - The relevant list in ``extendMarkdown()`` in ``VertoExtension.py`` (see `OrderedDict in the Markdown API docs`_ for manipulating processor order). -- The processor's template should be added to ``html-templates`` using the Jinja2 template engine syntax for variable parameters. A valid template will only have one root level node after rendering. +- The processor's template should be added to ``html-templates`` using the Jinja2 template engine syntax for variable parameters. A valid template will only have one root level node after rendering, if more root nodes are necessary the remove tag can be used as the root node which will be removed later. - Any errors should have appropriate classes in the ``errors\`` directory, they should be well described by their class name such that for an expert knows immediately what to do to resolve the issue, otherwise a message should be used to describe the exact causation of the error for a novice. From 603fff217c33765726c0059b805c14f4035db210 Mon Sep 17 00:00:00 2001 From: ravenmaster001 Date: Mon, 22 May 2017 16:22:30 +1200 Subject: [PATCH 10/12] Fix typo in documentation 'heading_root' -> 'heading_tree'. --- docs/source/usage.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/usage.rst b/docs/source/usage.rst index b6ae536b..d69f5d6f 100644 --- a/docs/source/usage.rst +++ b/docs/source/usage.rst @@ -86,7 +86,7 @@ The following attributes are available: - See :ref:`accessing-scratch-image-data` for data from Scratch processor. -- ``heading_root`` - A tuple of namedtuples which describes the tree of headings, as generated by our heading processor. Each namedtuple contains a ``title`` (string), ``title_slug`` (string), ``level`` (integer) and ``children`` (tuple of nodes). +- ``heading_tree`` - A tuple of namedtuples which describes the tree of headings, as generated by our heading processor. Each namedtuple contains a ``title`` (string), ``title_slug`` (string), ``level`` (integer) and ``children`` (tuple of nodes). - For example the heading root after a conversion of a file: From 30a3983860c94bb704d31901486983a0460f310c Mon Sep 17 00:00:00 2001 From: ravenmaster001 Date: Mon, 22 May 2017 16:30:38 +1200 Subject: [PATCH 11/12] PR fixes. --- docs/source/contributing.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/source/contributing.rst b/docs/source/contributing.rst index 9f849392..49f390d1 100644 --- a/docs/source/contributing.rst +++ b/docs/source/contributing.rst @@ -141,7 +141,7 @@ There are two types of generic processors: - tags (``generic_tag``): which match ``{ }`` in the markdown text replacing with the given html-template. - containers (``generic_container``): which are a pair of tags which capture the content between the tags for the html-template. A generic container's opening tag specifies the arguments, while the closing tag only has the ``end`` argument allowing for the content to contain generic containers. -To create a new processor that uses the generic processors the processor must be added to the ``processor-info.json`` file and an associated html-template must be created. Where the template must only have one root level node after rendering. +To create a new processor that uses the generic processors the processor must be added to the ``processor-info.json`` file and an associated html-template must be created. The template must only have one root level node after rendering. How to make a JSON Definition ++++++++++++++++++++++++++++++++++++++ From 831481fae2f95f548f7db16d4cf52669f247b768 Mon Sep 17 00:00:00 2001 From: ravenmaster001 Date: Tue, 23 May 2017 08:38:20 +1200 Subject: [PATCH 12/12] Bump to version 0.6.0. --- docs/source/changelog.rst | 13 +++++++++++++ verto/__init__.py | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/docs/source/changelog.rst b/docs/source/changelog.rst index 00384398..c3a8d5d9 100644 --- a/docs/source/changelog.rst +++ b/docs/source/changelog.rst @@ -1,6 +1,19 @@ Changelog ####################################### +0.6.0 +======================================= + +Features: + + - Added :doc:`processors/image-inline` processor, intended for use in tables. + - Added :doc:`processors/scratch-inline` processor for inline scratch support. + +Fixes: + + - Removed ``beautifulsoup4`` dependency. + - Typo in VertoResult documentation (*heading_root* -> *heading_tree*). + 0.5.3 ======================================= diff --git a/verto/__init__.py b/verto/__init__.py index 741c4762..7e3917ef 100644 --- a/verto/__init__.py +++ b/verto/__init__.py @@ -1,4 +1,4 @@ # flake8: noqa from .Verto import Verto -__version__ = '0.5.3' +__version__ = '0.6.0'