Skip to content

Commit

Permalink
Introduce render_markdown.
Browse files Browse the repository at this point in the history
Closes #62
  • Loading branch information
daavoo committed Jul 7, 2022
1 parent e589110 commit 4669ca1
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 4 deletions.
5 changes: 5 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ packages = find:
[options.extras_require]
table =
tabulate>=0.8.7
markdown =
%(table)s
matplotlib
docs =
mkdocs==1.3.0
mkdocs-gen-files==0.3.4
Expand All @@ -36,6 +39,7 @@ docs =
mkdocstrings-python==0.7.0
tests =
%(table)s
%(markdown)s
funcy>=1.17
pytest==7.1.2
pytest-sugar==0.9.4
Expand All @@ -46,6 +50,7 @@ tests =
pytest-test-utils>=0.0.6
dev =
%(table)s
%(markdown)s
%(tests)s
%(docs)s

Expand Down
7 changes: 7 additions & 0 deletions src/dvc_render/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,9 @@
class DvcRenderException(Exception):
pass


class MissingPlaceholderError(DvcRenderException):
def __init__(self, placeholder, template_type):
super().__init__(
f"{template_type} template has to contain '{placeholder}'."
)
5 changes: 1 addition & 4 deletions src/dvc_render/html.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from pathlib import Path
from typing import TYPE_CHECKING, Dict, List, Optional
from typing import TYPE_CHECKING, List, Optional

from .exceptions import DvcRenderException

Expand Down Expand Up @@ -81,7 +81,6 @@ def embed(self) -> str:
def render_html(
renderers: List["Renderer"],
output_file: "StrPath",
metrics: Optional[Dict[str, Dict]] = None,
template_path: Optional["StrPath"] = None,
refresh_seconds: Optional[int] = None,
) -> "StrPath":
Expand All @@ -95,8 +94,6 @@ def render_html(
page_html = fobj.read()

document = HTML(page_html, refresh_seconds=refresh_seconds)
if metrics:
document.with_element("<br>")

for renderer in renderers:
document.with_scripts(renderer.SCRIPTS)
Expand Down
73 changes: 73 additions & 0 deletions src/dvc_render/markdown.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
from pathlib import Path
from typing import TYPE_CHECKING, List, Optional

from .exceptions import MissingPlaceholderError

if TYPE_CHECKING:
from .base import Renderer, StrPath


PAGE_MARKDOWN = """# DVC Report
{renderers}
"""


class Markdown:
RENDERERS_PLACEHOLDER = "renderers"
RENDERERS_PLACEHOLDER_FORMAT_STR = f"{{{RENDERERS_PLACEHOLDER}}}"

def __init__(
self,
template: Optional[str] = None,
):
template = template or PAGE_MARKDOWN
if self.RENDERERS_PLACEHOLDER_FORMAT_STR not in template:
raise MissingPlaceholderError(
self.RENDERERS_PLACEHOLDER_FORMAT_STR, "Markdown"
)

self.template = template
self.elements: List[str] = []

def with_element(self, md: str) -> "Markdown":
"Adds custom markdown element."
self.elements.append(md)
return self

def embed(self) -> str:
"Format Markdown template with all elements."
kwargs = {
self.RENDERERS_PLACEHOLDER: "\n".join(self.elements),
}
for placeholder, value in kwargs.items():
self.template = self.template.replace(
"{" + placeholder + "}", value
)
return self.template


def render_markdown(
renderers: List["Renderer"],
output_file: "StrPath",
template_path: Optional["StrPath"] = None,
) -> "StrPath":
"User renderers to fill an Markdown template and write to path."
output_path = Path(output_file)
output_path.parent.mkdir(exist_ok=True)

page = None
if template_path:
with open(template_path, encoding="utf-8") as fobj:
page = fobj.read()

document = Markdown(page)

for renderer in renderers:
document.with_element(
renderer.generate_markdown(output_path=output_path)
)

output_path.write_text(document.embed(), encoding="utf8")

return output_file
46 changes: 46 additions & 0 deletions tests/test_markdown.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import pytest

from dvc_render.markdown import (
PAGE_MARKDOWN,
Markdown,
MissingPlaceholderError,
)

# pylint: disable=missing-function-docstring, R0801


CUSTOM_PAGE_MARKDOWN = """# CUSTOM REPORT
{renderers}
"""


@pytest.mark.parametrize(
"template,page_elements,expected_page",
[
(
None,
["content"],
PAGE_MARKDOWN.replace("{renderers}", "content"),
),
(
CUSTOM_PAGE_MARKDOWN,
["content"],
CUSTOM_PAGE_MARKDOWN.format(renderers="content"),
),
],
)
def test_html(template, page_elements, expected_page):
page = Markdown(template)
page.elements = page_elements

result = page.embed()

assert result == expected_page


def test_no_placeholder():
template = "# Missing Placeholder"

with pytest.raises(MissingPlaceholderError):
Markdown(template)

0 comments on commit 4669ca1

Please sign in to comment.