import logging
import os
import traitlets as traits
from nbconvert.preprocessors import Preprocessor
from nbformat.notebooknode import NotebookNode
[docs]class LatexDocHTML(Preprocessor):
r""" processing of ipub metatags, specific to html
- import embedded html files
- add refmap key to references for {label:reference name} lookup
e.g. {"fig:test":"fig. 1"}
- add caption_prefix tag for floats with correct numbering/name
e.g. cell.metadata.ipub.figure.caption_prefix = "Figure 1: "
"""
metapath = traits.Unicode("", help="the path to the meta data").tag(config=True)
filesfolder = traits.Unicode("", help="the folder to point towards").tag(
config=True
)
src_name = traits.Unicode(
"src",
help=("for embedding, if reveal js slides use data-src " "(for lazy loading)"),
).tag(config=True)
@traits.validate("src_name")
def _valid_value(self, proposal):
if proposal["value"] not in ["src", "data-src"]:
raise traits.TraitError("src_name must be src or src or data-src")
return proposal["value"]
def __init__(self, *args, **kwargs):
super(LatexDocHTML, self).__init__(*args, **kwargs)
[docs] def resolve_path(self, fpath, filepath):
"""resolve a relative path, w.r.t. another filepath """
if not os.path.isabs(fpath):
fpath = os.path.join(os.path.dirname(str(filepath)), fpath)
fpath = os.path.abspath(fpath)
return fpath
[docs] def embed_html(self, cell, path):
""" a new cell, based on embedded html file
"""
logging.info("embedding html in notebook from: {}".format(path))
height = int(cell.metadata.ipub.embed_html.get("height", 0.5) * 100)
width = int(cell.metadata.ipub.embed_html.get("width", 0.5) * 100)
embed_code = (
'<iframe style="display:block; margin: 0 auto; height:{height}vh; '
'width:{width}vw; overflow:auto; resize:both" {src}="{path}" '
'frameborder="0" allowfullscreen>'
"</iframe>"
).format(src=self.src_name, path=path, height=height, width=width)
# add to the exising output or create a new one
if cell.outputs:
cell.outputs[0]["data"]["text/html"] = embed_code
else:
cell.outputs.append(
NotebookNode(
{
"data": {"text/html": embed_code},
"execution_count": 0,
"metadata": {},
"output_type": "execute_result",
}
)
)
return cell
[docs] def preprocess(self, nb, resources):
logging.info(
"processing notebook for html output"
+ " in ipub metadata to: {}".format(self.metapath)
)
final_cells = []
float_count = dict(
[("figure", 0), ("table", 0), ("code", 0), ("text", 0), ("error", 0)]
)
for i, cell in enumerate(nb.cells):
if hasattr(cell.metadata, "ipub"):
if hasattr(cell.metadata.ipub, "embed_html"):
if hasattr(cell.metadata.ipub.embed_html, "filepath"):
paths = [cell.metadata.ipub.embed_html.filepath]
if hasattr(cell.metadata.ipub.embed_html, "other_files"):
if not isinstance(
cell.metadata.ipub.embed_html.other_files, list
):
raise TypeError(
"{} should be a list".format(
cell.metadata.ipub.embed_html.other_files
)
)
paths += cell.metadata.ipub.embed_html.other_files
for j, path in enumerate(paths):
fpath = self.resolve_path(path, self.metapath)
if not os.path.exists(fpath):
logging.warning(
"file in embed html metadata doesn't exist"
": {}".format(fpath)
)
else:
resources.setdefault("external_file_paths", [])
resources["external_file_paths"].append(fpath)
if j == 0:
self.embed_html(
cell,
os.path.join(
self.filesfolder, os.path.basename(fpath)
),
)
elif hasattr(cell.metadata.ipub.embed_html, "url"):
self.embed_html(cell, cell.metadata.ipub.embed_html.url)
else:
logging.warning(
"cell {} has no filepath or url key in its "
"metadata.embed_html".format(i)
)
for floattype, floatabbr in [
("figure", "fig."),
("table", "tbl."),
("code", "code"),
("text", "text"),
("error", "error"),
]:
if floattype in cell.metadata.ipub:
if floattype != "code" and not cell.get("outputs", []):
continue
float_count[floattype] += 1
if not isinstance(cell.metadata.ipub[floattype], dict):
continue
cell.metadata.ipub[floattype][
"caption_prefix"
] = "<b>{0} {1}:</b> ".format( # noqa: E501
floattype.capitalize(), float_count[floattype]
)
if "label" in cell.metadata.ipub[floattype]:
label = "{0} {1}".format(floatabbr, float_count[floattype])
resources.setdefault("refmap", {})[
cell.metadata.ipub[floattype]["label"]
] = label
final_cells.append(cell)
nb.cells = final_cells
return nb, resources