1 { fetchurl, lib, stdenv, python3
2 , fetchFromGitHub, autoreconfHook
4 , enableStandardFeatures ? false
25 # if true, enable all the below filters and backends
26 , enableExtraPlugins ? false
28 # unzip is needed to extract filter and backend plugins
31 , enableDitaaFilter ? false, jre
32 , enableMscgenFilter ? false, mscgen
33 , enableDiagFilter ? false, blockdiag, seqdiag, actdiag, nwdiag
34 , enableQrcodeFilter ? false, qrencode
35 , enableMatplotlibFilter ? false, matplotlib, numpy
36 , enableAafigureFilter ? false, aafigure, recursive-pth-loader
38 , enableDeckjsBackend ? false
39 , enableOdfBackend ? false
41 # java is problematic on some platforms, where it is unfree
49 _enableDitaaFilter = (enableExtraPlugins && enableJava) || enableDitaaFilter;
50 _enableMscgenFilter = enableExtraPlugins || enableMscgenFilter;
51 _enableDiagFilter = enableExtraPlugins || enableDiagFilter;
52 _enableQrcodeFilter = enableExtraPlugins || enableQrcodeFilter;
53 _enableMatplotlibFilter = enableExtraPlugins || enableMatplotlibFilter;
54 _enableAafigureFilter = enableExtraPlugins || enableAafigureFilter;
55 _enableDeckjsBackend = enableExtraPlugins || enableDeckjsBackend;
56 _enableOdfBackend = enableExtraPlugins || enableOdfBackend;
61 texlive = texliveMinimal.withPackages (ps: [ ps.dvipng ]);
67 ditaaFilterSrc = fetchurl {
68 url = "https://asciidoc-ditaa-filter.googlecode.com/files/ditaa-filter-1.1.zip";
69 sha256 = "0p7hm2a1xywx982ia3vg4c0lam5sz0xknsc10i2a5vswy026naf6";
72 mscgenFilterSrc = fetchurl {
73 url = "https://asciidoc-mscgen-filter.googlecode.com/files/mscgen-filter-1.2.zip";
74 sha256 = "1nfwmj375gpv5dn9i770pjv59aihzy2kja0fflsk96xwnlqsqq61";
77 diagFilterSrc = fetchurl {
78 # unfortunately no version number
79 url = "https://asciidoc-diag-filter.googlecode.com/files/diag_filter.zip";
80 sha256 = "1qlqrdbqkdqqgfdhjsgdws1al0sacsyq6jmwxdfy7r8k7bv7n7mm";
83 qrcodeFilterSrc = fetchurl {
84 url = "https://asciidoc-qrencode-filter.googlecode.com/files/qrcode-filter-1.0.zip";
85 sha256 = "0h4bql1nb4y4fmg2yvlpfjhvy22ln8jsaxdr10f8bfcg5lr0zkxs";
88 # there are no archives or tags, using latest commit in master branch as per 2013-09-22
89 matplotlibFilterSrc = let commit = "75f0d009629f93f33fab04b83faca20cc35dd358"; in fetchurl {
90 name = "mplw-${commit}.tar.gz";
91 url = "https://api.github.com/repos/lvv/mplw/tarball/${commit}";
92 sha256 = "0yfhkm2dr8gnp0fcg25x89hwiymkri2m5cyqzmzragzwj0hbmcf1";
95 aafigureFilterSrc = fetchurl {
96 url = "https://asciidoc-aafigure-filter.googlecode.com/files/aafigure-filter-1.1.zip";
97 sha256 = "1hq2s30dvmv5dqvj0xm1qwdwafhgm9w1iyr0lr0c40cyk8h00j8j";
104 deckjsBackendSrc = fetchurl {
105 url = "https://github.com/downloads/houqp/asciidoc-deckjs/deckjs-1.6.2.zip";
106 sha256 = "1siy1j8naj5irrrrv5bfgl4d8nal6j9pyahy4f50wmrr9wv59s46";
109 # the odf backend is actually two plugins: odt + odp
110 odtBackendSrc = fetchurl {
111 url = "https://github.com/downloads/dagwieers/asciidoc-odf/odt-backend-0.1.zip";
112 sha256 = "1zaa97h9sx6ncxcdkl1x3ggydi7f8kjgvrnpjnkjiizi45k350kw";
115 odpBackendSrc = fetchurl {
116 url = "https://github.com/downloads/dagwieers/asciidoc-odf/odp-backend-0.1.zip";
117 sha256 = "08ya4bskygzqkfqwjllpg31qc5k08xp2k78z9b2480g8y57bfy10";
120 in python3.pkgs.buildPythonApplication rec {
122 + lib.optionalString enableStandardFeatures "-full"
123 + lib.optionalString enableExtraPlugins "-with-plugins";
127 src = fetchFromGitHub {
128 owner = "asciidoc-py";
129 repo = "asciidoc-py";
131 hash = "sha256-td3C7xTWfSzdo9Bbz0dHW2oPaCQYmUE9H2sUFfg5HH0=";
134 nativeBuildInputs = [
140 # install filters early, so their shebangs are patched too
142 mkdir -p "$out/etc/asciidoc/filters"
143 mkdir -p "$out/etc/asciidoc/backends"
144 '' + lib.optionalString _enableDitaaFilter ''
145 echo "Extracting ditaa filter"
146 unzip -d "$out/etc/asciidoc/filters/ditaa" "${ditaaFilterSrc}"
147 sed -i -e "s|java -jar|${jre}/bin/java -jar|" \
148 "$out/etc/asciidoc/filters/ditaa/ditaa2img.py"
149 '' + lib.optionalString _enableMscgenFilter ''
150 echo "Extracting mscgen filter"
151 unzip -d "$out/etc/asciidoc/filters/mscgen" "${mscgenFilterSrc}"
152 sed -i -e "s|filter-wrapper.py mscgen|filter-wrapper.py ${mscgen}/bin/mscgen|" \
153 "$out/etc/asciidoc/filters/mscgen/mscgen-filter.conf"
154 '' + lib.optionalString _enableDiagFilter ''
155 echo "Extracting diag filter"
156 unzip -d "$out/etc/asciidoc/filters/diag" "${diagFilterSrc}"
158 -e "s|filter='blockdiag|filter=\'${blockdiag}/bin/blockdiag|" \
159 -e "s|filter='seqdiag|filter=\'${seqdiag}/bin/seqdiag|" \
160 -e "s|filter='actdiag|filter=\'${actdiag}/bin/actdiag|" \
161 -e "s|filter='nwdiag|filter=\'${nwdiag}/bin/nwdiag|" \
162 -e "s|filter='packetdiag|filter=\'${nwdiag}/bin/packetdiag|" \
163 "$out/etc/asciidoc/filters/diag/diag-filter.conf"
164 '' + lib.optionalString _enableQrcodeFilter ''
165 echo "Extracting qrcode filter"
166 unzip -d "$out/etc/asciidoc/filters/qrcode" "${qrcodeFilterSrc}"
167 sed -i -e "s|systemcmd('qrencode|systemcmd('${qrencode}/bin/qrencode|" \
168 "$out/etc/asciidoc/filters/qrcode/qrcode2img.py"
169 '' + lib.optionalString _enableMatplotlibFilter ''
170 echo "Extracting mpl (matplotlib) filter"
171 mkdir -p "$out/etc/asciidoc/filters/mpl"
172 tar xvf "${matplotlibFilterSrc}" -C "$out/etc/asciidoc/filters/mpl" --strip-components=1
173 # Stop asciidoc from loading mpl/.old/chart-filter.conf
174 rm -rf "$out/etc/asciidoc/filters/mpl/.old"
175 # Add matplotlib and numpy to sys.path
176 matplotlib_path="$(toPythonPath ${matplotlib})"
177 numpy_path="$(toPythonPath ${numpy})"
178 sed -i "/^import.*sys/asys.path.append(\"$matplotlib_path\"); sys.path.append(\"$numpy_path\");" \
179 "$out/etc/asciidoc/filters/mpl/mplw.py"
180 '' + lib.optionalString _enableAafigureFilter ''
181 echo "Extracting aafigure filter"
182 unzip -d "$out/etc/asciidoc/filters/aafigure" "${aafigureFilterSrc}"
183 # Add aafigure to sys.path (and it needs recursive-pth-loader)
184 pth_loader_path="$(toPythonPath ${recursive-pth-loader})"
185 aafigure_path="$(toPythonPath ${aafigure})"
186 sed -i "/^import.*sys/asys.path.append(\"$pth_loader_path\"); sys.path.append(\"$aafigure_path\"); import sitecustomize" \
187 "$out/etc/asciidoc/filters/aafigure/aafig2img.py"
188 '' + lib.optionalString _enableDeckjsBackend ''
189 echo "Extracting deckjs backend"
190 unzip -d "$out/etc/asciidoc/backends/deckjs" "${deckjsBackendSrc}"
191 '' + lib.optionalString _enableOdfBackend ''
192 echo "Extracting odf backend (odt + odp)"
193 unzip -d "$out/etc/asciidoc/backends/odt" "${odtBackendSrc}"
194 unzip -d "$out/etc/asciidoc/backends/odp" "${odpBackendSrc}"
195 # The odt backend has a TODO note about removing this hardcoded path, but
196 # the odp backend already has that fix. Copy it here until fixed upstream.
197 sed -i "s|'/etc/asciidoc/backends/odt/asciidoc.ott'|os.path.dirname(__file__),'asciidoc.ott'|" \
198 "$out/etc/asciidoc/backends/odt/a2x-backend.py"
199 '' + (if enableStandardFeatures then ''
200 sed -e "s|dot|${graphviz}/bin/dot|g" \
201 -e "s|neato|${graphviz}/bin/neato|g" \
202 -e "s|twopi|${graphviz}/bin/twopi|g" \
203 -e "s|circo|${graphviz}/bin/circo|g" \
204 -e "s|fdp|${graphviz}/bin/fdp|g" \
205 -i "asciidoc/resources/filters/graphviz/graphviz2png.py"
207 sed -e "s|run('latex|run('${texlive}/bin/latex|g" \
208 -e "s|cmd = 'dvipng'|cmd = '${texlive}/bin/dvipng'|g" \
209 -e "s|cmd = 'dvisvgm'|cmd = '${texlive}/bin/dvisvgm'|g" \
210 -i "asciidoc/resources/filters/latex/latex2img.py"
212 sed -e "s|run('abc2ly|run('${lilypond}/bin/abc2ly|g" \
213 -e "s|run('lilypond|run('${lilypond}/bin/lilypond|g" \
214 -e "s|run('convert|run('${imagemagick.out}/bin/convert|g" \
215 -i "asciidoc/resources/filters/music/music2png.py"
217 sed -e 's|filter="source-highlight|filter="${sourceHighlight}/bin/source-highlight|' \
218 -e 's|filter="highlight|filter="${highlight}/bin/highlight|' \
219 -e 's|filter="pygmentize|filter="${pygments}/bin/pygmentize|' \
220 -i "asciidoc/resources/filters/source/source-highlight-filter.conf"
222 # ENV is custom environment passed to programs that a2x invokes. Here we
223 # use it to work around an impurity in the tetex package; tetex tools
224 # cannot find their neighbours (e.g. pdflatex doesn't find mktextfm).
225 # We can remove PATH= when those impurities are fixed.
226 # TODO: Is this still necessary when using texlive?
227 sed -e "s|^ENV =.*|ENV = dict(XML_CATALOG_FILES='${docbook_xml_dtd_45}/xml/dtd/docbook/catalog.xml ${docbook_xsl_ns}/xml/xsl/docbook/catalog.xml ${docbook_xsl}/xml/xsl/docbook/catalog.xml', PATH='${lib.makeBinPath [ texlive coreutils gnused ]}', **(dict(filter(lambda v: v[0] == 'SOURCE_DATE_EPOCH', os.environ.items()))))|" \
228 -e "s|^ASCIIDOC =.*|ASCIIDOC = '$out/bin/asciidoc'|" \
229 -e "s|^XSLTPROC =.*|XSLTPROC = '${libxslt.bin}/bin/xsltproc'|" \
230 -e "s|^DBLATEX =.*|DBLATEX = '${dblatexFull}/bin/dblatex'|" \
231 ${lib.optionalString enableJava ''-e "s|^FOP =.*|FOP = '${fop}/bin/fop'|"''} \
232 -e "s|^W3M =.*|W3M = '${w3m}/bin/w3m'|" \
233 -e "s|^LYNX =.*|LYNX = '${lynx}/bin/lynx'|" \
234 -e "s|^XMLLINT =.*|XMLLINT = '${libxml2.bin}/bin/xmllint'|" \
235 -e "s|^EPUBCHECK =.*|EPUBCHECK = '${epubcheck}/bin/epubcheck'|" \
238 sed -e "s|^ENV =.*|ENV = dict(XML_CATALOG_FILES='${docbook_xml_dtd_45}/xml/dtd/docbook/catalog.xml ${docbook_xsl_ns}/xml/xsl/docbook/catalog.xml ${docbook_xsl}/xml/xsl/docbook/catalog.xml', **(dict(filter(lambda v: v[0] == 'SOURCE_DATE_EPOCH', os.environ.items()))))|" \
239 -e "s|^XSLTPROC =.*|XSLTPROC = '${libxslt.bin}/bin/xsltproc'|" \
240 -e "s|^XMLLINT =.*|XMLLINT = '${libxml2.bin}/bin/xmllint'|" \
244 for f in $(grep -R --files-with-matches "2002-11-25") ; do
245 substituteInPlace $f --replace "2002-11-25" "1980-01-02"
246 substituteInPlace $f --replace "00:37:42" "00:00:00"
248 '' + lib.optionalString (stdenv.buildPlatform != stdenv.hostPlatform) ''
249 # We want to use asciidoc from the build platform to build the documentation.
250 substituteInPlace Makefile.in \
251 --replace "python3 -m asciidoc.a2x" "${buildPackages.asciidoc}/bin/a2x"
254 build-system = with python3.pythonOnBuildForHost.pkgs; [ setuptools ];
261 installManPage doc/asciidoc.1 doc/a2x.1 doc/testasciidoc.1
264 nativeCheckInputs = with python3.pkgs; [
278 description = "Text-based document generation system";
280 AsciiDoc is a text document format for writing notes, documentation,
281 articles, books, ebooks, slideshows, web pages, man pages and blogs.
282 AsciiDoc files can be translated to many formats including HTML, PDF,
285 AsciiDoc is highly configurable: both the AsciiDoc source file syntax and
286 the backend output markups (which can be almost any type of SGML/XML
287 markup) can be customized and extended by the user.
289 sourceProvenance = [ lib.sourceTypes.fromSource ]
290 ++ lib.optional _enableDitaaFilter lib.sourceTypes.binaryBytecode;
291 homepage = "https://asciidoc-py.github.io/";
292 changelog = "https://github.com/asciidoc-py/asciidoc-py/blob/${version}/CHANGELOG.adoc";
293 license = lib.licenses.gpl2Plus;
294 platforms = lib.platforms.unix;
295 maintainers = with lib.maintainers; [ bjornfor dotlambda ];