chrisjsewell / ipypublish
1 3
import logging
2 3
import os
3

4 3
import traitlets as traits
5 3
from nbconvert.preprocessors import Preprocessor
6 3
from nbformat.notebooknode import NotebookNode
7

8

9 3
class LatexDocHTML(Preprocessor):
10
    r""" processing of ipub metatags, specific to html
11

12
    - import embedded html files
13
    - add refmap key to references for {label:reference name} lookup
14
      e.g. {"fig:test":"fig. 1"}
15
    - add caption_prefix tag for floats with correct numbering/name
16
      e.g. cell.metadata.ipub.figure.caption_prefix = "Figure 1: "
17

18
    """
19

20 3
    metapath = traits.Unicode("", help="the path to the meta data").tag(config=True)
21 3
    filesfolder = traits.Unicode("", help="the folder to point towards").tag(
22
        config=True
23
    )
24 3
    src_name = traits.Unicode(
25
        "src",
26
        help=("for embedding, if reveal js slides use data-src " "(for lazy loading)"),
27
    ).tag(config=True)
28

29 3
    @traits.validate("src_name")
30 3
    def _valid_value(self, proposal):
31 3
        if proposal["value"] not in ["src", "data-src"]:
32 0
            raise traits.TraitError("src_name must be src or src or data-src")
33 3
        return proposal["value"]
34

35 3
    def __init__(self, *args, **kwargs):
36 3
        super(LatexDocHTML, self).__init__(*args, **kwargs)
37

38 3
    def resolve_path(self, fpath, filepath):
39
        """resolve a relative path, w.r.t. another filepath """
40 0
        if not os.path.isabs(fpath):
41 0
            fpath = os.path.join(os.path.dirname(str(filepath)), fpath)
42 0
            fpath = os.path.abspath(fpath)
43 0
        return fpath
44

45 3
    def embed_html(self, cell, path):
46
        """ a new cell, based on embedded html file
47
        """
48 0
        logging.info("embedding html in notebook from: {}".format(path))
49

50 0
        height = int(cell.metadata.ipub.embed_html.get("height", 0.5) * 100)
51 0
        width = int(cell.metadata.ipub.embed_html.get("width", 0.5) * 100)
52 0
        embed_code = (
53
            '<iframe style="display:block; margin: 0 auto; height:{height}vh; '
54
            'width:{width}vw; overflow:auto; resize:both" {src}="{path}" '
55
            'frameborder="0" allowfullscreen>'
56
            "</iframe>"
57
        ).format(src=self.src_name, path=path, height=height, width=width)
58

59
        # add to the exising output or create a new one
60 0
        if cell.outputs:
61 0
            cell.outputs[0]["data"]["text/html"] = embed_code
62
        else:
63 0
            cell.outputs.append(
64
                NotebookNode(
65
                    {
66
                        "data": {"text/html": embed_code},
67
                        "execution_count": 0,
68
                        "metadata": {},
69
                        "output_type": "execute_result",
70
                    }
71
                )
72
            )
73

74 0
        return cell
75

76 3
    def preprocess(self, nb, resources):
77

78 3
        logging.info(
79
            "processing notebook for html output"
80
            + " in ipub metadata to: {}".format(self.metapath)
81
        )
82

83 3
        final_cells = []
84 3
        float_count = dict(
85
            [("figure", 0), ("table", 0), ("code", 0), ("text", 0), ("error", 0)]
86
        )
87 3
        for i, cell in enumerate(nb.cells):
88 3
            if hasattr(cell.metadata, "ipub"):
89 3
                if hasattr(cell.metadata.ipub, "embed_html"):
90 0
                    if hasattr(cell.metadata.ipub.embed_html, "filepath"):
91 0
                        paths = [cell.metadata.ipub.embed_html.filepath]
92 0
                        if hasattr(cell.metadata.ipub.embed_html, "other_files"):
93 0
                            if not isinstance(
94
                                cell.metadata.ipub.embed_html.other_files, list
95
                            ):
96 0
                                raise TypeError(
97
                                    "{} should be a list".format(
98
                                        cell.metadata.ipub.embed_html.other_files
99
                                    )
100
                                )
101 0
                            paths += cell.metadata.ipub.embed_html.other_files
102 0
                        for j, path in enumerate(paths):
103 0
                            fpath = self.resolve_path(path, self.metapath)
104 0
                            if not os.path.exists(fpath):
105 0
                                logging.warning(
106
                                    "file in embed html metadata doesn't exist"
107
                                    ": {}".format(fpath)
108
                                )
109
                            else:
110 0
                                resources.setdefault("external_file_paths", [])
111 0
                                resources["external_file_paths"].append(fpath)
112 0
                                if j == 0:
113 0
                                    self.embed_html(
114
                                        cell,
115
                                        os.path.join(
116
                                            self.filesfolder, os.path.basename(fpath)
117
                                        ),
118
                                    )
119

120 0
                    elif hasattr(cell.metadata.ipub.embed_html, "url"):
121 0
                        self.embed_html(cell, cell.metadata.ipub.embed_html.url)
122
                    else:
123 0
                        logging.warning(
124
                            "cell {} has no filepath or url key in its "
125
                            "metadata.embed_html".format(i)
126
                        )
127

128 3
                for floattype, floatabbr in [
129
                    ("figure", "fig."),
130
                    ("table", "tbl."),
131
                    ("code", "code"),
132
                    ("text", "text"),
133
                    ("error", "error"),
134
                ]:
135 3
                    if floattype in cell.metadata.ipub:
136 3
                        if floattype != "code" and not cell.get("outputs", []):
137 3
                            continue
138 3
                        float_count[floattype] += 1
139 3
                        if not isinstance(cell.metadata.ipub[floattype], dict):
140 3
                            continue
141 3
                        cell.metadata.ipub[floattype][
142
                            "caption_prefix"
143
                        ] = "<b>{0} {1}:</b> ".format(  # noqa: E501
144
                            floattype.capitalize(), float_count[floattype]
145
                        )
146 3
                        if "label" in cell.metadata.ipub[floattype]:
147 3
                            label = "{0} {1}".format(floatabbr, float_count[floattype])
148 3
                            resources.setdefault("refmap", {})[
149
                                cell.metadata.ipub[floattype]["label"]
150
                            ] = label
151

152 3
            final_cells.append(cell)
153 3
        nb.cells = final_cells
154

155 3
        return nb, resources

Read our documentation on viewing source code .

Loading