git.iko.soy/typeable/nix-pills-ru
on master help sign in
Switch to graphviz & write two more sections
commit8af4018f70816f78915363f8499da52f4fbb78d6 authorAlexander Bantyev <balsoft@yandex.ru> dateMon 22 Jul 2019, 11:03 (7 years ago) parenta03c8dd
71 files changed+627−341
Makefile+4−2 architecture.png default.nix+38−1 examples/first/builder.sh+2 examples/simple/result+1 examples/simple/simple.c+3 examples/simple/simple.nix+9 examples/simple/simple_builder.sh+3 images/07e910e4a018be44.pdf images/0e2457d9ab526702.pdf images/1424617b7ac7c95d.pdf images/188fdf7211acc88d.pdf images/19da3971dd333eb6.pdf images/1b1f183d83d63270.pdf images/24648988d661d96d.pdf images/24a74845eae811f8.pdf images/2ab1bef9accfd6b0.pdf images/2f58b1ea7cddeebb.pdf images/4713703a545f70d9.pdf images/4771d4d465c7d8d6.pdf images/4830188cd5dc92c1.pdf images/492d8a15398696b5.pdf images/4edcbd8378c550f8.pdf−70 images/54dbd54f7d63a297.pdf images/5b59dff014a9fc01.pdf images/5ba939cbd4bf3541.pdf images/5f808030cca24e58.pdf images/61a5a568c6312110.pdf images/6719d7c8f0674e9a.pdf images/69f31e5c6d2582b0.pdf images/6fa1eb51499dec60.pdf images/71c6154d00ce3e77.pdf images/76e53559a97fd7bf.pdf images/81e8ebffe440857c.pdf images/84f297320ced1abe.pdf−68 images/97249b599f25b363.pdf images/97cb221c7bbd7878.pdf images/9ccd45546b741322.pdf images/9e0973ce17eb93f8.pdf images/a1ffb430c5484b30.pdf images/a26eb6e8ea57450c.pdf images/a9b760021ecd34bd.pdf−69 images/ae73261c80860acf.pdf images/b1a1661668188271.pdf images/b4cecac95d5577c6.pdf images/b5eb5e2d77f27a48.pdf images/c2a15ddceeeebf53.pdf images/ce4c6b342ddaa8dc.pdf images/ce72ab0d235dbdca.pdf images/d6e8b1a4deae57d5.pdf images/d7909fc639c79f60.pdf images/d82aa8575d0021db.pdf images/e2a0d73df0d6c40a.pdf images/e2ed79f26b927b14.pdf images/f76f111a0a16a95a.pdf images/ff9616da8be506e1.pdf images/nix.png missfont.log−10 nix.md+437−86 nix.pdf nix.png nix_text.pdf nix_text.pptx pandoc-filter-graphviz/.gitignore+4 pandoc-filter-graphviz/GititPluginGraphviz.hs+6 pandoc-filter-graphviz/GraphvizBlock.hs+43 pandoc-filter-graphviz/Main.hs+4 pandoc-filter-graphviz/README.md+48 pandoc-filter-graphviz/example.md+25 result−1 shell.nix−34
Makefile+4−2
@@ -1,3 +1,5 @@
1−loop: ; while inotifywait nix.md; do eval $$buildPhase; done
1+build: ; eval $$buildPhase
22
3−all: loop
3+autoreload: ; while inotifywait -qq nix.md; do eval $$buildPhase; done
4+
5+all: build
architecture.pngdeleted

Binary file not shown.

default.nixmode 120000 → 100644+38−1
@@ -1 +0,0 @@
1−shell.nix
@@ -0,0 +1,38 @@
1+with import <nixpkgs> { };
2+let
3+ pandoc-filter-graphviz = stdenv.mkDerivation rec {
4+ name = "pandoc-filter-graphviz";
5+ src = ./pandoc-filter-graphviz;
6+ buildInputs = [ (ghc.withPackages (ps: with ps; [ pandoc ])) ];
7+ propogatedBuildInputs = [ graphviz dot2tex ];
8+ buildPhase = "ghc --make Main.hs -o ${name}";
9+ installPhase = "mkdir -p $out/bin; cp ${name} $out/bin";
10+ };
11+in stdenv.mkDerivation rec {
12+ name = "presentation";
13+ buildInputs = [
14+ pandoc
15+ texlive.combined.scheme-full
16+ pandoc-filter-graphviz
17+ fontconfig
18+ roboto
19+ hack-font
20+ graphviz
21+ dot2tex
22+
23+ inotify-tools
24+ ];
25+
26+ src = ./.;
27+
28+ phases = [ "buildPhase" ];
29+
30+ preferLocalBuild = true;
31+
32+ buildPhase = ''
33+ pandoc nix.md -t beamer --slide-level=2 --pdf-engine xelatex -F pandoc-filter-graphviz -o nix.pdf;
34+ pandoc nix.md -t slidy -F pandoc-filter-graphviz -o nix.html;
35+ sed -e "/<!--/,/-->/!d" nix.md | sed -e "s/<!--//" | sed -e "s/-->/\n\* \* \*/" > speaker-notes.md;
36+ pandoc speaker-notes.md -o speaker-notes.html
37+ '';
38+}
examples/first/builder.shnew file+2
@@ -0,0 +1,2 @@
1+declare -xp
2+echo foo > $out
examples/simple/resultnew file+1
@@ -0,0 +1 @@
1+/nix/store/p6a11dai9b7xw3xgf44pgyr5kdlnr9rf-simple
examples/simple/simple.cnew file+3
@@ -0,0 +1,3 @@
1+void main() {
2+ puts("Simple!");
3+}
examples/simple/simple.nixnew file+9
@@ -0,0 +1,9 @@
1+with (import <nixpkgs> {});
2+derivation {
3+ name = "simple";
4+ builder = "${bash}/bin/bash";
5+ args = [ ./simple_builder.sh ]; # Сборщик
6+ inherit gcc coreutils; # Зависимости
7+ src = ./simple.c;
8+ system = builtins.currentSystem;
9+}
examples/simple/simple_builder.shnew file+3
@@ -0,0 +1,3 @@
1+export PATH="$coreutils/bin:$gcc/bin" # Переменные из derivation
2+mkdir -p $out/bin # Создадим выходную директорию
3+gcc -o $out/bin/simple $src # Соберем нашу программу
images/07e910e4a018be44.pdfdeleted

Binary file not shown.

images/0e2457d9ab526702.pdfdeleted

Binary file not shown.

images/1424617b7ac7c95d.pdfdeleted

Binary file not shown.

images/188fdf7211acc88d.pdfdeleted

Binary file not shown.

images/19da3971dd333eb6.pdfdeleted

