From c47c350f6518ed39c2a16e4fadf9137b6c559ddc Mon Sep 17 00:00:00 2001 From: Kirill Elagin Date: Sat, 1 Jan 2022 14:51:06 -0500 Subject: [PATCH] pandoc: add new module Add a module for pandoc that provides the following: 1. Setting default configuration options. 2. Installing templates. 3. Installing citation styles. --- .github/CODEOWNERS | 3 + modules/misc/news.nix | 7 ++ modules/modules.nix | 1 + modules/programs/pandoc.nix | 104 ++++++++++++++++++ tests/default.nix | 1 + tests/modules/programs/pandoc/csl.nix | 18 +++ tests/modules/programs/pandoc/default.nix | 5 + .../programs/pandoc/defaults-expected.json | 7 ++ tests/modules/programs/pandoc/defaults.nix | 30 +++++ tests/modules/programs/pandoc/example.csl | 12 ++ tests/modules/programs/pandoc/output-expected | 2 + tests/modules/programs/pandoc/stub.nix | 10 ++ tests/modules/programs/pandoc/template.latex | 9 ++ tests/modules/programs/pandoc/templates.nix | 18 +++ 14 files changed, 227 insertions(+) create mode 100644 modules/programs/pandoc.nix create mode 100644 tests/modules/programs/pandoc/csl.nix create mode 100644 tests/modules/programs/pandoc/default.nix create mode 100644 tests/modules/programs/pandoc/defaults-expected.json create mode 100644 tests/modules/programs/pandoc/defaults.nix create mode 100644 tests/modules/programs/pandoc/example.csl create mode 100644 tests/modules/programs/pandoc/output-expected create mode 100644 tests/modules/programs/pandoc/stub.nix create mode 100644 tests/modules/programs/pandoc/template.latex create mode 100644 tests/modules/programs/pandoc/templates.nix diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 8477e086b..5d3fea78d 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -176,6 +176,9 @@ /modules/programs/openssh.nix @rycee +/modules/programs/pandoc.nix @kirelagin +/tests/modules/programs/pandoc @kirelagin + /modules/programs/password-store.nix @pacien /modules/programs/pazi.nix @marsam diff --git a/modules/misc/news.nix b/modules/misc/news.nix index b1ab5c543..94c053b81 100644 --- a/modules/misc/news.nix +++ b/modules/misc/news.nix @@ -2380,6 +2380,13 @@ in A new module is available: 'programs.tint2'. ''; } + + { + time = "2022-01-22T17:39:20+00:00"; + message = '' + A new module is available: 'programs.pandoc'. + ''; + } ]; }; } diff --git a/modules/modules.nix b/modules/modules.nix index 57be5c244..42b3e902f 100644 --- a/modules/modules.nix +++ b/modules/modules.nix @@ -117,6 +117,7 @@ let ./programs/octant.nix ./programs/offlineimap.nix ./programs/opam.nix + ./programs/pandoc.nix ./programs/password-store.nix ./programs/pazi.nix ./programs/pet.nix diff --git a/modules/programs/pandoc.nix b/modules/programs/pandoc.nix new file mode 100644 index 000000000..7f0fa713c --- /dev/null +++ b/modules/programs/pandoc.nix @@ -0,0 +1,104 @@ +{ config, lib, pkgs, ... }: + +let + + cfg = config.programs.pandoc; + + inherit (lib) literalExpression mkEnableOption mkIf mkOption types; + + jsonFormat = pkgs.formats.json { }; + + makeTemplateFile = name: file: + lib.nameValuePair "pandoc/templates/${name}" { source = file; }; + + getFileName = file: + # This is actually safe here, since it is just a file name + builtins.unsafeDiscardStringContext (baseNameOf file); + + makeCslFile = file: + lib.nameValuePair "pandoc/csl/${getFileName file}" { source = file; }; + +in { + meta.maintainers = [ lib.maintainers.kirelagin ]; + + options.programs.pandoc = { + enable = mkEnableOption "pandoc"; + + package = mkOption { + type = types.package; + default = pkgs.pandoc; + defaultText = literalExpression "pkgs.pandoc"; + description = "The pandoc package to use."; + }; + + # We wrap the executable to pass some arguments + finalPackage = mkOption { + type = types.package; + readOnly = true; + description = "Resulting package."; + }; + + defaults = mkOption { + type = jsonFormat.type; + default = { }; + example = literalExpression '' + { + metadata = { + author = "John Doe"; + }; + pdf-engine = "xelatex"; + citeproc = true; + } + ''; + description = '' + Options to set by default. + These will be converted to JSON and written to a defaults + file (see Default files in pandoc documentation). + ''; + }; + + defaultsFile = mkOption { + type = types.path; + readOnly = true; + description = "Resulting defaults file."; + }; + + templates = mkOption { + type = types.attrsOf types.path; + default = { }; + example = literalExpression '' + { + "default.latex" = path/to/your/template; + } + ''; + description = "Custom templates."; + }; + + citationStyles = mkOption { + type = types.listOf types.path; + default = [ ]; + example = literalExpression "[ path/to/file.csl ]"; + description = "List of .csl files to install."; + }; + }; + + config = mkIf cfg.enable { + programs.pandoc = { + defaultsFile = jsonFormat.generate "hm.json" cfg.defaults; + + finalPackage = pkgs.symlinkJoin { + name = "pandoc-with-defaults"; + paths = [ cfg.package ]; + nativeBuildInputs = [ pkgs.makeWrapper ]; + postBuild = '' + wrapProgram "$out/bin/pandoc" \ + --add-flags '--defaults "${cfg.defaultsFile}"' + ''; + }; + }; + + home.packages = [ cfg.finalPackage ]; + xdg.dataFile = lib.mapAttrs' makeTemplateFile cfg.templates + // lib.listToAttrs (map makeCslFile cfg.citationStyles); + }; +} diff --git a/tests/default.nix b/tests/default.nix index e1e5f4302..4349e3f4f 100644 --- a/tests/default.nix +++ b/tests/default.nix @@ -86,6 +86,7 @@ import nmt { ./modules/programs/nix-index ./modules/programs/nnn ./modules/programs/nushell + ./modules/programs/pandoc ./modules/programs/pet ./modules/programs/powerline-go ./modules/programs/qutebrowser diff --git a/tests/modules/programs/pandoc/csl.nix b/tests/modules/programs/pandoc/csl.nix new file mode 100644 index 000000000..7384ec995 --- /dev/null +++ b/tests/modules/programs/pandoc/csl.nix @@ -0,0 +1,18 @@ +{ config, ... }: + +{ + programs.pandoc = { + enable = true; + + citationStyles = [ ./example.csl ]; + }; + + test.stubs.pandoc = import ./stub.nix; + + nmt.script = '' + assertFileExists home-files/.local/share/pandoc/csl/example.csl + assertFileContent home-files/.local/share/pandoc/csl/example.csl \ + ${./example.csl} + ''; +} + diff --git a/tests/modules/programs/pandoc/default.nix b/tests/modules/programs/pandoc/default.nix new file mode 100644 index 000000000..d33eff86c --- /dev/null +++ b/tests/modules/programs/pandoc/default.nix @@ -0,0 +1,5 @@ +{ + pandoc-citation-styles = ./csl.nix; + pandoc-defaults = ./defaults.nix; + pandoc-templates = ./templates.nix; +} diff --git a/tests/modules/programs/pandoc/defaults-expected.json b/tests/modules/programs/pandoc/defaults-expected.json new file mode 100644 index 000000000..efffefb2b --- /dev/null +++ b/tests/modules/programs/pandoc/defaults-expected.json @@ -0,0 +1,7 @@ +{ + "citeproc": true, + "metadata": { + "author": "John Doe" + }, + "pdf-engine": "xelatex" +} diff --git a/tests/modules/programs/pandoc/defaults.nix b/tests/modules/programs/pandoc/defaults.nix new file mode 100644 index 000000000..e9288657b --- /dev/null +++ b/tests/modules/programs/pandoc/defaults.nix @@ -0,0 +1,30 @@ +{ config, lib, ... }: + +let cfg = config.programs.pandoc; + +in { + config = lib.mkIf config.test.enableBig { + programs.pandoc = { + enable = true; + + defaults = { + metadata = { author = "John Doe"; }; + pdf-engine = "xelatex"; + citeproc = true; + }; + }; + + nmt.script = '' + assertFileContent ${cfg.defaultsFile} ${./defaults-expected.json} + + # Test that defaults are set by looking at the metadata for an empty file + # (it should contain the author that we set in defaults). + output=$(mktemp) + ${cfg.finalPackage}/bin/pandoc --standalone \ + -f markdown /dev/null \ + -t native -o "$output" + assertFileContent "$output" ${./output-expected} + ''; + }; +} + diff --git a/tests/modules/programs/pandoc/example.csl b/tests/modules/programs/pandoc/example.csl new file mode 100644 index 000000000..63f626701 --- /dev/null +++ b/tests/modules/programs/pandoc/example.csl @@ -0,0 +1,12 @@ + + diff --git a/tests/modules/programs/pandoc/output-expected b/tests/modules/programs/pandoc/output-expected new file mode 100644 index 000000000..ef1a5e4c1 --- /dev/null +++ b/tests/modules/programs/pandoc/output-expected @@ -0,0 +1,2 @@ +Pandoc (Meta {unMeta = fromList [("author",MetaString "John Doe")]}) +[] diff --git a/tests/modules/programs/pandoc/stub.nix b/tests/modules/programs/pandoc/stub.nix new file mode 100644 index 000000000..26af1e3ba --- /dev/null +++ b/tests/modules/programs/pandoc/stub.nix @@ -0,0 +1,10 @@ +{ + name = "pandoc-stub"; + outPath = null; + buildScript = '' + mkdir -p "$out"/bin + pandoc="$out"/bin/pandoc + echo 'Stub to make the wrapper happy' > "$pandoc" + chmod a+x "$pandoc" + ''; +} diff --git a/tests/modules/programs/pandoc/template.latex b/tests/modules/programs/pandoc/template.latex new file mode 100644 index 000000000..16d24ec80 --- /dev/null +++ b/tests/modules/programs/pandoc/template.latex @@ -0,0 +1,9 @@ +\documentclass[a4paper]{scrartcl} + +$if(title)$\title{$title$}$endif$ +$if(author)$\author{$for(author)$$author$$sep$ \and $endfor$}$endif$ + +\begin{document} +\maketitle +$body$ +\end{document} diff --git a/tests/modules/programs/pandoc/templates.nix b/tests/modules/programs/pandoc/templates.nix new file mode 100644 index 000000000..f276381a3 --- /dev/null +++ b/tests/modules/programs/pandoc/templates.nix @@ -0,0 +1,18 @@ +{ config, ... }: + +{ + programs.pandoc = { + enable = true; + + templates = { "default.latex" = ./template.latex; }; + }; + + test.stubs.pandoc = import ./stub.nix; + + nmt.script = '' + assertFileExists home-files/.local/share/pandoc/templates/default.latex + assertFileContent home-files/.local/share/pandoc/templates/default.latex \ + ${./template.latex} + ''; +} +