]> Git — Sourcephile - julm/books.git/commitdiff
init main
authorJulien Moutinho <julm@sourcephile.fr>
Thu, 6 Feb 2025 20:53:46 +0000 (21:53 +0100)
committerJulien Moutinho <julm+books@sourcephile.fr>
Fri, 7 Feb 2025 01:33:30 +0000 (02:33 +0100)
.envrc [new file with mode: 0644]
calibre/.gitattributes [new file with mode: 0644]
calibre/J. K. Rowling/Harry Potter and the Philosopher's Stone (484)/Harry Potter and the Philosopher's Stone - J. K. Rowling.epub [new file with mode: 0644]
calibre/J. K. Rowling/Harry Potter and the Philosopher's Stone (484)/filter [new file with mode: 0755]
flake.lock [new file with mode: 0644]
flake.nix [new file with mode: 0644]
scripts/epub2pdf.sh [new file with mode: 0755]
scripts/styles/epub.header.tex [new file with mode: 0644]

diff --git a/.envrc b/.envrc
new file mode 100644 (file)
index 0000000..3550a30
--- /dev/null
+++ b/.envrc
@@ -0,0 +1 @@
+use flake
diff --git a/calibre/.gitattributes b/calibre/.gitattributes
new file mode 100644 (file)
index 0000000..a3e2527
--- /dev/null
@@ -0,0 +1,2 @@
+*.epub filter=git-crypt diff=git-crypt
+*.pdf  filter=git-crypt diff=git-crypt
diff --git a/calibre/J. K. Rowling/Harry Potter and the Philosopher's Stone (484)/Harry Potter and the Philosopher's Stone - J. K. Rowling.epub b/calibre/J. K. Rowling/Harry Potter and the Philosopher's Stone (484)/Harry Potter and the Philosopher's Stone - J. K. Rowling.epub
new file mode 100644 (file)
index 0000000..cd7a1a2
Binary files /dev/null and b/calibre/J. K. Rowling/Harry Potter and the Philosopher's Stone (484)/Harry Potter and the Philosopher's Stone - J. K. Rowling.epub differ
diff --git a/calibre/J. K. Rowling/Harry Potter and the Philosopher's Stone (484)/filter b/calibre/J. K. Rowling/Harry Potter and the Philosopher's Stone (484)/filter
new file mode 100755 (executable)
index 0000000..da9a464
--- /dev/null
@@ -0,0 +1,42 @@
+#!/usr/bin/env nix
+#! nix shell --impure --expr ``
+#! nix with (builtins.getFlake "git+file://${toString ./../..}/..").packages.${builtins.currentSystem};
+#! nix [
+#! nix   (haskellPackages.ghcWithPackages (
+#! nix     haskellPackages: [
+#! nix       haskellPackages.pandoc-types
+#! nix     ]
+#! nix   ))
+#! nix ]
+#! nix ``
+#! nix --command runhaskell
+
+{-#LANGUAGE OverloadedStrings#-}
+{-#LANGUAGE ViewPatterns #-}
+import Text.Pandoc.JSON
+import Data.List qualified as List
+import Data.Text qualified as Text
+
+main :: IO ()
+main = toJSONFilter filt
+
+filt :: Block -> Block
+-- Put chapter images into the chapter
+filt (Div as@(_, ["Section1"], _) es) = Div as (fixChapterImage es)
+-- Remove useless images
+filt (Para (Image _ _ ("Images/philos0.jpg", _):_)) = Para []
+filt x = x
+
+fixChapterImage (p@(Para
+        [ Span
+            ( _ , _ , _ )
+            (Image ( _ , _ , _ ) _ ( Text.isPrefixOf "Images/Chapter" -> True , _ )
+            :_)
+        ])
+   :h@Header{}
+   :xs
+   ) = h:p:xs
+fixChapterImage (x:xs) = x:fixChapterImage xs
+fixChapterImage [] = []
+
+-- vim: syntax=haskell
diff --git a/flake.lock b/flake.lock
new file mode 100644 (file)
index 0000000..3f81ec3
--- /dev/null
@@ -0,0 +1,87 @@
+{
+  "nodes": {
+    "flake-compat": {
+      "flake": false,
+      "locked": {
+        "lastModified": 1696426674,
+        "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=",
+        "owner": "edolstra",
+        "repo": "flake-compat",
+        "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33",
+        "type": "github"
+      },
+      "original": {
+        "owner": "edolstra",
+        "repo": "flake-compat",
+        "type": "github"
+      }
+    },
+    "gitignore": {
+      "inputs": {
+        "nixpkgs": [
+          "pre-commit-hooks",
+          "nixpkgs"
+        ]
+      },
+      "locked": {
+        "lastModified": 1709087332,
+        "narHash": "sha256-HG2cCnktfHsKV0s4XW83gU3F57gaTljL9KNSuG6bnQs=",
+        "owner": "hercules-ci",
+        "repo": "gitignore.nix",
+        "rev": "637db329424fd7e46cf4185293b9cc8c88c95394",
+        "type": "github"
+      },
+      "original": {
+        "owner": "hercules-ci",
+        "repo": "gitignore.nix",
+        "type": "github"
+      }
+    },
+    "nixpkgs": {
+      "locked": {
+        "lastModified": 1734323986,
+        "narHash": "sha256-m/lh6hYMIWDYHCAsn81CDAiXoT3gmxXI9J987W5tZrE=",
+        "owner": "NixOS",
+        "repo": "nixpkgs",
+        "rev": "394571358ce82dff7411395829aa6a3aad45b907",
+        "type": "github"
+      },
+      "original": {
+        "owner": "NixOS",
+        "ref": "nixos-24.11",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    },
+    "pre-commit-hooks": {
+      "inputs": {
+        "flake-compat": "flake-compat",
+        "gitignore": "gitignore",
+        "nixpkgs": [
+          "nixpkgs"
+        ]
+      },
+      "locked": {
+        "lastModified": 1737465171,
+        "narHash": "sha256-R10v2hoJRLq8jcL4syVFag7nIGE7m13qO48wRIukWNg=",
+        "owner": "cachix",
+        "repo": "pre-commit-hooks.nix",
+        "rev": "9364dc02281ce2d37a1f55b6e51f7c0f65a75f17",
+        "type": "github"
+      },
+      "original": {
+        "owner": "cachix",
+        "repo": "pre-commit-hooks.nix",
+        "type": "github"
+      }
+    },
+    "root": {
+      "inputs": {
+        "nixpkgs": "nixpkgs",
+        "pre-commit-hooks": "pre-commit-hooks"
+      }
+    }
+  },
+  "root": "root",
+  "version": 7
+}
diff --git a/flake.nix b/flake.nix
new file mode 100644 (file)
index 0000000..9b92b7c
--- /dev/null
+++ b/flake.nix
@@ -0,0 +1,61 @@
+{
+  description = "books";
+  inputs = {
+    nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11";
+    pre-commit-hooks.inputs.nixpkgs.follows = "nixpkgs";
+    pre-commit-hooks.url = "github:cachix/pre-commit-hooks.nix";
+  };
+
+  outputs =
+    inputs:
+    let
+      inherit (inputs.nixpkgs) lib;
+      forAllSystems =
+        f:
+        lib.genAttrs lib.systems.flakeExposed (
+          system:
+          f rec {
+            inherit system;
+            pkgs = inputs.nixpkgs.legacyPackages.${system};
+          }
+        );
+    in
+    {
+      # nix -L build .#hello
+      packages = forAllSystems ({ pkgs, ... }: pkgs);
+
+      # nix -L develop  or  direnv allow
+      devShell = forAllSystems (
+        {
+          pkgs,
+          system,
+          ...
+        }:
+        pkgs.mkShell {
+          name = "shell";
+          src = null;
+          buildInputs = [
+            pkgs.fontconfig
+            #pkgs.gitFull
+            pkgs.jq
+            pkgs.pandoc
+            pkgs.reuse
+            pkgs.shellcheck
+          ];
+          inherit (inputs.self.checks.${system}.pre-commit-check) shellHook;
+        }
+      );
+
+      # nix flake check
+      checks = forAllSystems (
+        args: with args; {
+          pre-commit-check = inputs.pre-commit-hooks.lib.${system}.run {
+            src = inputs.self;
+            hooks = {
+              nixfmt-rfc-style.enable = true;
+            };
+          };
+        }
+      );
+    };
+}
diff --git a/scripts/epub2pdf.sh b/scripts/epub2pdf.sh
new file mode 100755 (executable)
index 0000000..c84c3c5
--- /dev/null
@@ -0,0 +1,124 @@
+#!/usr/bin/env nix
+#! nix shell --impure --expr ``
+#! nix with (builtins.getFlake "git+file://${toString ./.}/..").packages.${builtins.currentSystem};
+#! nix let fonts = [
+#! nix   pkgs.comic-mono
+#! nix   pkgs.crimson
+#! nix   pkgs.dejavu_fonts
+#! nix   pkgs.fira-code
+#! nix   pkgs.freefont_ttf
+#! nix   pkgs.gyre-fonts # TrueType substitutes for standard PostScript fonts
+#! nix   pkgs.hack-font
+#! nix   pkgs.liberation_ttf
+#! nix   pkgs.lmodern
+#! nix   pkgs.noto-fonts-emoji
+#! nix   pkgs.tex-gyre.adventor
+#! nix   pkgs.tex-gyre.bonum
+#! nix   pkgs.tex-gyre.chorus
+#! nix   pkgs.tex-gyre.cursor
+#! nix   pkgs.tex-gyre.heros
+#! nix   pkgs.tex-gyre.pagella
+#! nix   pkgs.tex-gyre.schola
+#! nix   pkgs.tex-gyre.termes
+#! nix   pkgs.unifont
+#! nix ]; in
+#! nix [
+#! nix    (pkgs.writeShellScriptBin "interpreter" ''
+#! nix      # used by luaotfload (lualatex)
+#! nix      export OSFONTDIR="${lib.concatStringsSep "//:" (map toString fonts)}"
+#! nix      exec bash "$@"
+#! nix    '')
+#! nix     pandoc
+#! nix     pdftk
+#! nix     qpdf
+#! nix     (pkgs.texlive.combine {
+#! nix       inherit (pkgs.texlive)
+#! nix         collection-fontsrecommended
+#! nix         collection-langenglish
+#! nix         collection-langfrench
+#! nix         collection-latexrecommended
+#! nix         collection-luatex
+#! nix         pdfbook2
+#! nix         pdfcrop
+#! nix         pdfjam
+#! nix         scheme-basic
+#! nix         tex-gyre
+#! nix         ;
+#! nix     })
+#! nix ]
+#! nix ``
+#! nix --command interpreter
+
+epubPath=$1
+epubDir=$(realpath -e "$(dirname "$epubPath")")
+styleDir=$(realpath -e "$(dirname "$0")")/styles
+outDir=$epubDir/pdf
+pdfFile="$outDir"/out.pdf
+rm -rf "$outDir"
+mkdir -p "$outDir"
+
+# Converting EPUB to PDF
+set -eux
+pandoc \
+  --embed-resources \
+  --include-in-header "$styleDir"/epub.header.tex \
+  --filter "$epubDir"/filter \
+  --number-sections \
+  --pdf-engine lualatex \
+  --standalone \
+  --toc \
+  --toc-depth 6 \
+  --top-level-division chapter \
+  -V documentclass=scrbook \
+  -V classoption=english \
+  -V mainfont="TeX Gyre Termes" \
+  -V fontsize=13pt \
+  -V papersize=a5 \
+  -i "$epubPath" \
+  -t pdf \
+  -o "$pdfFile"
+
+# Slicing on chapters and splitting into chunks of at most 18 pages (for easy binding)
+  mkdir -p "$outDir"/sections
+  pdftk "$pdfFile" dump_data | grep '^BookmarkPageNumber:' |
+  {
+    sectionNum=1
+    sectionBegin=1
+    splitSection () {
+      qpdf \
+        "$pdfFile" \
+        "$outDir"/sections/sectionNum="$sectionNum".pages="$sectionPages".chunk=%d.pdf \
+        --pages "$pdfFile" "$sectionPages" -- \
+        --split-pages=18
+    }
+    while read -r _BookmarkPageNumber sectionEnd; do
+      test "$sectionEnd" != 1 || continue
+      sectionPages=$sectionBegin-$((sectionEnd-1))
+      splitSection
+      sectionNum=$((sectionNum+1))
+      sectionBegin=$sectionEnd
+    done
+    sectionPages="$sectionBegin"-r1
+    splitSection
+  }
+
+# Converting to booklet
+  find "$outDir"/sections -type f |
+  sort -n |
+  while read -r pdfSection; do
+    # Margins have already been set correctly by the geometry package in header.tex
+    # pdfbook2 fails to move the .pdf over filesystems
+    pdfbook2 --no-crop \
+      --paper "${paper:-a4paper}" \
+      --outer-margin "${outerMargin:-80}" \
+      --inner-margin "${innerMargin:-150}" \
+      --top-margin "${topmargin:-30}" \
+      --bottom-margin "${bottomMargin:-30}" \
+      "$pdfSection"
+    rm "$pdfSection"
+
+    # Split odd and even pages to print in the same direction
+      pdftk "${pdfSection%.pdf}"-book.pdf cat oddSouth output "${pdfSection%.pdf}".book.odds.pdf
+      pdftk "${pdfSection%.pdf}"-book.pdf cat even output "${pdfSection%.pdf}".book.even.pdf
+    rm "${pdfSection%.pdf}"-book.pdf
+  done
diff --git a/scripts/styles/epub.header.tex b/scripts/styles/epub.header.tex
new file mode 100644 (file)
index 0000000..68e3eba
--- /dev/null
@@ -0,0 +1,5 @@
+% Geometry for the booklet
+\usepackage[portrait, left=1.5cm, right=1.5cm, top=2.5cm, bottom=2cm, headheight=1.5cm, headsep=1cm, footskip=1cm, marginparsep=0pt, marginparwidth=0pt, bindingoffset=1cm, twoside]{geometry}
+
+% No title
+\renewcommand{\maketitle}{}