epub-generator 0.0.2__py3-none-any.whl → 0.0.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- epub_generator/context.py +5 -4
- epub_generator/data/container.xml.jinja +6 -0
- epub_generator/data/content.opf.jinja +66 -0
- epub_generator/data/cover.xhtml.jinja +15 -0
- epub_generator/data/mimetype.jinja +1 -0
- epub_generator/data/part.xhtml.jinja +22 -0
- epub_generator/data/style.css.jinja +56 -0
- epub_generator/data/toc.ncx.jinja +28 -0
- epub_generator/gen_part.py +6 -3
- epub_generator/template.py +4 -4
- {epub_generator-0.0.2.dist-info → epub_generator-0.0.3.dist-info}/METADATA +1 -1
- epub_generator-0.0.3.dist-info/RECORD +21 -0
- epub_generator-0.0.2.dist-info/RECORD +0 -14
- {epub_generator-0.0.2.dist-info → epub_generator-0.0.3.dist-info}/LICENSE +0 -0
- {epub_generator-0.0.2.dist-info → epub_generator-0.0.3.dist-info}/WHEEL +0 -0
epub_generator/context.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
|
+
from typing import cast
|
|
2
3
|
from zipfile import ZipFile
|
|
3
4
|
from importlib.resources import files
|
|
4
5
|
from jinja2 import Environment, Template as JinjaTemplate
|
|
@@ -74,16 +75,16 @@ class Context:
|
|
|
74
75
|
|
|
75
76
|
class Template:
|
|
76
77
|
def __init__(self):
|
|
77
|
-
templates_path = files("
|
|
78
|
+
templates_path = cast(Path, files("epub_generator")) / "data"
|
|
78
79
|
self._env: Environment = create_env(templates_path)
|
|
79
80
|
self._templates: dict[str, JinjaTemplate] = {}
|
|
80
81
|
|
|
81
82
|
def render(self, template: str, **params) -> str:
|
|
82
|
-
|
|
83
|
-
return
|
|
83
|
+
jinja_template: JinjaTemplate = self._template(template)
|
|
84
|
+
return jinja_template.render(**params)
|
|
84
85
|
|
|
85
86
|
def _template(self, name: str) -> JinjaTemplate:
|
|
86
|
-
template
|
|
87
|
+
template = self._templates.get(name, None)
|
|
87
88
|
if template is None:
|
|
88
89
|
template = self._env.get_template(name)
|
|
89
90
|
self._templates[name] = template
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<package version="2.0" xmlns="http://www.idpf.org/2007/opf" unique-identifier="uid">
|
|
3
|
+
<metadata xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:opf="http://www.idpf.org/2007/opf">
|
|
4
|
+
<dc:language>zh</dc:language>
|
|
5
|
+
<dc:identifier id="uid">{{ ISBN }}</dc:identifier>
|
|
6
|
+
{% if "title" in meta %}
|
|
7
|
+
<dc:title>{{ meta["title"] }}</dc:title>
|
|
8
|
+
{% else %}
|
|
9
|
+
<dc:title>{{ i18n.unnamed }}</dc:title>
|
|
10
|
+
{% endif %}
|
|
11
|
+
{% if "description" in meta %}
|
|
12
|
+
<dc:description>{{ meta["description"] }}</dc:description>
|
|
13
|
+
{% endif %}
|
|
14
|
+
{% if "publisher" in meta %}
|
|
15
|
+
<dc:publisher>{{ meta["publisher"] }}</dc:publisher>
|
|
16
|
+
{% endif %}
|
|
17
|
+
{% if "authors" in meta %}
|
|
18
|
+
{% for author in meta["authors"] %}
|
|
19
|
+
<dc:creator opf:role="aut">{{ author }}</dc:creator>
|
|
20
|
+
{% endfor %}
|
|
21
|
+
{% endif %}
|
|
22
|
+
{% if "editors" in meta %}
|
|
23
|
+
{% for editor in meta["editors"] %}
|
|
24
|
+
<dc:creator opf:role="edt">{{ editor }}</dc:creator>
|
|
25
|
+
{% endfor %}
|
|
26
|
+
{% endif %}
|
|
27
|
+
{% if "translators" in meta %}
|
|
28
|
+
{% for translator in meta["translators"] %}
|
|
29
|
+
<dc:creator opf:role="trl">{{ translator }}</dc:creator>
|
|
30
|
+
{% endfor %}
|
|
31
|
+
{% endif %}
|
|
32
|
+
{% if has_cover %}
|
|
33
|
+
<meta name="cover" content="a_cover" />
|
|
34
|
+
{% endif %}
|
|
35
|
+
<meta name="output encoding" content="utf-8" />
|
|
36
|
+
<meta name="primary-writing-mode" content="horizontal-lr" />
|
|
37
|
+
</metadata>
|
|
38
|
+
<manifest>
|
|
39
|
+
<item id="a_css" media-type="text/css" href="styles/style.css" />
|
|
40
|
+
{% for asset_file, media_type in asset_files %}
|
|
41
|
+
<item id="a_{{ asset_file|safe }}" media-type="{{ media_type|safe }}" href="assets/{{ asset_file|safe }}" />
|
|
42
|
+
{% endfor%}
|
|
43
|
+
{% if has_cover %}
|
|
44
|
+
<item id="a_cover" media-type="image/png" href="assets/cover.png" />
|
|
45
|
+
<item id="x_cover.xhtml" media-type="application/xhtml+xml" href="Text/cover.xhtml" />
|
|
46
|
+
{% endif %}
|
|
47
|
+
{% if has_head_chapter %}
|
|
48
|
+
<item id="x_head.xhtml" media-type="application/xhtml+xml" href="Text/head.xhtml" />
|
|
49
|
+
{% endif %}
|
|
50
|
+
{% for nav_point in nav_points %}
|
|
51
|
+
<item id="x_{{ nav_point.file_name|safe }}" media-type="application/xhtml+xml" href="Text/{{ nav_point.file_name|safe }}" />
|
|
52
|
+
{% endfor %}
|
|
53
|
+
<item id="ncx" media-type="application/x-dtbncx+xml" href="toc.ncx" />
|
|
54
|
+
</manifest>
|
|
55
|
+
<spine toc="ncx">
|
|
56
|
+
{% if has_cover %}
|
|
57
|
+
<itemref idref="x_cover.xhtml" linear="no" />
|
|
58
|
+
{% endif %}
|
|
59
|
+
{% if has_head_chapter %}
|
|
60
|
+
<itemref idref="x_head.xhtml" />
|
|
61
|
+
{% endif %}
|
|
62
|
+
{% for nav_point in nav_points %}
|
|
63
|
+
<itemref idref="x_{{ nav_point.file_name|safe }}" />
|
|
64
|
+
{% endfor %}
|
|
65
|
+
</spine>
|
|
66
|
+
</package>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
|
2
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
|
3
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="zh">
|
|
4
|
+
|
|
5
|
+
<head>
|
|
6
|
+
<title>{{ i18n.cover }}</title>
|
|
7
|
+
</head>
|
|
8
|
+
|
|
9
|
+
<body>
|
|
10
|
+
<p>
|
|
11
|
+
<img src="../assets/cover.png" alt="Cover" />
|
|
12
|
+
</p>
|
|
13
|
+
</body>
|
|
14
|
+
|
|
15
|
+
</html>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
application/epub+zip
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="utf-8" standalone="no"?>
|
|
2
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
|
3
|
+
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
4
|
+
|
|
5
|
+
<head>
|
|
6
|
+
<title></title>
|
|
7
|
+
<link href="../styles/style.css" rel="stylesheet" type="text/css"/>
|
|
8
|
+
</head>
|
|
9
|
+
|
|
10
|
+
<body>
|
|
11
|
+
{% for item in content %}
|
|
12
|
+
{{ item|safe }}
|
|
13
|
+
{% endfor %}
|
|
14
|
+
{% if citations %}
|
|
15
|
+
<h2>{{ i18n.references }}</h2>
|
|
16
|
+
{% for item in citations %}
|
|
17
|
+
{{ item|safe }}
|
|
18
|
+
{% endfor %}
|
|
19
|
+
{% endif %}
|
|
20
|
+
</body>
|
|
21
|
+
|
|
22
|
+
</html>
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
blockquote {
|
|
2
|
+
border-left: 0.15em solid #c7c7c7;
|
|
3
|
+
margin: 0.75em;
|
|
4
|
+
padding: 1em;
|
|
5
|
+
text-indent:2em;
|
|
6
|
+
line-height:1.5em;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
a.super {
|
|
10
|
+
font-size: 0.75em;
|
|
11
|
+
vertical-align: super;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
a.citation {
|
|
15
|
+
font-size: 0.75em;
|
|
16
|
+
font-weight: bold;
|
|
17
|
+
vertical-align: super;
|
|
18
|
+
padding-right: 0.55em;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
div.citation {
|
|
22
|
+
margin-top: 0.5em;
|
|
23
|
+
margin-left: 0.75em;
|
|
24
|
+
margin-bottom: 1.5em;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
div.alt-wrapper {
|
|
28
|
+
display: flex;
|
|
29
|
+
flex-direction: column;
|
|
30
|
+
align-items: center;
|
|
31
|
+
padding-top: 0.8em;
|
|
32
|
+
padding-bottom: 3em;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
div.alt-wrapper table {
|
|
36
|
+
width: 100%;
|
|
37
|
+
table-layout: fixed;
|
|
38
|
+
border-collapse: collapse;
|
|
39
|
+
border-spacing: 0;
|
|
40
|
+
margin: 0;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
div.alt-wrapper th,
|
|
44
|
+
.alt-wrapper td {
|
|
45
|
+
padding: 8px 12px;
|
|
46
|
+
border: 1px solid #e1e4e8;
|
|
47
|
+
text-align: left;
|
|
48
|
+
font-size: 14px;
|
|
49
|
+
line-height: 1.5;
|
|
50
|
+
word-wrap: break-word;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
div.alt-wrapper th {
|
|
54
|
+
background-color: #f6f8fa;
|
|
55
|
+
font-weight: 600;
|
|
56
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<?xml version='1.0' encoding='utf-8'?>
|
|
2
|
+
<ncx xmlns="http://www.daisy.org/z3986/2005/ncx/" version="2005-1" xml:lang="zh">
|
|
3
|
+
<head>
|
|
4
|
+
<meta content="{{ depth }}" name="dtb:depth" />
|
|
5
|
+
<meta content="0" name="dtb:totalPageCount" />
|
|
6
|
+
<meta content="0" name="dtb:maxPageNumber" />
|
|
7
|
+
</head>
|
|
8
|
+
<docTitle>
|
|
9
|
+
{% if "title" in meta %}
|
|
10
|
+
<text>{{ meta["title"] }}</text>
|
|
11
|
+
{% else %}
|
|
12
|
+
<text>{{ i18n.unnamed }}</text>
|
|
13
|
+
{% endif %}
|
|
14
|
+
</docTitle>
|
|
15
|
+
<navMap>
|
|
16
|
+
{% if has_cover %}
|
|
17
|
+
<navPoint id="cover" playOrder="1">
|
|
18
|
+
<navLabel>
|
|
19
|
+
<text>{{ i18n.cover }}</text>
|
|
20
|
+
</navLabel>
|
|
21
|
+
<content src="Text/cover.xhtml" />
|
|
22
|
+
</navPoint>
|
|
23
|
+
{% endif %}
|
|
24
|
+
{% for nav_point in nav_points %}
|
|
25
|
+
{{ nav_point|safe }}
|
|
26
|
+
{% endfor %}
|
|
27
|
+
</navMap>
|
|
28
|
+
</ncx>
|
epub_generator/gen_part.py
CHANGED
|
@@ -57,7 +57,7 @@ def _render_footnotes(context: Context, chapter_element: Element):
|
|
|
57
57
|
if not found_mark or len(citation_div) == 0:
|
|
58
58
|
continue
|
|
59
59
|
|
|
60
|
-
footnote_id = int(footnote.get("id"))
|
|
60
|
+
footnote_id = int(footnote.get("id", "-1"))
|
|
61
61
|
ref = Element("a")
|
|
62
62
|
ref.text = f"[{footnote_id}]"
|
|
63
63
|
ref.attrib = {
|
|
@@ -86,7 +86,7 @@ def _render_layout(context: Context, raw_layout: Element) -> Element | None:
|
|
|
86
86
|
layout.text = raw_layout.text
|
|
87
87
|
for mark in raw_layout:
|
|
88
88
|
assert mark.tag == "mark"
|
|
89
|
-
mark_id = int(mark.get("id"))
|
|
89
|
+
mark_id = int(mark.get("id", ""))
|
|
90
90
|
anchor = Element("a")
|
|
91
91
|
anchor.attrib = {
|
|
92
92
|
"id": f"ref-{mark_id}",
|
|
@@ -109,7 +109,10 @@ def _render_layout(context: Context, raw_layout: Element) -> Element | None:
|
|
|
109
109
|
"class": "alt-wrapper",
|
|
110
110
|
})
|
|
111
111
|
if raw_layout.tag == "table":
|
|
112
|
-
|
|
112
|
+
table_children = try_gen_table(context, raw_layout)
|
|
113
|
+
assert table_children is not None
|
|
114
|
+
asset_wrapper.extend(table_children)
|
|
115
|
+
|
|
113
116
|
elif raw_layout.tag == "formula":
|
|
114
117
|
formula = try_gen_formula(context, raw_layout)
|
|
115
118
|
if formula is not None:
|
epub_generator/template.py
CHANGED
|
@@ -2,13 +2,13 @@ import re
|
|
|
2
2
|
|
|
3
3
|
from typing import Tuple, Callable
|
|
4
4
|
from pathlib import Path
|
|
5
|
-
from jinja2 import
|
|
5
|
+
from jinja2 import Environment, BaseLoader, TemplateNotFound
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
def create_env(dir_path: Path) -> Environment:
|
|
9
9
|
return Environment(
|
|
10
10
|
loader=_DSLoader(dir_path),
|
|
11
|
-
autoescape=
|
|
11
|
+
autoescape=True,
|
|
12
12
|
trim_blocks=True,
|
|
13
13
|
keep_trailing_newline=True,
|
|
14
14
|
)
|
|
@@ -20,7 +20,7 @@ class _DSLoader(BaseLoader):
|
|
|
20
20
|
super().__init__()
|
|
21
21
|
self._dir_path: Path = dir_path
|
|
22
22
|
|
|
23
|
-
def get_source(self,
|
|
23
|
+
def get_source(self, environment: Environment, template: str) -> _LoaderResult:
|
|
24
24
|
template = self._norm_template(template)
|
|
25
25
|
target_path = (self._dir_path / template).resolve()
|
|
26
26
|
|
|
@@ -47,4 +47,4 @@ class _DSLoader(BaseLoader):
|
|
|
47
47
|
def is_updated() -> bool:
|
|
48
48
|
return mtime == path.stat().st_mtime
|
|
49
49
|
|
|
50
|
-
return source, path, is_updated
|
|
50
|
+
return source, str(path), is_updated
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
epub_generator/__init__.py,sha256=BTAVO_YqMdArhQQQN1aNsXIiPATpqZzb6OWVuAQyoNI,160
|
|
2
|
+
epub_generator/context.py,sha256=921e7xh4V0ZYfI-8mqgrCKWxnFOgNCU-bXuTZLG5x9A,2650
|
|
3
|
+
epub_generator/data/container.xml.jinja,sha256=SkACyZgsAVUS5lmiCEhq3SpbFspYdyCnRNjWnLztLt0,252
|
|
4
|
+
epub_generator/data/content.opf.jinja,sha256=ZoYduOZeUbN2-I2aLfmv4vxkDMpbY9KhJZrLk5FPTjE,2453
|
|
5
|
+
epub_generator/data/cover.xhtml.jinja,sha256=U4Jevq_pN2-qTol0tej9dI9gX819sLEtAUdiXTmQ4jk,332
|
|
6
|
+
epub_generator/data/mimetype.jinja,sha256=5GjjUNEUPrZI9gx7C9YDEQHsBUSjYcp07O8laskB9Is,20
|
|
7
|
+
epub_generator/data/part.xhtml.jinja,sha256=HVpXl08TTFrr0IwxNvIz0JpV-0Izt-BKPV5Dlrf9JFA,517
|
|
8
|
+
epub_generator/data/style.css.jinja,sha256=j4jAC3dtCviEilFMy0JolqAOVoFb6GfPJnoGxzyuNIs,882
|
|
9
|
+
epub_generator/data/toc.ncx.jinja,sha256=4GPmbKLYK9LTRyCwTfpujBR12T0borOOWvhdCtxRHiM,753
|
|
10
|
+
epub_generator/gen_asset.py,sha256=52K92RWzioRka2uzU94s1gnL0BqcaFmPrOsKgC77_Nc,3567
|
|
11
|
+
epub_generator/gen_epub.py,sha256=Dvi6AsnQbQ3uOU0fcXfazTM3g9U1mnccWM68VIuJq10,4834
|
|
12
|
+
epub_generator/gen_index.py,sha256=Cp0Lmx7nGFn6e_VzJR92gyuFTk4Z2cBezO4FwvJT0HE,4455
|
|
13
|
+
epub_generator/gen_part.py,sha256=KwCe09DzO5XMhxyX2tDRrS9KnXozLm7rb_cl5LY5m_A,3408
|
|
14
|
+
epub_generator/hash.py,sha256=EUIrpST9vAvSy8-kfPeBqemUfYyNXbZXF90fS1I355E,138
|
|
15
|
+
epub_generator/i18n.py,sha256=zGpM4TpESqMPr57f-WsUlK1UDo3wTdAL6H5o9OhQ6xc,349
|
|
16
|
+
epub_generator/template.py,sha256=ALtmf7Ib9aBprZtOrFKcBStJmpjtnEO5a0bu2h_Hj5Q,1441
|
|
17
|
+
epub_generator/types.py,sha256=zSd6SOytrcjzuOGuRYa49TcnSvGRJmGXO3e7_Im_t9k,170
|
|
18
|
+
epub_generator-0.0.3.dist-info/LICENSE,sha256=9Zt_a4mrzkvR2rc0UbqTgbboIjWuumDFgeQyKos0H2E,1066
|
|
19
|
+
epub_generator-0.0.3.dist-info/METADATA,sha256=TkmxCGJ5NHiLTaJNMlSORboq3-e8aoOVkYC3P0pnQhY,596
|
|
20
|
+
epub_generator-0.0.3.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
21
|
+
epub_generator-0.0.3.dist-info/RECORD,,
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
epub_generator/__init__.py,sha256=BTAVO_YqMdArhQQQN1aNsXIiPATpqZzb6OWVuAQyoNI,160
|
|
2
|
-
epub_generator/context.py,sha256=hWauz9eza6b_k0zgjZSA9hhSqYMiRAQ2cZ8H6BIA34k,2626
|
|
3
|
-
epub_generator/gen_asset.py,sha256=52K92RWzioRka2uzU94s1gnL0BqcaFmPrOsKgC77_Nc,3567
|
|
4
|
-
epub_generator/gen_epub.py,sha256=Dvi6AsnQbQ3uOU0fcXfazTM3g9U1mnccWM68VIuJq10,4834
|
|
5
|
-
epub_generator/gen_index.py,sha256=Cp0Lmx7nGFn6e_VzJR92gyuFTk4Z2cBezO4FwvJT0HE,4455
|
|
6
|
-
epub_generator/gen_part.py,sha256=t9XZIqzJdtdxnFZqPGvJpVWqT68jTZNSaQ9T973NEFo,3319
|
|
7
|
-
epub_generator/hash.py,sha256=EUIrpST9vAvSy8-kfPeBqemUfYyNXbZXF90fS1I355E,138
|
|
8
|
-
epub_generator/i18n.py,sha256=zGpM4TpESqMPr57f-WsUlK1UDo3wTdAL6H5o9OhQ6xc,349
|
|
9
|
-
epub_generator/template.py,sha256=GdV3QnypProKFCMH1kBNfdt6wiShygP_-xGnE5EOUwU,1460
|
|
10
|
-
epub_generator/types.py,sha256=zSd6SOytrcjzuOGuRYa49TcnSvGRJmGXO3e7_Im_t9k,170
|
|
11
|
-
epub_generator-0.0.2.dist-info/LICENSE,sha256=9Zt_a4mrzkvR2rc0UbqTgbboIjWuumDFgeQyKos0H2E,1066
|
|
12
|
-
epub_generator-0.0.2.dist-info/METADATA,sha256=M0cRhViBEBLL69xE5L5-XZYrjyxrWADL0NvkWQEJlgg,596
|
|
13
|
-
epub_generator-0.0.2.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
|
14
|
-
epub_generator-0.0.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|