add support for multi-page pdfs from stag
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -2,3 +2,4 @@
|
|||||||
/pack
|
/pack
|
||||||
/result
|
/result
|
||||||
/target
|
/target
|
||||||
|
/template/lib/
|
||||||
|
|||||||
18
Makefile
18
Makefile
@@ -3,14 +3,17 @@ PACKS_ROOT := $(BUILD_DIR)/pack
|
|||||||
PACKDIR := $(PACKS_ROOT)/tultemplate2
|
PACKDIR := $(PACKS_ROOT)/tultemplate2
|
||||||
BUNDLEDIR := $(PACKS_ROOT)/bundle
|
BUNDLEDIR := $(PACKS_ROOT)/bundle
|
||||||
|
|
||||||
TO_PACK := $(shell find template -type f) template/LICENSE
|
LIB_MUCHPDFTOOLS := lib.typ much_pdf_tools.wasm
|
||||||
|
LIBS := $(LIB_MUCHPDFTOOLS:%=much_pdf_tools/%)
|
||||||
|
|
||||||
|
TO_PACK := $(shell find template -type f) template/LICENSE $(LIBS:%=template/lib/%)
|
||||||
BUNDLE_THESES := bp_cs bp_en dp_cs dp_en prj_cs prj_en sp_cs sp_en
|
BUNDLE_THESES := bp_cs bp_en dp_cs dp_en prj_cs prj_en sp_cs sp_en
|
||||||
BUNDLE_TARGETS := $(TO_PACK:%=$(BUNDLEDIR)/%) $(BUNDLEDIR)/citations.bib $(BUNDLEDIR)/bp_cs.typ \
|
BUNDLE_TARGETS := $(TO_PACK:%=$(BUNDLEDIR)/%) $(BUNDLEDIR)/citations.bib $(BUNDLEDIR)/bp_cs.typ \
|
||||||
$(BUNDLE_THESES:%=$(BUNDLEDIR)/%.typ) $(BUNDLEDIR)/Makefile
|
$(BUNDLE_THESES:%=$(BUNDLEDIR)/%.typ) $(BUNDLEDIR)/Makefile
|
||||||
PACK_TARGETS := $(TO_PACK:%=$(PACKDIR)/%) $(PACKDIR)/documentation.typ \
|
PACK_TARGETS := $(TO_PACK:%=$(PACKDIR)/%) $(PACKDIR)/documentation.typ \
|
||||||
$(PACKDIR)/documentation.pdf $(PACKDIR)/citations.bib $(PACKDIR)/Makefile
|
$(PACKDIR)/documentation.pdf $(PACKDIR)/citations.bib $(PACKDIR)/Makefile
|
||||||
|
|
||||||
TEMPLATE_SRCS := $(shell find template -type f)
|
TEMPLATE_SRCS := $(shell find template -type f) $(LIBS:%=template/lib/%)
|
||||||
|
|
||||||
# == MAIN TARGETS ==
|
# == MAIN TARGETS ==
|
||||||
|
|
||||||
@@ -41,6 +44,7 @@ documentation: $(BUILD_DIR)/documentation.pdf
|
|||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean:
|
||||||
rm -rf target
|
rm -rf target
|
||||||
|
rm -rf template/lib
|
||||||
|
|
||||||
# == ROOTS ==
|
# == ROOTS ==
|
||||||
|
|
||||||
@@ -70,6 +74,16 @@ define replace_with_file_line
|
|||||||
sed "s/$(1)/$$(sed '$(3)q;d' $(2))/g"
|
sed "s/$(1)/$$(sed '$(3)q;d' $(2))/g"
|
||||||
endef
|
endef
|
||||||
|
|
||||||
|
# == LIBS ==
|
||||||
|
|
||||||
|
template/lib:
|
||||||
|
mkdir -p $@
|
||||||
|
|
||||||
|
$(LIB_MUCHPDFTOOLS:%=template/lib/much_pdf_tools/%): | template/lib
|
||||||
|
cd template/lib && wget "https://tulsablona.zumepro.cz/lib/much_pdf_tools.tar.gz" && \
|
||||||
|
tar -xvf much_pdf_tools.tar.gz && \
|
||||||
|
rm much_pdf_tools.tar.gz
|
||||||
|
|
||||||
# == DOCUMENTATION ==
|
# == DOCUMENTATION ==
|
||||||
|
|
||||||
$(BUILD_DIR)/documentation.pdf: documentation.typ $(TEMPLATE_SRCS) | $(BUILD_DIR)
|
$(BUILD_DIR)/documentation.pdf: documentation.typ $(TEMPLATE_SRCS) | $(BUILD_DIR)
|
||||||
|
|||||||
95
flake.lock
generated
95
flake.lock
generated
@@ -1,12 +1,81 @@
|
|||||||
{
|
{
|
||||||
"nodes": {
|
"nodes": {
|
||||||
|
"flake-parts": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs-lib": "nixpkgs-lib"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1743550720,
|
||||||
|
"narHash": "sha256-hIshGgKZCgWh6AYJpJmRgFdR3WUbkY04o82X05xqQiY=",
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"rev": "c621e8422220273271f52058f618c94e405bb0f5",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"much_pdf_tools": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-parts": "flake-parts",
|
||||||
|
"nixpkgs": "nixpkgs",
|
||||||
|
"systems": "systems"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1764192868,
|
||||||
|
"narHash": "sha256-0h4Fqg3C+VMS2+gvJUKKEjJJDWEeRcMCFkXerl9kPc0=",
|
||||||
|
"ref": "refs/heads/master",
|
||||||
|
"rev": "bf65c77e3b0e02b6f22bd20840277c603cd9c2bf",
|
||||||
|
"revCount": 1,
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://git.zumepro.cz/ondrej.mekina/much_pdf_tools.git"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://git.zumepro.cz/ondrej.mekina/much_pdf_tools.git"
|
||||||
|
}
|
||||||
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1762482733,
|
"lastModified": 1745804731,
|
||||||
"narHash": "sha256-g/da4FzvckvbiZT075Sb1/YDNDr+tGQgh4N8i5ceYMg=",
|
"narHash": "sha256-v/sK3AS0QKu/Tu5sHIfddiEHCvrbNYPv8X10Fpux68g=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "e1ebeec86b771e9d387dd02d82ffdc77ac753abc",
|
"rev": "29335f23bea5e34228349ea739f31ee79e267b88",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixpkgs-unstable",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs-lib": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1743296961,
|
||||||
|
"narHash": "sha256-b1EdN3cULCqtorQ4QeWgLMrd5ZGOjLSLemfa00heasc=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "nixpkgs.lib",
|
||||||
|
"rev": "e4822aea2a6d1cdd36653c134cacfd64c97ff4fa",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "nixpkgs.lib",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixpkgs_2": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1764138170,
|
||||||
|
"narHash": "sha256-2bCmfCUZyi2yj9FFXYKwsDiaZmizN75cLhI/eWmf3tk=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "bb813de6d2241bcb1b5af2d3059f560c66329967",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
@@ -18,7 +87,8 @@
|
|||||||
},
|
},
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": "nixpkgs",
|
"much_pdf_tools": "much_pdf_tools",
|
||||||
|
"nixpkgs": "nixpkgs_2",
|
||||||
"utils": "utils"
|
"utils": "utils"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -37,9 +107,24 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"systems_2": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"utils": {
|
"utils": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"systems": "systems"
|
"systems": "systems_2"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1731533236,
|
"lastModified": 1731533236,
|
||||||
|
|||||||
35
flake.nix
35
flake.nix
@@ -2,16 +2,24 @@
|
|||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable";
|
||||||
utils.url = "github:numtide/flake-utils";
|
utils.url = "github:numtide/flake-utils";
|
||||||
|
much_pdf_tools.url = "git+https://git.zumepro.cz/ondrej.mekina/much_pdf_tools.git";
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = { self, nixpkgs, utils }:
|
outputs = { self, nixpkgs, utils, much_pdf_tools }:
|
||||||
utils.lib.eachDefaultSystem (system:
|
utils.lib.eachDefaultSystem (system:
|
||||||
let
|
let
|
||||||
pkgs = import nixpkgs { inherit system; };
|
pkgs = import nixpkgs { inherit system; };
|
||||||
buildInputs = with pkgs; [ typst gnumake jq xdg-utils zip ];
|
buildInputs = with pkgs; [ typst gnumake jq xdg-utils zip wget ];
|
||||||
name = "tultemplate2";
|
name = "tultemplate2";
|
||||||
envSetup = ''
|
envSetup = ''
|
||||||
unset SOURCE_DATE_EPOCH
|
unset SOURCE_DATE_EPOCH
|
||||||
|
LIB=template/lib
|
||||||
|
if [ ! -e $LIB ]; then mkdir $LIB; fi
|
||||||
|
if [ ! -e $LIB/much_pdf_tools ]
|
||||||
|
then
|
||||||
|
cp -R ${much_pdf_tools.packages.${system}.much_pdf_tools} $LIB/much_pdf_tools
|
||||||
|
chmod +w $LIB/much_pdf_tools
|
||||||
|
fi
|
||||||
'';
|
'';
|
||||||
build_with_target = target: buildOutput: pkgs.stdenv.mkDerivation {
|
build_with_target = target: buildOutput: pkgs.stdenv.mkDerivation {
|
||||||
inherit buildInputs target buildOutput;
|
inherit buildInputs target buildOutput;
|
||||||
@@ -33,29 +41,6 @@
|
|||||||
inherit buildInputs;
|
inherit buildInputs;
|
||||||
shellHook = envSetup;
|
shellHook = envSetup;
|
||||||
};
|
};
|
||||||
} // (
|
|
||||||
with pkgs;
|
|
||||||
let
|
|
||||||
merge = buildInputs: name: stdenv.mkDerivation {
|
|
||||||
inherit name buildInputs;
|
|
||||||
dontUnpack = true;
|
|
||||||
installPhase = ''
|
|
||||||
mkdir $out
|
|
||||||
for input in $buildInputs
|
|
||||||
do
|
|
||||||
cp -R $input/. $out
|
|
||||||
done
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
documentation = build "documentation.pdf";
|
|
||||||
in
|
|
||||||
{
|
|
||||||
packages.documentation = documentation;
|
|
||||||
packages.default = merge [documentation] name;
|
|
||||||
packages.pack = build_with_target "pack" (builtins.map (v: "target/pack/" + v) [
|
|
||||||
"tultemplate2" "tultemplate2.zip"
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,99 +1,6 @@
|
|||||||
#let generate_jumptable(pat) = {
|
|
||||||
let jt = ();
|
|
||||||
let matched = 0;
|
|
||||||
for (idx, item) in pat.enumerate() {
|
|
||||||
jt.push(matched);
|
|
||||||
if idx != 0 and item == pat.at(matched) {
|
|
||||||
matched += 1;
|
|
||||||
} else {
|
|
||||||
matched = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
jt
|
|
||||||
}
|
|
||||||
|
|
||||||
#let advance(pat, jt, ptr, cur) = {
|
|
||||||
if ptr >= pat.len() {
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
if pat.at(ptr) == cur {
|
|
||||||
ptr + 1
|
|
||||||
} else {
|
|
||||||
if ptr == 0 {
|
|
||||||
0
|
|
||||||
} else {
|
|
||||||
advance(pat, jt, jt.at(ptr), cur)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#let find(pat, jt, haystack, start_from: 0) = {
|
|
||||||
let ptr = 0;
|
|
||||||
for idx in range(start_from, haystack.len()) {
|
|
||||||
let item = haystack.at(idx);
|
|
||||||
ptr = advance(pat, jt, ptr, item);
|
|
||||||
if ptr >= pat.len() {
|
|
||||||
return idx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
none
|
|
||||||
}
|
|
||||||
|
|
||||||
#let match(pat, haystack, start_at) = {
|
|
||||||
if start_at + pat.len() > haystack.len() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
for idx in range(start_at, start_at + pat.len()) {
|
|
||||||
if haystack.at(idx) != pat.at(idx - start_at) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
#let number_of_pages(haystack) = {
|
|
||||||
let pat_type = (47, 84, 121, 112, 101); // "/Type"
|
|
||||||
let pat_page = (47, 80, 97, 103, 101); // "/Page"
|
|
||||||
let space = 32; // " "
|
|
||||||
let ascii_chars = (
|
|
||||||
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, 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
|
|
||||||
);
|
|
||||||
let jt_type = generate_jumptable(pat_type);
|
|
||||||
|
|
||||||
let skip_spaces(haystack, start_at) = {
|
|
||||||
for idx in range(start_at, haystack.len()) {
|
|
||||||
let item = haystack.at(idx);
|
|
||||||
if item != space {
|
|
||||||
return idx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
none
|
|
||||||
}
|
|
||||||
|
|
||||||
let res = 0;
|
|
||||||
let ptr = 0;
|
|
||||||
while ptr < haystack.len() and type(ptr) != type(none) {
|
|
||||||
ptr = find(pat_type, jt_type, haystack, start_from: ptr);
|
|
||||||
if type(ptr) == type(none) { break; }
|
|
||||||
// Matched: "/Type"
|
|
||||||
ptr = skip_spaces(haystack, ptr + 1);
|
|
||||||
if type(ptr) == type(none) { break; }
|
|
||||||
// Matched: "/Type", spaces
|
|
||||||
if not match(pat_page, haystack, ptr) { continue; }
|
|
||||||
ptr += pat_page.len();
|
|
||||||
// Matched: "/Type", spaces, "/Page"
|
|
||||||
if haystack.at(ptr) in ascii_chars { continue; }
|
|
||||||
// Matched: "/Type", spaces, "/Page", word_end
|
|
||||||
res += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
res
|
|
||||||
}
|
|
||||||
|
|
||||||
#let embed_full(src) = {
|
#let embed_full(src) = {
|
||||||
let page_count = number_of_pages(src);
|
import "./lib/much_pdf_tools/lib.typ": pdf_count_pages;
|
||||||
|
let page_count = pdf_count_pages(src);
|
||||||
for idx in range(0, page_count) {
|
for idx in range(0, page_count) {
|
||||||
page(
|
page(
|
||||||
place(center + horizon, image(src, page: idx + 1, fit: "contain", width: auto, height: auto)),
|
place(center + horizon, image(src, page: idx + 1, fit: "contain", width: auto, height: auto)),
|
||||||
|
|||||||
Reference in New Issue
Block a user