Skip to content

Commit

Permalink
feat: Try to extract per-part PDF files
Browse files Browse the repository at this point in the history
  • Loading branch information
vEnhance committed Jul 31, 2024
1 parent c68a859 commit ef8c46a
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 15 deletions.
18 changes: 12 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ jobs:
uses: awalsh128/cache-apt-pkgs-action@latest
with:
packages: |
latexmk asymptote ghostscript
latexmk asymptote ghostscript qpdf
- name: Restore cache
uses: actions/cache/restore@v4
Expand Down Expand Up @@ -107,18 +107,24 @@ jobs:
- name: Extract table of contents
run: |
python3 print-toc.py --parts --chapters --numbers > toc.txt
- name: Extract per-part PDF's
run: |
python3 print-toc.py --qpdf | bash
- name: Create dist folder
run: |
mkdir -p dist
mkdir -p dist/asy
mkdir -p dist/figures
mkdir -p dist/cuts/
cp Napkin.log dist/
cp Napkin.pdf dist/
cp asy/*.asy dist/asy/
cp asy/*.pdf dist/asy/
cp asy/*.asy dist/figures/
cp asy/*.pdf dist/figures/
cp flowchart.png dist/
cp toc.txt dist/
mv flowchart.png dist/
mv toc.txt dist/
mv part-*.pdf dist/cuts
cd dist
tree -H '.' -I "index.html" -D --charset utf-8 --filesfirst -T "An Infinitely Large Napkin" >index.html
Expand Down
87 changes: 78 additions & 9 deletions print-toc.py
Original file line number Diff line number Diff line change
@@ -1,41 +1,110 @@
#!/usr/bin/env python3

import argparse
import re

parser = argparse.ArgumentParser("print-toc.py")
parser.add_argument(
"-q", "--qpdf", action="store_true", help="Instead produce commands for QPDF."
)
parser.add_argument("-p", "--parts", action="store_true", help="Show the parts.")
parser.add_argument("-c", "--chapters", action="store_true", help="Show the chapters.")
parser.add_argument(
"-n", "--numbers", action="store_true", help="Include page numbers."
)
parser.add_argument(
"-l", "--links", action="store_true", help="Markdown hyperlinks for per-part links."
)

opts = parser.parse_args()
if not (opts.parts or opts.chapters):
parser.error("Need to specify at least one of -p/--parts and -c/--chapters")

part_chunk = r"\contentsline {part}{\numberline {"
ch_chunk = r"\contentsline {chapter}{\numberline {"

# only used for qpdf
last_page_number = 1
last_part_number = 0
last_part_title = "Frontmatter"


def slugify(s: str) -> str:
words = s.split(" ")[:3]
return "-".join(re.sub(r"[^a-z0-9 ]+", "", word.lower()) for word in words)


def get_filename(part_number: int, part_title: str) -> str:
return f"part-{part_number:02d}-napkin-{slugify(part_title)}.pdf"


def get_qpdf_invocation(
start_page: int,
end_page: int | None,
part_number: int,
part_title: str,
) -> str:
return (
r"qpdf Napkin.pdf --pages . "
f"{start_page}-{end_page if end_page is not None else 'r1'} "
f"-- {get_filename(part_number, part_title)}"
)


if opts.links:
filename = get_filename(last_part_number, last_part_title)
print(f"- [{last_part_title}](https://venhance.github.io/napkin/cuts/{filename})")


has_started = False
with open("Napkin.toc") as f:
for line in f:
if line.startswith(part_chunk) and opts.parts:
if line.startswith(part_chunk):
part_number, part_title, *junk = line.strip()[len(part_chunk) :].split("}")
assert junk[0].startswith("{")
page_number = junk[0][1:]
if has_started is True and opts.chapters:
page_number = int(junk[0][1:])
if has_started is True and opts.chapters and not opts.qpdf:
print()
else:
has_started = True
print(f"{part_number+'.':<6} {part_title}")
if opts.qpdf:
print(
get_qpdf_invocation(
last_page_number,
page_number - 1,
last_part_number,
last_part_title,
)
)
last_part_title = part_title
last_part_number += 1
last_page_number = page_number
if opts.links:
filename = get_filename(last_part_number, part_title)
print(
f"- {part_number}. "
f"[{part_title}](https://venhance.github.io/napkin/cuts/{filename})"
)

elif opts.parts:
print(f"{part_number+'.':<6} {part_title}")
if line.startswith(ch_chunk) and opts.chapters:
ch_number, ch_title, *junk = line.strip()[len(ch_chunk) :].split("}")
assert junk[0].startswith("{")
page_number = junk[0][1:]
page_number = int(junk[0][1:])
if ch_number.isdigit():
s = " " * 2 if opts.parts else ""
s += f"{ch_number}. {ch_title}"
if opts.numbers is True:
s += "." * max(72 - len(s) - len(page_number), 3)
s += page_number
s += "." * max(72 - len(s) - len(str(page_number)), 3)
s += str(page_number)
print(s)


if opts.qpdf:
print(
get_qpdf_invocation(
last_page_number,
None,
last_part_number,
last_part_title,
)
)

0 comments on commit ef8c46a

Please sign in to comment.