-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathentry.mu
More file actions
executable file
·160 lines (133 loc) · 5.28 KB
/
Copy pathentry.mu
File metadata and controls
executable file
·160 lines (133 loc) · 5.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#!/bin/python3
import os
import settings
import theme
import archives
import cache
from formatting import common, wikipedia, generic, gutenberg
rf = settings.root_folder
page = f"/page/{rf}" if rf else "/page"
names = archives.available_names()
zim = os.environ.get("var_zim") or (names[0] if names else None)
entry_path = os.environ.get("var_entry_path", "")
chunk = os.environ.get("var_chunk")
fmt = os.environ.get("var_format")
kind = archives.archive_type(zim) if zim else "generic"
if kind == "gutenberg" and entry_path:
entry_path = gutenberg.book_path(entry_path)
def dump_raw(text):
for line in text.split("\n"):
print(common.guard(common.esc(line)))
def resolve_entry():
archive = archives.open_archive(zim)
entry = archive.get_entry_by_path(entry_path)
if entry.is_redirect:
entry = entry.get_redirect_entry()
return entry.title, entry.get_item()
def render_micron(item, path):
validator = f"{item.size}-{common.RENDER_VERSION}"
micron = cache.get(zim, path, validator)
if micron is None:
html = bytes(item.content).decode("utf-8", "replace")
if kind == "wikipedia":
micron = wikipedia.html_to_micron(html, zim=zim, entry_path=path)
elif kind == "gutenberg":
micron = gutenberg.html_to_micron(html, zim=zim, entry_path=path)
else:
micron = generic.html_to_micron(html, zim=zim, entry_path=path)
cache.put(zim, path, validator, micron)
return micron
if fmt in ("micron", "html") and zim and entry_path:
try:
title, item = resolve_entry()
path = item.path
if not item.mimetype.startswith("text/html"):
print("This entry is not a readable text document.")
elif fmt == "html":
dump_raw(bytes(item.content).decode("utf-8", "replace"))
else:
dump_raw(render_micron(item, path))
except KeyError:
print("Can't find entry")
except FileNotFoundError:
print("Archive not found")
raise SystemExit
import template
print(template.render_header(zim))
if not zim:
print("No archive selected.")
print(f"`F{theme.LINK}`_`[Choose an archive`:{page}/index.mu]`_`f")
raise SystemExit
if not entry_path:
print(f">{archives.load_meta(zim).get('title', zim)}")
print("Use the search field above to find an entry.")
raise SystemExit
def nav_line(idx, total, base):
parts = []
if idx > 1:
parts.append(f"`F{theme.NAV}`_`[◀ Prev`:{page}/entry.mu`{base}|chunk={idx - 1}]`_`f")
parts.append(f"`F{theme.NAV}`_`[Parts`:{page}/entry.mu`{base}|chunk=parts]`_`f")
parts.append(f"`F{theme.NAV}`_`[Full`:{page}/entry.mu`{base}]`_`f")
if idx < total:
parts.append(f"`F{theme.NAV}`_`[Next ▶`:{page}/entry.mu`{base}|chunk={idx + 1}]`_`f")
return "`c" + " · ".join(parts) + "`a"
try:
title, item = resolve_entry()
entry_path = item.path
base = f"zim={zim}|entry_path={entry_path}"
if kind in ("pdf", "video"):
print(f">{title}")
print(f"This entry is a {kind} document and cannot be displayed in a text browser.")
raise SystemExit
if not item.mimetype.startswith("text/html"):
print(f">{title}")
print("This entry is not a readable text document.")
raise SystemExit
micron = render_micron(item, entry_path)
size_str = common.human_size(common.byte_size(micron))
chunks = common.chunk_micron(micron, getattr(settings, "chunk_size", 4096))
total = len(chunks)
plural = "part" if total == 1 else "parts"
print(f">{title}")
if chunk is None:
actions = [f"`Faaa{size_str}`f"]
if total > 1:
actions.append(f"`F{theme.NAV}`_`[⇊ {total} parts`:{page}/entry.mu`{base}|chunk=parts]`_`f")
actions.append(f"`F{theme.NAV}`_`[⤓ Micron {size_str}`:{page}/entry.mu`{base}|format=micron]`_`f")
actions.append(f"`F{theme.NAV}`_`[⤓ HTML {common.human_size(item.size)}`:{page}/entry.mu`{base}|format=html]`_`f")
print("`c" + " · ".join(actions) + "`a")
print("-─")
print(micron)
elif chunk == "parts":
sections = {}
for level, sec_title, ci in common.section_index(chunks):
sections.setdefault(ci, []).append(sec_title)
print(f"`Faaa{size_str} of readable text · {total} {plural}`f")
print(f"`F{theme.NAV}`_`[Read full entry`:{page}/entry.mu`{base}]`_`f")
print("")
print("Select a part to read:")
print("")
for i, piece in enumerate(chunks, start=1):
here = sections.get(i) or (["Introduction"] if i == 1 else [])
desc = ", ".join(here[:3])
label = f"Part {i} — {common.human_size(common.byte_size(piece))}"
line = f"• `F{theme.NAV}`_`[{label}`:{page}/entry.mu`{base}|chunk={i}]`_`f"
if desc:
line += f" `Faaa{desc}`f"
print(line)
else:
try:
idx = max(1, min(int(chunk), total))
except ValueError:
idx = 1
nav = nav_line(idx, total, base)
print(f"`c`Faaapart {idx}/{total} · {size_str} total`f`a")
print(nav)
print("-─")
print(chunks[idx - 1])
print("-─")
print(nav)
except KeyError:
print("Can't find entry")
except FileNotFoundError:
print("Archive not found")