Binary file not shown.

images/1b1f183d83d63270.pdfdeleted

Binary file not shown.

images/24648988d661d96d.pdfdeleted

Binary file not shown.

images/24a74845eae811f8.pdfdeleted

Binary file not shown.

images/2ab1bef9accfd6b0.pdfdeleted

Binary file not shown.

images/2f58b1ea7cddeebb.pdfdeleted

Binary file not shown.

images/4713703a545f70d9.pdfdeleted

Binary file not shown.

images/4771d4d465c7d8d6.pdfdeleted

Binary file not shown.

images/4830188cd5dc92c1.pdfdeleted

Binary file not shown.

images/492d8a15398696b5.pdfdeleted

Binary file not shown.

images/4edcbd8378c550f8.pdfdeleted−70
@@ -1,70 +0,0 @@
1−%PDF-1.5
2−%����
3−4 0 obj
4−<< /Length 5 0 R
5− /Filter /FlateDecode
6−>>
7−stream
8−x��T�j�1 ��)�U,ɿ�^
9−��kȡ|�������K�w��$�L,iFR�1���/J)��;%�'��5>}O���I���'�kϽu����,?���)���H�!c��z�xYL�oΑ�B����hR�Wv|D F.�) 8 O�X��� �,�=R ��$$�e(�2g�[G��}�k�w
10−;Bk"EZ{q$�J'ɐ3�NS��j��N)b�(!�� j����}lhLy�� ��]q8C��?q��b:�6��������WӇ���id�D>���6�3Ԑf^#��V�2�Ğ{° ��0 ���۽<�-B����1�s"��0߃�ft�t����&�z��)raF�p 6[�{������i�������G� s��0�k�9K�ak�R�:�-g*�+��3v���$�.4WԂm�-���Vߟ�XM��3~e��^�`�{^(k�9�:r:�u����N� 䌞(��:rVď��P�e� �>���G�k��1�
11−endstream
12−endobj
13−5 0 obj
14− 489
15−endobj
16−3 0 obj
17−<<
18− /ExtGState <<
19− /a0 << /CA 1 /ca 1 >>
20− >>
21−>>
22−endobj
23−2 0 obj
24−<< /Type /Page % 1
25− /Parent 1 0 R
26− /MediaBox [ 0 0 500 200 ]
27− /Contents 4 0 R
28− /Group <<
29− /Type /Group
30− /S /Transparency
31− /I true
32− /CS /DeviceRGB
33− >>
34− /Resources 3 0 R
35−>>
36−endobj
37−1 0 obj
38−<< /Type /Pages
39− /Kids [ 2 0 R ]
40− /Count 1
41−>>
42−endobj
43−6 0 obj
44−<< /Producer (cairo 1.16.0 (https://cairographics.org))
45− /CreationDate (D:20190721124059+03'00)
46−>>
47−endobj
48−7 0 obj
49−<< /Type /Catalog
50− /Pages 1 0 R
51−>>
52−endobj
53−xref
54−0 8
55−0000000000 65535 f
56−0000000893 00000 n
57−0000000675 00000 n
58−0000000603 00000 n
59−0000000015 00000 n
60−0000000581 00000 n
61−0000000958 00000 n
62−0000001074 00000 n
63−trailer
64−<< /Size 8
65− /Root 7 0 R
66− /Info 6 0 R
67−>>
68−startxref
69−1126
70−%%EOF
images/54dbd54f7d63a297.pdfdeleted

Binary file not shown.

images/5b59dff014a9fc01.pdfdeleted

Binary file not shown.

images/5ba939cbd4bf3541.pdfdeleted

Binary file not shown.

images/5f808030cca24e58.pdfdeleted

Binary file not shown.

images/61a5a568c6312110.pdfdeleted

Binary file not shown.

images/6719d7c8f0674e9a.pdfdeleted

Binary file not shown.

images/69f31e5c6d2582b0.pdfdeleted

Binary file not shown.

images/6fa1eb51499dec60.pdfdeleted

Binary file not shown.

images/71c6154d00ce3e77.pdfdeleted

Binary file not shown.

images/76e53559a97fd7bf.pdfdeleted

Binary file not shown.

images/81e8ebffe440857c.pdfdeleted

Binary file not shown.

images/84f297320ced1abe.pdfdeleted−68
@@ -1,68 +0,0 @@
1−%PDF-1.5
2−%����
3−4 0 obj
4−<< /Length 5 0 R
5− /Filter /FlateDecode
6−>>
7−stream
8−x�e�MJA ��9Ż�1��� �c/Ņ��H�b��ן�SՂMQ���KJ!~ԟ �y� ɯ���w�畔UjS�x����^� ,� <#ZeK ڄ=�"��1gT��`\+˦B����ʡ4.-� ,��t�{T�fnu��n��Ʉ(l�c9qҡf�:HJ75s�zo�j����>B�ޭfK�.i���#1�������&:� �Ny
9−endstream
10−endobj
11−5 0 obj
12− 207
13−endobj
14−3 0 obj
15−<<
16− /ExtGState <<
17− /a0 << /CA 1 /ca 1 >>
18− >>
19−>>
20−endobj
21−2 0 obj
22−<< /Type /Page % 1
23− /Parent 1 0 R
24− /MediaBox [ 0 0 500 200 ]
25− /Contents 4 0 R
26− /Group <<
27− /Type /Group
28− /S /Transparency
29− /I true
30− /CS /DeviceRGB
31− >>
32− /Resources 3 0 R
33−>>
34−endobj
35−1 0 obj
36−<< /Type /Pages
37− /Kids [ 2 0 R ]
38− /Count 1
39−>>
40−endobj
41−6 0 obj
42−<< /Producer (cairo 1.16.0 (https://cairographics.org))
43− /CreationDate (D:20190721125717+03'00)
44−>>
45−endobj
46−7 0 obj
47−<< /Type /Catalog
48− /Pages 1 0 R
49−>>
50−endobj
51−xref
52−0 8
53−0000000000 65535 f
54−0000000611 00000 n
55−0000000393 00000 n
56−0000000321 00000 n
57−0000000015 00000 n
58−0000000299 00000 n
59−0000000676 00000 n
60−0000000792 00000 n
61−trailer
62−<< /Size 8
63− /Root 7 0 R
64− /Info 6 0 R
65−>>
66−startxref
67−844
68−%%EOF
images/97249b599f25b363.pdfdeleted

Binary file not shown.

images/97cb221c7bbd7878.pdfdeleted

Binary file not shown.

images/9ccd45546b741322.pdfdeleted

Binary file not shown.

images/9e0973ce17eb93f8.pdfdeleted

Binary file not shown.

images/a1ffb430c5484b30.pdfdeleted

Binary file not shown.

images/a26eb6e8ea57450c.pdfdeleted

Binary file not shown.

images/a9b760021ecd34bd.pdfdeleted−69
@@ -1,69 +0,0 @@
1−%PDF-1.5
2−%����
3−4 0 obj
4−<< /Length 5 0 R
5− /Filter /FlateDecode
6−>>
7−stream
8−x�UNA
9−1 ����ݲ���A=���{~�n�-Jh��0�Q0�Js�$�$/a�[����-t|2���)� 舛(�G�L�Y;-`07Z@ ��s4��:$��}��'M��l�:��gѩ�+�cS�U 鱚�'e�C�B�� _�2p
10−endstream
11−endobj
12−5 0 obj
13− 145
14−endobj
15−3 0 obj
16−<<
17− /ExtGState <<
18− /a0 << /CA 1 /ca 1 >>
19− >>
20−>>
21−endobj
22−2 0 obj
23−<< /Type /Page % 1
24− /Parent 1 0 R
25− /MediaBox [ 0 0 500 200 ]
26− /Contents 4 0 R
27− /Group <<
28− /Type /Group
29− /S /Transparency
30− /I true
31− /CS /DeviceRGB
32− >>
33− /Resources 3 0 R
34−>>
35−endobj
36−1 0 obj
37−<< /Type /Pages
38− /Kids [ 2 0 R ]
39− /Count 1
40−>>
41−endobj
42−6 0 obj
43−<< /Producer (cairo 1.16.0 (https://cairographics.org))
44− /CreationDate (D:20190721120555+03'00)
45−>>
46−endobj
47−7 0 obj
48−<< /Type /Catalog
49− /Pages 1 0 R
50−>>
51−endobj
52−xref
53−0 8
54−0000000000 65535 f
55−0000000549 00000 n
56−0000000331 00000 n
57−0000000259 00000 n
58−0000000015 00000 n
59−0000000237 00000 n
60−0000000614 00000 n
61−0000000730 00000 n
62−trailer
63−<< /Size 8
64− /Root 7 0 R
65− /Info 6 0 R
66−>>
67−startxref
68−782
69−%%EOF
images/ae73261c80860acf.pdfdeleted

Binary file not shown.

images/b1a1661668188271.pdfdeleted

Binary file not shown.

images/b4cecac95d5577c6.pdfdeleted

Binary file not shown.

images/b5eb5e2d77f27a48.pdfdeleted

Binary file not shown.

images/c2a15ddceeeebf53.pdfdeleted

Binary file not shown.

images/ce4c6b342ddaa8dc.pdfdeleted

Binary file not shown.

images/ce72ab0d235dbdca.pdfdeleted

Binary file not shown.

images/d6e8b1a4deae57d5.pdfdeleted

Binary file not shown.

images/d7909fc639c79f60.pdfdeleted

Binary file not shown.

images/d82aa8575d0021db.pdfdeleted

Binary file not shown.

images/e2a0d73df0d6c40a.pdfdeleted

Binary file not shown.

images/e2ed79f26b927b14.pdfdeleted

Binary file not shown.

images/f76f111a0a16a95a.pdfdeleted

Binary file not shown.

images/ff9616da8be506e1.pdfdeleted

Binary file not shown.

images/nix.pngnew file

Binary file not shown.

missfont.logdeleted−10
@@ -1,10 +0,0 @@
1−mktextfm noto-mono
2−mktextfm noto-mono
3−mktextfm Noto
4−mktextfm Noto
5−mktextfm noto
6−mktextfm noto
7−mktextfm NotoMono
8−mktextfm NotoMono
9−mktextfm RobotoMono
10−mktextfm RobotoMono
nix.md+437−86
@@ -1,36 +1,197 @@
11---
22title: Nix
33subtitle: Язык, пакетный менеджер и экосистема
4−author: Александр Бантьев
5−theme: Madrid
4+author: Александр Бантьев @balsoft, typeable.io
5+description: |
6+ Вольный пересказ nix-pills на русском языке.
7+ https://nixos.org/nixos/nix-pills, автор Luca Bruno (aka Lethalman)
8+theme: Boadilla
69colortheme: dolphin
710mainfont: Roboto
811monofont: Hack
912aspectratio: 169
10−titlegraphic: nix.png
13+titlegraphic: images/nix.png
14+toc: true
1115header-includes:
1216- \usepackage[utf8]{inputenc}
1317- \usepackage[russian]{babel}
18+- \uselanguage{Russian}
19+- \languagepath{Russian}
20+- \usepackage{tikz}
1421---
1522
23+<!--
24+<meta charset="utf8" />
25+<title>Заметки выступающего</title>
26+# Заметки выступающего
27+-->
28+
1629# Вступление
1730
31+Основано на <https://nixos.org/nixos/nix-pills> . Огромная благодарность @Lethalman и @grahamc за написание и поддержку этого материала!
32+
33+Я хотел бы, чтобы к концу презентации всем стало понятно
34+
35+* Что такое Nix
36+* Как собрать пакеты из `contractor` с помощью nix
37+* Что находится в `contractor/nix/pkgs`
38+* Что находится в `contractor/nix/overlay.nix`
39+* Как писать несложные выражения на nix, не совершая неочевидных ошибок
40+
41+Вы можете прекратить слушать после любой секции, и я надеюсь, что вы унесете какую-то полезную для себя информацию.
42+
43+
44+<!--
45+Как вы все скорее всего знаете, мы используем Nix для сборки и тестирования нашего кода. Я, Александр Бантьев (@balsoft) отвечаю за инфраструктуру сборки пакетов (Hydra, NixOps), а также за поддержание инструкций сборки в актуальном состоянии. Я бы хотел рассказать вам про nix с помощью вольного пересказа отличной серии статей ["Nix pills"](https://nixos.org/nixos/nix-pills)
46+-->
47+
1848## Что такое nix?
19−Nix - это чистый функциональный язык с динамическим типизированием и пакетный менеджер на основе этого языка.
2049
21−Философия Nix как пакетного менеджера - атомарность, повторяемость и чистота сборки.
50+<!--
51+Говоря "Nix", мы подразумеваем одну из двух его ипостасей -- Nix как язык или Nix как пакетный менеджер. Такая путаница возникла из-за того, что как DSL Nix имеет смысл только в связке со своим пакетным менеджером, а как пакетный менеджер он без своего языка слишком сложен в использовании, и Eelco Dolstra (создатель Nix) решил не разделять их.
52+-->
53+
54+[Nix](https://nixos.org/nix) -- это
55+
56+#. Язык
57+ + Декларативный
58+ + Функциональный
59+ + Чистый
60+ + Ленивый
61+ + Динамически типизированный
62+#. Пакетный менеджер
63+ + Атомарный
64+ + Повторяемый
65+ + Source/Binary
2266
23−Как язык, Nix отличается упором на ленивые вычисления и ориентированностью на данные: большая часть кода на Nix представляет из себя напоминающие JSON множества аттрибутов (attrsets).
2467
2568## Экосистема
26−![Экосистема](architecture.png){ height=90% }
69+
70+<!--
71+Nix довольно быстро стал широко известен в узких кругах, и вокруг него возникла большая экосистема декларативных, атомарных инструментов, в том числе:
72+
73+* nixpkgs, репозиторий описаний пакетов на языке nix;
74+* NixOS, дистрибутив GNU/Linux с интересным подходом к конфигурации системы;
75+* NixOps, инструментарий для разворачивания виртуальных машин и приложений на них на базе NixOS;
76+* Hydra, CI -- сервер;
77+* Disnix, система для разворачивания распределенных систем.
78+-->
79+
80+```{.graphviz layout=fdp}
81+digraph {
82+ graph [ dpi = 200; font = Hack; ];
83+ subgraph cluster_nix {
84+ "nix (пакетный менеджер)" -> "nix (язык)";
85+ "nix (язык)" -> "nix (пакетный менеджер)";
86+ color = blue;
87+ }
88+ cluster_nix -> Disnix;
89+ cluster_nix -> Hydra;
90+ cluster_nix -> nixpkgs -> NixOS -> NixOps;
91+}
92+```
93+
94+
95+# Nix как пакетный менеджер
96+
97+> Nix is a powerful package manager for Linux and other Unix systems that makes package management reliable and reproducible. It provides atomic upgrades and rollbacks, side-by-side installation of multiple versions of a package, multi-user package management and easy setup of build environments.
98+
99+*--- nixos.org/nix*
100+
101+<!--
102+На https://nixos.org/nix заявлено, что nix -- это все-таки пакетный менеджер. С этого компонента мы и начнем.
103+-->
104+
105+## Хранилище (nix store)
106+
107+<!--
108+Центральным местом файловой системы для Nix является Хранилище (nix store). Именно здесь хранятся все файлы, с которыми оперирует наш пакетный менеджер: инструкции сборки и её результаты -- исполняемые файлы, документация, заголовочные файлы, etc.
109+
110+Все элементы директории `/nix/store` имеют одинаковый формат имени -- `<hash>-<name>[-version][-output]`. Хэш вычисляется при добавлении в хранилище или при сборке на основе содержимого файла либо содержимого деривации (инструкции сборки), из которого этот путь был собран.
111+-->
112+
113+
114+> In the beginning was the Store, and the Store was with Nix, and the Store was Nix.
115+
116+*--- Nix manual, 1:1*
117+
118+
119+```bash
120+$ ls /nix/store | wc -l
121+46251
122+$ nix add-to-store nix.conf
123+/nix/store/za34q8y0jcx3qsrnbrd005mh8zcnlrlr-nix.conf
124+```
125+### Формат имени
126+```
127+<hash>-<name>[-version][-output]
128+```
129+Например,
130+```
131+/nix/store/04mm93j20jlnwvhh21db674b3vy6fs54-pandoc-2.7.1-data
132+ | hash | name | ver | out |
133+```
134+
135+## Принцип работы
136+
137+<!--
138+В общих чертах, получение результата любого выражения (в терминологии ПМ -- пакета) на nix состоит из двух этапов -- вычисления (за это отвечает nix как язык), и сборки -- именно эта часть ложится на плечи nix как пакетного менеджера.
139+-->
140+
141+```graphviz
142+digraph {
143+ graph [ dpi = 200; font = Hack; ];
144+ "myname.nix" -> "/nix/store/...-myname.drv" [ label = " Вычисление (nix как язык)" ];
145+ "/nix/store/...-myname.drv" -> "/nix/store/...-myname" [ label = " Сборка (nix как пакетный менеджер)" ];
146+}
147+```
148+
149+## Деривации (derivations, `.drv` files)
150+
151+<!--
152+Для сборки пакетов любому пакетному менеджеру нужны инструкции. Например, ABS (Arch build system) использует PKGBUILD, portage (Gentoo) использует EBUILD, brew использует recepies. Nix не является исключением, и для сборки он использует Деривации (.drv). Пример деривации (с добавленными мною переносами строки и пробелами для улучшения читаемости) -- на слайде.
153+-->
154+
155+
156+### `/nix/store/z3hhlxbckx4g3n9sw91nnvlkjvyw754p-myname.drv`
157+```
158+Derive
159+([("out"
160+ ,"/nix/store/40s0qmrfb45vlh6610rk29ym318dswdr-myname","","")]
161+,[]
162+,[]
163+,"mysystem"
164+,"mybuilder"
165+,[]
166+,[("builder","mybuilder")
167+ ,("name","myname")
168+ ,("out","/nix/store/40s0qmrfb45vlh6610rk29ym318dswdr-myname")
169+ ,("system","mysystem") ] )
170+```
171+
172+## Краткая справка по инструментарию
173+### Собрать (build/realize) деривацию
174+```
175+$ nix-store -r /nix/store/z3hhlxbckx4g3n9sw91nnvlkjvyw754p-myname.drv
176+```
177+### Вычислить (evaluate) и затем собрать содержимое файла `default.nix`
178+```
179+$ nix build -f default.nix # или nix-build default.nix
180+```
181+### Вычислить, собрать и запустить интерактивное окружение
182+```
183+$ nix run -f default.nix # или nix-shell default.nix
184+```
27185
28186# Nix как язык
29187
30−## Nix как язык
188+<!--
189+В общих чертах разобравшись с пакетным менеджером, перейдем к языку. Большая часть синтаксиса, конструкций и идей будет знакома вам по другим языкам, поэтому мы быстро пробежимся по примерам, останавливаясь лишь на уникальных чертах и граблях, на которые легко наступить.
190+-->
191+
31192Рассмотрим основы синтаксиса Nix.
32193
33−### Краткая инструкция для желающих повторить
194+Краткая инструкция для желающих повторить:
34195```bash
35196$ curl https://nixos.org/nix/install | sh
36197<...>
@@ -129,7 +290,7 @@ nix-repl> :t /bin/sh
129290a path
130291nix-repl> ./hello # Относительно текущего .nix файла или PWD для repl
131292/home/balsoft/hello
132−nix-repl> https://typeable.io
293+nix-repl> https://typeable.io # Синтаксический сахар для строк
133294"https://typeable.io"
134295nix-repl> :t https://typeable.io
135296a string
@@ -182,7 +343,7 @@ nix-repl> rec { a = 3; b = a + 4; } # Recursive attrset
182343```
183344
184345
185−## Let и with
346+## Let, with и inherit
186347```
187348nix-repl> let a = 3; b = 4; in a + b
1883497
@@ -191,10 +352,12 @@ nix-repl> let a = 4; b = a + 5; in b # Let definitions are recursive
191352nix-repl> let a = 3; a = 8; in a
192353error: attribute `a' at (string):1:12 already defined at (string):1:5
193354nix-repl> longName = { a = 3; b = 4; }
194−nix-repl> longName.a + longName.b
195−7
196355nix-repl> with longName; a + b
1973567
357+nix-repl> let a = 10; b = 20; in { inherit a; b = b + 1; }
358+{ a = 10; b = 21; }
359+nix-repl> { inherit (s) "123" foo; }
360+{ "123" = "num"; foo = "bar"; }
198361```
199362
200363## Функции (functions)
@@ -225,7 +388,7 @@ nix-repl> greet { name = "ak3n"; }
225388nix-repl> greet { name = "ak3n"; end = "."; }
226389"Hello, ak3n ."
227390nix-repl> greet = { name, end ? "!", ... }: "Hello, ${name} ${end}"
228−nix-repl> greet { name = "ak3n"; end = "."; extra = true; }
391+nix-repl> greet { name = "ak3n"; end = "."; extra = "foo"; }
229392"Hello, ak3n ."
230393nix-repl> foo = {a, ...}@args: args // { a = a + 3; }
231394nix-repl> foo { a = 10; b = 11; }
@@ -233,11 +396,11 @@ nix-repl> foo { a = 10; b = 11; }
233396```
234397
235398## Подключения файлов (import)
236−### number.nix
399+### `number.nix`
237400```
2384013
239402```
240−### function.nix
403+### `function.nix`
241404```
242405a: a + 3
243406```
@@ -250,84 +413,272 @@ nix-repl> f a
250413```
251414
252415## Деривации (derivation)
416+<!--
417+Вот мы и подошли к моменту, когда мы можем сделать свою собственную деривацию! Исследуем встроенную функцию `derivation`. Она возвращает attrset, но nix показывает его как `derivation`. Странные дела!
418+-->
253419```
254420nix-repl> d = derivation {
255421 name = "myname";
256422 builder = "mybuilder";
257− system = "mysystem";
258− }
423+ system = "mysystem"; }
259424nix-repl> :t d
260425a set
261426nix-repl> d
262427«derivation /nix/store/z3hhlxbckx4g3n9sw91nnvlkjvyw754p-myname.drv»
263428```
264−
265−### Лирическое отступление
266−На этом этапе нужно рассмотреть, что же представляет из себя nix-the-package-manager.
267−
268−# Пакетный менеджер Nix
269−## Хранилище (nix store)
270−> In the beginning was the Store, and the Store was with Nix, and the Store was Nix.
271−
272−*-- Nix manual, 1:1*
273−
274−```bash
275−$ ls /nix/store | wc -l
276−46251
277−$ nix add-to-store nix.conf
278−/nix/store/za34q8y0jcx3qsrnbrd005mh8zcnlrlr-nix.conf
279−
280−```
281−
282−## Деривации
283−```bash
284−$ cat /nix/store/z3hhlxbckx4g3n9sw91nnvlkjvyw754p-myname.drv
285−Derive
286−([("out","/nix/store/40s0qmrfb45vlh6610rk29ym318dswdr-myname","","")]
287−,[]
288−,[]
289−,"mysystem"
290−,"mybuilder"
291−,[]
292−,[("builder","mybuilder")
293− ,("name","myname")
294− ,("out","/nix/store/40s0qmrfb45vlh6610rk29ym318dswdr-myname")
295− ,("system","mysystem") ] )
429+## Деривации: сборка
430+<!--
431+Как вы помните, деривации -- это инструкции сборки для nix. Попробуем собрать нашу фейковую деривацию. nix подсказывает, что у нас система не `mysystem`, а `x86\_64-
432+linux`. Исправим это и попробуем ещё раз. Теперь проблема в том, что файла `mybuilder`, который должен собрать наш пакет, не существует. Fail. Остановимся и исследуем `derivation` поподробнее.
433+-->
296434```
297−
298−## Принцип работы
299−```diagram
300−text' s t = text t # fontSize (local s) <> strutY (s * 1.3)
301−
302−
303−sideText' s t = baselineText t # fontSize (local s)
304−
305−box t = text' 0.2 t # fc white # font "hack" <> roundedRect 2 0.4 0.2 # fc blue
306−
307−av = unitY ^* (-0.5)
308−
309−boxes = box "myname.nix" # named "nix"
310− ===
311− (strutY 0.5 <> sideText' 0.1 "Вычисление (nix как язык)")
312− ===
313− box "myname.drv" # named "drv"
314− ===
315− (strutY 0.5 <> sideText' 0.1 "Сборка (nix как пакетный менеджер)")
316− ===
317− box " myname " # named "out"
318−
319−arrows = arrowBetween (0 ^& (-0.2)) (0 ^& (-0.7))
320− <> arrowBetween (0 ^& (-1.1)) (0 ^& (-1.6))
321−
322−example = boxes <> arrows
435+nix-repl> :b d
436+[...]
437+error: a `mysystem' is required to build ..., but I am a `x86_64-linux'
438+nix-repl> d = derivation {
439+ name = "myname";
440+ builder = "mybuilder";
441+ system = builtins.currentSystem; }
442+nix-repl> :b d
443+[...]
444+[...]: executing 'mybuilder': No such file or directory
445+```
446+## Деривации: что внутри?
447+<!--
448+Так как derivation -- это обычный attrset, мы можем исследовать его аттрибуты с помощью встроенного инструментария. Заметим, что `drvAttrs` содержит аргументы, переданные в функцию `derivation`, `out` совпадает с самой деривацией (т.к. на данный момент у нашей деривации только один результат), ну и восхитимся магией типизации на аттрибутах (так вот почему nix так странно себя ведет, показывая derivation вместо сета!). Также заметим, что `toString` превращает в строки только те сеты, которые содержат аттрибут `outPath`.
449+-->
450+```
451+nix-repl> builtins.attrNames d
452+[ "all" "builder" "drvAttrs" "drvPath" "name"
453+ "out" "outPath" "outputName" "system" "type" ]
454+nix-repl> d.drvAttrs
455+{ builder = "mybuilder"; name = "myname"; system = "x86_64-linux"; }
456+nix-repl> (d == d.out)
457+true
458+nix-repl> { type = "derivation"; } # Типизация истинных джентельменов
459+«derivation ???»
460+nix-repl> toString d
461+"/nix/store/qaq9ir9w2a34dzkjmk3igfbibi5q59sd-myname"
462+nix-repl> toString { outPath = "blah"; }
463+"blah"
464+nix-repl> toString { a = 10; }
465+error: cannot coerce a set to a string, at (string):1:1
466+```
467+## Деривации: добавляем зависимости
468+```
469+nix-repl> :l <nixpkgs> # nixpkgs -- это огромная куча дериваций!
470+Added 10082 variables.
471+nix-repl> coreutils
472+«derivation /nix/store/...-coreutils-8.30.drv»
473+nix-repl> toString coreutils
474+"/nix/store/...-coreutils-8.30"
475+nix-repl> d = derivation {
476+ name = "myname";
477+ builder = "${coreutils}/bin/true";
478+ system = builtins.currentSystem; }
479+nix-repl> :b d
480+builder for '...-myname.drv' failed to produce output path '...-myname'
481+```
482+## Деривации: смотрим на зависимости
483+<!--
484+`nix show-derivation` показывает содержимое деривации в виде pretty-printed JSON. Как мы видим, у нас в зависимостях появилась ссылка на coreutils.drv, и builder стал указывать на true.
485+-->
486+```
487+$ nix show-derivation /nix/store/...-myname.drv
488+{
489+ "/nix/store/apvmj79y84wivsnjc2vkv2q79a37nf7l-myname.drv": {
490+ [...]
491+ "inputDrvs": {
492+ "...-coreutils-8.30.drv": [
493+ "out"
494+ ]
495+ },
496+ "builder": "...-coreutils-8.30/bin/true",
497+ [...]
498+ }
499+}
500+```
501+
502+## Деривации: рабочая деривация!
503+<!--
504+Исправим ошибку, которая не дает нам получить нашу первую собирающуюся деривацию! Создадим скрипт `builder.sh`, который создаст outPath. Обратите внимание: мы не будем указывать hashbang для нашего скрипта, потому что даже сам исполняемый файл bash лежит в `/nix/store`, и путь к нему мы можем определить только из nix. Из-за невозможности добавить hashbang, будем запускать наш сборщик как `bash builder.sh`:
505+-->
506+### `builder.sh`
507+```bash
508+declare -xp
509+echo foo > $out
510+```
511+
512+### Уютный `nix repl`
513+```
514+nix-repl> :l <nixpkgs>
515+Added 10082 variables.
516+nix-repl> d = derivation {
517+ name = "foo";
518+ builder = "${bash}/bin/bash";
519+ args = [ ./builder.sh ];
520+ system = builtins.currentSystem; }
521+nix-repl> :b d
522+this derivation produced the following outputs:
523+ out -> /nix/store/82jrv90z3aj1lmzr437jpp7m9krnrrzf-foo
524+```
525+## Деривации: посмотрим на env
526+<!--
527+Посмотрим на то, что показал `declare -xp` (т.е. на переменные окружения, которые доступны внутри сборщика). `nix log` показывает вывод сборщика при сборке определенного пути.
528+
529+* `$HOME` указывает в пустой `/homeless-shelter`
530+* `$PATH` тоже пуст
531+* `$PWD` указывает во временную директорию `/build` (на самом деле она находистся в `/tmp`)
532+
533+Замечу, что все аргументы derivation окажутся в env сборщика.
534+-->
535+```
536+$ nix log /nix/store/...-foo
537+[...]
538+declare -x HOME="/homeless-shelter"
539+declare -x NIX_BUILD_CORES="0"
540+declare -x NIX_BUILD_TOP="/build"
541+declare -x NIX_LOG_FD="2"
542+declare -x NIX_STORE="/nix/store"
543+declare -x PATH="/path-not-set"
544+declare -x PWD="/build"
545+declare -x TEMP="/build"
546+declare -x builder="/nix/store/...-bash-4.4-p23/bin/bash"
547+declare -x name="foo"
548+declare -x out="/nix/store/82jrv90z3aj1lmzr437jpp7m9krnrrzf-foo"
549+declare -x system="x86_64-linux"
550+```
551+
552+
553+## Деривации: опакетим простую программу на C
554+<!--
555+Теперь, когда мы умеем создавать рабочие деривации, добавлять зависимости и передавать произвольные переменные в env их сборщика, попробуем опакетить простую программу на C.
556+На этот раз вылезем из привычного `nix repl` и напишем файл!
557+
558+Для сборки программы нам нужны coreutils (для создания выходной директории) и gcc (для сборки). К счастью, эти (и десятки тысяч других) приложения уже опакечены в nixpkgs. Передадим их деривации как аргументы нашему `derivation`, и они окажутся в env сборщика.
559+-->
560+### `simple.c`
561+```C
562+void main() {
563+ puts("Simple!");
564+}
565+```
566+
567+### `simple_builder.sh`
568+```bash
569+export PATH="$coreutils/bin:$gcc/bin" # Переменные из derivation
570+mkdir -p $out/bin # Создадим выходную директорию
571+gcc -o $out/bin/simple $src # Соберем нашу программу
572+```
573+***
574+### `simple.nix`
575+```
576+with (import <nixpkgs> {});
577+derivation {
578+ name = "simple";
579+ builder = "${bash}/bin/bash";
580+ args = [ ./simple_builder.sh ]; # Сборщик
581+ inherit gcc coreutils; # Зависимости
582+ src = ./simple.c;
583+ system = builtins.currentSystem;
584+}
585+```
586+### Поехали!
587+```
588+$ nix build -f simple.nix
589+[1 built, 0.0 MiB DL]
590+$ ./result/bin/simple
591+Simple!
592+```
593+<!--
594+Успех!
595+-->
596+
597+
598+***
599+### Посмотрим граф зависимостей (`nix-store -q result --graph`)
600+```graphviz
601+digraph G {
602+graph [ dpi=200; ]
603+"/nix/store/p6a11dai9b7xw3xgf44pgyr5kdlnr9rf-simple" [label = "simple", shape = box, style = filled];
604+"/nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27" -> "/nix/store/p6a11dai9b7xw3xgf44pgyr5kdlnr9rf-simple" [color = "black"];
605+"/nix/store/9sll05wmn9b05f0pm1pwfmmq92fg0syh-simple.c" -> "/nix/store/p6a11dai9b7xw3xgf44pgyr5kdlnr9rf-simple" [color = "red"];
606+"/nix/store/d4n93jn9fdq8fkmkm1q8f32lfagvibjk-gcc-7.4.0" -> "/nix/store/p6a11dai9b7xw3xgf44pgyr5kdlnr9rf-simple" [color = "green"];
607+"/nix/store/hlnxw4k6931bachvg5sv0cyaissimswb-gcc-7.4.0-lib" -> "/nix/store/p6a11dai9b7xw3xgf44pgyr5kdlnr9rf-simple" [color = "blue"];
608+"/nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27" [label = "glibc-2.27", shape = box, style = filled];
609+"/nix/store/9sll05wmn9b05f0pm1pwfmmq92fg0syh-simple.c" [label = "simple.c", shape = box, style = filled];
610+"/nix/store/d4n93jn9fdq8fkmkm1q8f32lfagvibjk-gcc-7.4.0" [label = "gcc-7.4.0", shape = box, style = filled];
611+"/nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27" -> "/nix/store/d4n93jn9fdq8fkmkm1q8f32lfagvibjk-gcc-7.4.0" [color = "magenta"];
612+"/nix/store/hlnxw4k6931bachvg5sv0cyaissimswb-gcc-7.4.0-lib" -> "/nix/store/d4n93jn9fdq8fkmkm1q8f32lfagvibjk-gcc-7.4.0" [color = "burlywood"];
613+"/nix/store/iiymx8j7nlar3gc23lfkcscvr61fng8s-zlib-1.2.11" -> "/nix/store/d4n93jn9fdq8fkmkm1q8f32lfagvibjk-gcc-7.4.0" [color = "black"];
614+"/nix/store/sr4253np2gz2bpha4gn8gqlmiw604155-glibc-2.27-dev" -> "/nix/store/d4n93jn9fdq8fkmkm1q8f32lfagvibjk-gcc-7.4.0" [color = "red"];
615+"/nix/store/hlnxw4k6931bachvg5sv0cyaissimswb-gcc-7.4.0-lib" [label = "gcc-7.4.0-lib", shape = box, style = filled];
616+"/nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27" -> "/nix/store/hlnxw4k6931bachvg5sv0cyaissimswb-gcc-7.4.0-lib" [color = "green"];
617+"/nix/store/iiymx8j7nlar3gc23lfkcscvr61fng8s-zlib-1.2.11" [label = "zlib-1.2.11", shape = box, style = filled];
618+"/nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27" -> "/nix/store/iiymx8j7nlar3gc23lfkcscvr61fng8s-zlib-1.2.11" [color = "blue"];
619+"/nix/store/sr4253np2gz2bpha4gn8gqlmiw604155-glibc-2.27-dev" [label = "glibc-2.27-dev", shape = box, style = filled];
620+"/nix/store/5lyvydxv0w4f2s1ba84pjlbpvqkgn1ni-linux-headers-4.19.16" -> "/nix/store/sr4253np2gz2bpha4gn8gqlmiw604155-glibc-2.27-dev" [color = "magenta"];
621+"/nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27" -> "/nix/store/sr4253np2gz2bpha4gn8gqlmiw604155-glibc-2.27-dev" [color = "burlywood"];
622+"/nix/store/f5wl80zkrd3fc1jxsljmnpn7y02lz6v1-glibc-2.27-bin" -> "/nix/store/sr4253np2gz2bpha4gn8gqlmiw604155-glibc-2.27-dev" [color = "black"];
623+"/nix/store/5lyvydxv0w4f2s1ba84pjlbpvqkgn1ni-linux-headers-4.19.16" [label = "linux-headers-4.19.16", shape = box, style = filled];
624+"/nix/store/f5wl80zkrd3fc1jxsljmnpn7y02lz6v1-glibc-2.27-bin" [label = "glibc-2.27-bin", shape = box, style = filled];
625+"/nix/store/681354n3k44r8z90m35hm8945vsp95h1-glibc-2.27" -> "/nix/store/f5wl80zkrd3fc1jxsljmnpn7y02lz6v1-glibc-2.27-bin" [color = "red"];
626+}
627+```
628+
629+# Стандартные паттерны в Nix. nixpkgs.
630+## `mkDerivation`
631+<!--
632+Итак, у нас есть мощный и специализированный язык, а также пакетный менеджер, который предоставляет удобную, изолированную среду для сборки пакетов. Для того, чтобы опакечивать софт было проще, создадим функцию, которая будет обобщать `derivation` и уменьшать бойлерплейт. Назовем эту функцию...
633+-->
634+
635+Неудобства `derivation`
636+
637+- Очень большая часть написанного кода будет повторяться из пакета в пакет
638+ * Распаковка (чаще всего достаточно `tar -xf`)
639+ * Добавление зависимостей (`gcc`, `coreutils`, `bash`, `awk`, `make`, ...)
640+ * Сборка (очень часто можно обойтись `./configure && make`)
641+ * Установка (`make install`)
642+- Требует как минимум два файла -- builder и expression
643+- После вычисления уже нельзя поменять отдельные аргументы, а это может быть удобно
644+
645+Создадим свой `derivation` ~~c блекджеком и шлюхами~~ без этих недостатков!
646+
647+## `mkDerivation`: зависимости и стандартный сборщик
648+<!--
649+Для начала, напишем сборщик в файле `generic-builder.sh`. Сначала поставим свой `$PATH`, собрав его из содержимого `buildInputs`. Затем распакуем архив, переданный нам в `$src` и перейдем в свежесозданную директорию. Там сконфигурируем, соберем и установим наш autotools-проект.
650+-->
651+### `generic-builder.sh`
652+```
653+set -e
654+unset PATH
655+for p in $buildInputs; do
656+ export PATH=$p/bin${PATH:+:}$PATH
657+done
658+tar -xf $src
659+for d in *; do
660+ if [ -d "$d" ]; then
661+ cd "$d"
662+ break
663+ fi
664+done
665+./configure --prefix=$out
666+make
667+make install
668+```
669+***
670+<!--
671+В nix-части напишем функцию, которая создает деривацию с нашим сборщиком и некоторыми пакетами по-умолчанию, которые будут полезны при создании любого пакета.
672+-->
673+### `generic-builder.nix`
674+```
675+{ buildInputs, pkgs, ... }@args:
676+with pkgs;
677+derivation (args // {
678+ buildInputs = buildInputs
679+ ++ [ gnutar gzip gnumake gcc binutils-unwrapped
680+ coreutils gawk gnused gnugrep ];
681+ builder = "${bash}/bin/bash";
682+ args = [ ./generic-builder.sh ];
683+})
323684```
324−
325−*На эту диаграмму ушло четыре с половиной часа. Ненавижу `diagrams`, `diagrams-pandoc` и `svg-fonts`*
326−
327−
328−# Заключение
329−## Ссылки
330−https://nixos.org/
331−https://imgur.com/0gPQ4zg
332−
333−
nix.pdfdeleted

Binary file not shown.

nix.pngdeleted

Binary file not shown.

nix_text.pdfdeleted

Binary file not shown.

nix_text.pptxdeleted

Binary file not shown.

pandoc-filter-graphviz/.gitignorenew file+4
@@ -0,0 +1,4 @@
1+*
2+!.gitignore
3+!*.hs
4+!*.md
pandoc-filter-graphviz/GititPluginGraphviz.hsnew file+6
@@ -0,0 +1,6 @@
1+module GititPluginGraphviz (plugin) where
2+
3+import Network.Gitit.Interface
4+import GraphvizBlock
5+
6+plugin = mkPageTransformM $ liftIO . graphvizBlock (Just (Format "html"))
pandoc-filter-graphviz/GraphvizBlock.hsnew file+43
@@ -0,0 +1,43 @@
1+module GraphvizBlock (graphvizBlock) where
2+
3+import Data.ByteString.Lazy.UTF8 (fromString)
4+import Data.Digest.Pure.SHA (sha256, showDigest)
5+import System.Exit (ExitCode (ExitSuccess))
6+import System.Process (readProcessWithExitCode)
7+import Text.Pandoc
8+
9+graphvizBlock :: Maybe Format -> Block -> IO Block
10+graphvizBlock (Just format) (CodeBlock (id, classes, keyvals) content)
11+ | elem "graphviz" classes =
12+ (readProcessWithExitCode "mkdir" ["-p", "images"] "") >>
13+ case format of
14+ Format "html" ->
15+ do
16+ (ec, out, err) <- readProcessWithExitCode "dot" ["-Tsvg", "-K" ++ layout] content
17+ return $ case ec of
18+ ExitSuccess -> RawBlock (Format "html")
19+ ("<div id=\"" ++ id ++ "\" class=\"graphviz\">" ++ out ++ "</div>")
20+ _ -> CodeBlock (id, classes, keyvals) err
21+ Format "latex" ->
22+ do
23+ (ec, out, err) <- readProcessWithExitCode
24+ "dot2tex" ["--figonly", "--progoptions=-K" ++ layout] content
25+ return $ if length err == 0
26+ then RawBlock (Format "latex") out
27+ else CodeBlock (id, classes, keyvals) err
28+ _ ->
29+ do
30+ (ec, out, err) <- readProcessWithExitCode
31+ "dot" ["-Tpng", "-K" ++ layout, "-o" ++ filename] content
32+ return $ case ec of
33+ ExitSuccess -> Para [Image (id, [], []) [Str content] (filename, id)]
34+ _ -> CodeBlock (id, classes, keyvals) err
35+ where
36+ uniq = ((showDigest . sha256 . fromString) (layout ++ "/" ++ content))
37+ filename = "images/graphviz-" ++ uniq ++ ".png"
38+ where
39+ layout =
40+ case lookup "layout" keyvals of
41+ Just x -> x
42+ _ -> "dot"
43+graphvizBlock _ x = return x
pandoc-filter-graphviz/Main.hsnew file+4
@@ -0,0 +1,4 @@
1+import Text.Pandoc.JSON
2+import GraphvizBlock
3+
4+main = toJSONFilter graphvizBlock
pandoc-filter-graphviz/README.mdnew file+48
@@ -0,0 +1,48 @@
1+# A Pandoc filter for Graphviz
2+
3+This filter provides Graphviz code block support.
4+
5+## Features
6+- This filter changes the way to embed image according to the output format.
7+ - For html, it embeds svg elements directly.
8+ - For pdf/LaTeX, it embeds TikZ figures directly.
9+ - For other formats, it saves png images in working directory and embeds their links.
10+- The layout engine can be specified in block attributes.
11+- For wrong inputs, it embeds the error message as a code block. `pandoc` command does not fail.
12+
13+## Requirements
14+- pandoc
15+- graphviz
16+- dot2tex (pdf/LaTeX support)
17+
18+## Setup
19+
20+### Build filter
21+```
22+$ cd pandoc-filter-graphviz
23+$ ghc --make Main.hs -o pandoc-filter-graphviz
24+```
25+Note: `-dynamic` option is required in some environments.
26+
27+### Add TikZ to LaTeX template
28+You can skip this step if you do not use pdf/LaTeX.
29+
30+- Copy default template
31+ ```
32+ $ mkdir -p ~/.pandoc/templates
33+ $ pandoc -D latex > ~/.pandoc/templates/default.latex
34+ ```
35+
36+- Edit `~/.pandoc/templates/default.latex`
37+ ```latex
38+ ...
39+ \usepackage{tikz} % insert this line
40+
41+ \begin{document}
42+ ...
43+ ```
44+
45+## Usage
46+```
47+$ pandoc -F ./pandoc-filter-graphviz example.md -o example.html
48+```
pandoc-filter-graphviz/example.mdnew file+25
@@ -0,0 +1,25 @@
1+## examples of Graphviz code block
2+
3+### basic usage
4+```graphviz
5+digraph {
6+ a -> b;
7+ b -> c;
8+}
9+```
10+
11+### specify layout engine
12+```{.graphviz layout=neato}
13+digraph {
14+ a -> b;
15+ b -> c;
16+}
17+```
18+
19+### error in code
20+```graphviz
21+digraph {
22+ a -- b;
23+ b -- c;
24+}
25+```
resultdeleted−1
@@ -1 +0,0 @@
1−/nix/store/ama6q6ryavwxazc4p2m526zppbgg5qdh-presentation
shell.nixdeleted−34
@@ -1,34 +0,0 @@
1−with import <nixpkgs> { };
2−let
3− diagrams-pandoc = (haskell.lib.doJailbreak
4− (haskellPackages.diagrams-pandoc.overrideAttrs
5− (_: { meta.isBroken = false; })));
6− ghcDiagrams = ghc.withPackages (ps: with ps; [ diagrams-lib diagrams-builder diagrams-core SVGFonts ]);
7−in stdenv.mkDerivation rec {
8− name = "presentation";
9− buildInputs = [
10− pandoc
11− texlive.combined.scheme-full
12− diagrams-pandoc
13− fontconfig
14− roboto
15− hack-font
16−
17− inotify-tools
18− ];
19−
20− NIX_GHC = "${ghcDiagrams}/bin/ghc";
21− NIX_GHC_LIBDIR = "${ghcDiagrams}/lib/ghc-${ghcDiagrams.version}";
22−
23− FONTCONFIG_PATH = "${/etc/fonts}";
24−
25− src = ./.;
26−
27− phases = [ "buildPhase" ];
28−
29− preferLocalBuild = true;
30−
31− buildPhase = ''
32− pandoc nix.md -t beamer --pdf-engine xelatex --filter diagrams-pandoc -o nix.pdf
33− '';
34−}