Skip to content

Commit

Permalink
Add a kpm_iframe directive to docs and its example usage
Browse files Browse the repository at this point in the history
  • Loading branch information
mszalkowski-ant committed Sep 17, 2024
1 parent e259c5e commit 0eb51a4
Show file tree
Hide file tree
Showing 5 changed files with 173 additions and 2 deletions.
116 changes: 116 additions & 0 deletions docs/source/_extensions/kpm_plugin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
from __future__ import annotations

from typing import Optional
from urllib.parse import urlencode

from docutils import nodes
from docutils.parsers.rst.directives import path
from sphinx.addnodes import download_reference
from sphinx.application import Sphinx
from sphinx.util.docutils import SphinxDirective
from sphinx.util.typing import ExtensionMetadata
from sphinx.writers.html5 import HTML5Translator
from sphinx.writers.latex import LaTeXTranslator

KPM_PATH = "_static/kpm/index.html"


class KPMNode(nodes.container):
def __init__(
self,
depth: int,
preview: bool,
spec_ref: Optional[str],
graph_ref: Optional[str],
height: Optional[str],
) -> None:
# we're leveraging the builtin download_reference node
# to automatically move necessary files from sources
# into the build directory and have a path to them
spec_node = graph_node = None
if spec_ref:
spec_node = download_reference("", "", reftarget=spec_ref, disabled=True)
if graph_ref:
graph_node = download_reference("", "", reftarget=graph_ref, disabled=True)

super().__init__("", *(node for node in (spec_node, graph_node) if node))
self.spec_node = spec_node
self.graph_node = graph_node
self.rel_pfx = "../" * depth
self.preview = preview
self.height = height

def _node_to_target(self, node: download_reference) -> str:
if "filename" in node:
return "relative://../../_downloads/" + node["filename"]
elif "refuri" in node:
return node["refuri"]

raise ValueError("The KPM file path is neither a valid file nor a URL")

@staticmethod
def visit_html(trans: HTML5Translator, node: KPMNode):
params = {}
if node.spec_node:
params["spec"] = node._node_to_target(node.spec_node)
if node.graph_node:
params["graph"] = node._node_to_target(node.graph_node)
if node.preview:
params["preview"] = str(node.preview).lower()

trans.body.append(
f"""
<iframe src='{node.rel_pfx}{KPM_PATH}?{urlencode(params)}'
allow='fullscreen'
style='
width:100%;
{"height:" + node.height if node.height else "aspect-ratio:3/2"};
border:none;
'
></iframe>"""
)

@staticmethod
def visit_latex(trans: LaTeXTranslator, _: KPMNode):
trans.body.append(
r"""
\begin{sphinxadmonition}{warning}{Note:}
\sphinxAtStartPar
An interactive KPM frame, where you can explore the block design for this section,
is available here in the HTML version of this documentation.
\end{sphinxadmonition}"""
)

@staticmethod
def depart_node(*_):
pass


class KPMDirective(SphinxDirective):
option_spec = {"spec": path, "dataflow": path, "preview": bool, "height": str}

def run(self) -> list[nodes.Node]:
return [
KPMNode(
self.env.docname.count("/"),
self.options.get("preview", False),
self.options.get("spec"),
self.options.get("dataflow"),
self.options.get("height"),
)
]


def setup(app: Sphinx) -> ExtensionMetadata:
app.add_node(
KPMNode,
html=(KPMNode.visit_html, KPMNode.depart_node),
latex=(KPMNode.visit_latex, KPMNode.depart_node),
)
app.add_directive("kpm_iframe", KPMDirective)

return {
"version": "0.1",
"parallel_read_safe": True,
"parallel_write_safe": True,
}
6 changes: 4 additions & 2 deletions docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@

from datetime import datetime
from os import environ
import os
import sys

from antmicro_sphinx_utils.defaults import antmicro_html, antmicro_latex
from antmicro_sphinx_utils.defaults import extensions as default_extensions
Expand All @@ -29,7 +31,7 @@
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.'))
sys.path.insert(0, os.path.abspath('./_extensions'))

# -- General configuration -----------------------------------------------------

Expand All @@ -51,7 +53,7 @@

# If you need to add extensions just add to those lists
extensions = list(set(default_extensions + [
'sphinx.ext.autodoc',
'sphinx.ext.autodoc', 'kpm_plugin'
]))
myst_enable_extensions = default_myst_enable_extensions
myst_fence_as_directive = default_myst_fence_as_directive
Expand Down
43 changes: 43 additions & 0 deletions docs/source/developers_guide/inline_kpm_howto.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Using KPM iframes inside docs

It is possible to use the `kpm_iframe` Sphinx directive to embed KPM directly inside a doc.

## Usage

````
```{kpm_iframe}
:spec: <KPM specification .json file URI>
:dataflow: <KPM dataflow .json file URI>
:preview: <a boolean value specifying whether this KPM should be started in preview mode>
:height: <a string css height property that sets the `height` of iframe>
```
````

`URI` can represent either a local file from sources that gets copied into the build directory, or a remote resource.

All parameters of this directive are optional.


## Tests

### Use remote specification

```{kpm_iframe}
:spec: https://raw.githubusercontent.com/antmicro/topwrap/main/tests/data/data_kpm/examples/hdmi/specification_hdmi.json
```

### Use local files

```{kpm_iframe}
:spec: ../../../tests/data/data_kpm/examples/hierarchy/specification_hierarchy.json
:dataflow: ../../../tests/data/data_kpm/examples/hierarchy/dataflow_hierarchy.json
:height: 80vh
```

### Open in preview mode

```{kpm_iframe}
:spec: ../../../tests/data/data_kpm/examples/hierarchy/specification_hierarchy.json
:dataflow: ../../../tests/data/data_kpm/examples/hierarchy/dataflow_hierarchy.json
:preview: true
```
1 change: 1 addition & 0 deletions docs/source/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@ developers_guide/config
developers_guide/parsing
developers_guide/examples
developers_guide/future_enhancements
developers_guide/inline_kpm_howto
```
9 changes: 9 additions & 0 deletions noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,15 @@ def doc_gen(session: nox.Session) -> None:
session.install(".[docs]")
session.run("make", "-C", "docs", "html", external=True)
session.run("make", "-C", "docs", "latexpdf", external=True)
session.run(
"pipeline_manager",
"build",
"static-html",
"--output-directory",
"docs/build/html/_static/kpm",
"--workspace-directory",
"docs/build/kpm",
)
session.run("cp", "docs/build/latex/topwrap.pdf", "docs/build/html", external=True)


Expand Down

0 comments on commit 0eb51a4

Please sign in to comment.