summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/hybrid-latex/doc/hybrid.tex
blob: c226321e90328d9df1fbefa599f0974065f6049d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
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
91
92
93
94
95
96
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
\documentclass[12pt]{article}
\usepackage{hybrid}

\begin{document}

\lstset{%
basicstyle={\tts},basewidth={0.50em},
numbers=none,numberstyle=\tiny,numbersep=10pt,
aboveskip=10pt,belowskip=0pt,
frame=single,framesep=2pt,framerule=0pt}

\bgcolour{grey95}

\begin{center}
   {\Large\bf A hybrid LaTeX collection.}\\[20pt]
   {Leo Brewin}\\[5pt]
   {School of Mathematics, Monash University}\\[5pt]
   {\tts Leo.Brewin@monash.edu}\\[5pt]
   {August 2018}\\[10pt]
   {Version 0.1}\\[10pt]
   {\href{https://github.com/leo-brewin/hybrid-latex}{https://github.com/leo-brewin/hybrid-latex}}\\[20pt]
   {\bf\small Abstract}\\[10pt]
   {\small\MyPar{0.80}%
      {This collection of LaTeX packages and Python scripts provides simple
      tools to allow active Python to be embedded in a LaTeX document.
      It does this by defining
      a number of simple macros and Python scripts that build a bridge between
      the output generated by the active code and the LaTeX code. Each language
      is defined independently of the other languages. The scripts and macros
      for one language are almost identical to those for the other languages in
      the collection differing only in the names of the macros and some minor
      language specific tweaks.
      This makes it a simple matter to extend the collection to other languages.}}
\end{center}

\vskip 1cm

\parindent=0pt
\parskip=0pt plus 0pt minus 0pt

\tableofcontents

\vfill

\clearpage

\parindent=0pt
\parskip=8pt plus 2pt minus 1pt

\section{Introduction}

Programs like Mathematica, Maple, Python and so on do a wonderful job of symbolic,
numeric and graphical computations. On the other hand, LaTeX produces exceptional
typeset documents but is less adept at symbolic and other forms of computation. It
is a case of horses for courses. A common approach is to use one or more codes (in
Python, Maple etc.) to do the computations and a separate LaTeX code to collect and
document the results. It seems reasonable then to attempt to consolidate these
separate codes into a single hybrid LaTeX document. That is the main purpose of
this collection -- to provide tools that support active code within a LaTeX
document.

This document describes the CTAN version of this package. An extended version
of the pacakge that allows inclusion of Python, Mathematica, Maple, Matlab and
Cadabra code can be found on the
{\href{https://github.com/leo-brewin/hybrid-latex}{GitHub repository}}.

\section{The pyLaTeX package}

There are other packages that do the same job, such as
\href{https://github.com/gpoore/pythontex}{\PythonTeX} and
\href{https://github.com/sagemath/sagetex}{\SageTeX}. In each case the journey from
source to pdf is similar; the Python code is mined from the LaTeX source, passed
over to Python and the output feed back into the LaTeX source. The packages differ
in both the tools used to mine the Python code and the manner in which the output
is made visible to the LaTeX source.

In both \PythonTeX\ and \SageTeX, the Python code is mined using a first pass of
LaTeX whereas \pyLaTeX\ uses a Python script to do the same job. There are two main
reasons for adopting Python as the code miner. First, it is much easier to extend
\pyLaTeX\ to incorporate other foreign languages (such as Mathematica, Matlab,
Cadabra etc.). Doing so in \PythonTeX\ and \SageTeX\ requires careful tweaking of
the underlying LaTeX class files -- such adventures requires a solid understanding
of the LaTeX programming language and is not for the faint of heart. The second
reason is that LaTeX is not the ideal tool to mine Python (or any other code) from
a LaTeX document. There are much better text processing tools (such as Python) that
can do the same job while being much easier (for the developer) to read, debug and
extend.

There are also some important differences in the way the end user accesses the
Python output for use in the LaTeX source. In \PythonTeX\ and \SageTeX\ the Python
output is saved to a collection of files (roughly one file per Python code block)
while \pyLaTeX\ creates a single file. In all cases the contents of these files are
made available to the LaTeX source by way of special LaTeX macros. The \PythonTeX\
and \SageTeX\ output files are tightly coupled to the original LaTeX source. This
means that their contents can not be easily shared with other LaTeX sources
(without manual intervention). In contrast, the \pyLaTeX\ output is a single file
that contains a collection of LaTeX macros, one for each piece of (tagged) Python
output, that can be read by any other LaTeX source. Thus a user could split a
larger LaTeX source into a collection of smaller sources (e.g., chapters of a book)
with the Python output included as needed. An example of this sharing of Python
output can be found in the examples directory. The file {\tts summary.tex} does no
symbolic calculations of its own but instead pulls in selected parts of the Python
output from other examples in that directory.

Another important difference between \pyLaTeX\ and \PythonTeX\ and \SageTeX\ is
that \pyLaTeX\ uses tags to nominate which pieces of the Python output should be
made available to the LaTeX source. Both \PythonTeX\ and \SageTeX\ allow all Python
output to accessed in the LaTeX source. The problem with that method is that it is
not possible to record the history of a single Python expression. For example, if
the Python code computes the expression {\tts foo} five times then only the fifth
instance will be seen by LaTeX.

\section{Requirements}

\subsection{Latex}
The \pyLaTeX\ package draws on a number of latex packages all of which should be
available in any recent LaTeX distribution. The examples described in this document
were run using the {\tts TeXLive-2018} distribution for macOS.

The \pyLaTeX\ package provides both a normal style file, {\tts pylatex.sty} and a
class file {\tts pylatex.cls}. The preamble to the style file contains the
following declarations.

\vskip 12pt

\begin{latex}
   \usepackage{comment}
   \usepackage{listings}
   \usepackage{keyval}
   \usepackage{etoolbox}
   \usepackage{xcolor}
   \usepackage{pymacros}
\end{latex}

The {\tts pymacros} package is a key part of the \pyLaTeX\ collection as it defines
the core macros for \pyLaTeX.

The class file first includes the style file then executes the following statements

\vskip 12pt

\begin{latex}
   \usepackage[papersize={297mm,210mm},
               hmargin=2cm,tmargin=1.0cm,bmargin=1.5cm]{geometry}
   \usepackage{amsmath}
   \usepackage{amssymb}
   \usepackage{hyperref}
   \usepackage{breqn}
\end{latex}

The extra packages included in the class file are not essential but have proven
useful in many cases and thus are included as a convenient default. Note that the
options to the geometry package sets the output to A4 landscape format. This can be
changed, either by editing the class file or by including a line like the following
somewhere in the preamble of the users document.

\vskip 6pt

\begin{latex}
  \geometry{margin=2.0cm,paperheight=25cm}
\end{latex}

\subsection{Python}
There are no particular requirements on the Python environment in order to use the
\pyLaTeX\ package though the examples listed below do require {\tts sympy} version
1.1.1 or later. The simple measure is that if your embedded Python code can be run
in your normal Python environment then that same code should work equally well
using \pyLaTeX. All of the examples described in this document were run under macOS
using the default Apple Python environment (Python 2.7) as well as under the
Anaconda 5.2 (Python3.6) environment.

\section{Setup}

There is no setup tool as you only have a few files to install. The following files
can be found inside the {\tts Python} directory of the hybrid collection.

\begin{tabular}{rl}
{\tts shell/pylatex.sh}:&Copied to anywhere that is visible on your path.\\[5pt]
{\tts python/pypostproc.py}:&Copied to anywhere that is visible on your path.\\
{\tts python/pypreproc.py}:&Ditto\\
{\tts python/merge-tex.py}:&Ditto\\[5pt]
{\tts latex/pylatex.cls}:&Copied to anywhere that is visible to LaTeX.\\
{\tts latex/pylatex.sty}:&Ditto\\
{\tts latex/pymacros.sty}:&Ditto
\end{tabular}

For example, the shell and Python scripts could be copied to {\tts
\$HOME/local/sh/} while the LaTeX files could be copied to {\tts
\$HOME/tex/inputs/}. Provided those directories are on the appropriate paths (i.e.,
PATH and TEXINPUTS), that should be all that needs doing.

Note that each of the Python scripts uses the following shebang (i.e., the first
line in the file)

\begin{lstlisting}
#!/usr/local/bin/python3
\end{lstlisting}

You may need to change this to match the path to your version of {\tts python3}.

\section{Compiling}
To compile the file {\tts foo.tex} use

\begin{lstlisting}
   pylatex.sh -i foo
\end{lstlisting}

The {\tts pylatex.sh} script will call Pyhton and LaTeX as required to produce the
pdf output. Along the way a number of intermediate files will be created (most of
which will be deleted by default). Using the above command will produce not only
the pdf but also {\tts foo.pytex}. This file contains a list of macros, one for
each \pyLaTeX\ tag in {\tts foo.tex}, that are executed when the \pyLaTeX\ macros
such as {\tts\verb|\py{bah}|} are called (in this case {\tts bah} is a tag
associated with part of the Python code in the {\tts foo.tex} source). This same
file can also be included in other LaTeX files using
{\tts\verb|\input{foo.pytex}|}. This makes the Python output from {\tts foo.tex}
available to other LaTeX files.

Executing {\tts pylatex.sh} with the {\tts -h} flag will produce the following
usage information.

\begin{lstlisting}
   usage : pylatex.sh -i file [-I<path to pymacros.sty>]
                              [-P<path to python>] [-s] [-k] [-x] [-h]
   options :  -i file : source file (without .tex extension)
              -I file : full path to pymacros.sty file
              -P path : where to find the Python binary
              -s : silent, don't open the pdf file
              -k : keep all temporary files
              -x : don't call latex
              -h : this help message
   example : pylatex.sh -i file -P/usr/local/bin/python
\end{lstlisting}

The intermediate files produced by the {\tts -k} option are (excluding the
standard LaTeX files)

\bgroup
\def\MYn{\vrule height  0pt depth  5pt width 0pt}
\def\MYN{\vrule height  0pt depth  0pt width 0pt}
\begin{tabular}{rl}
   {\tts foo.py:}&\MyPar{0.75}%
      {A copy of all the Python code stripped bare of (most) tags.}\\
   {\tts foo_.py:}&\MyPar{0.75}%
      {Similar to {\tts foo.py} but with additional Python code to catch Python
      output for the \pyLaTeX\ tags.}\\
   {\tts foo.pyidx:}&\MyPar{0.75}%
      {An index of all \pyLaTeX\ tags.}\\
   {\tts foo.pytex:}&\MyPar{0.75}%
      {A set of macros, one for each tag, expanding to the Python output.}\\
   {\tts foo.pytxt:}&\MyPar{0.75}%
      {The raw Python output from {\tts foo_.py}.}
\end{tabular}
\egroup

The {\tts -k} option is useful in cases where there is a bug in the users Python
code. This option will force {\tts pylatex.sh} to retain all intermediate files,
in particular the mined Python code {\tts foo.py}. This file can then be debugged
and in turn the original LaTeX source can be corrected.

The {\tts -I} option can be used in cases where the output from {\tts foo.tex} is
intended for use in other LaTeX sources that do not use the \pyLaTeX\ style file
{\tts pylatex.sty}. This could be useful for sharing results with colleagues who
have not installed the \pyLaTeX\ package or when submitting a paper to a journal.
The nett effect of the {\tts -I} option is to prepend the {\tts foo.pytex} file
with the LaTeX definitions for all of the \pyLaTeX\ macros. Another approach would
be to not use the {\tts -I} but share both the {\tts foo.pytex} and {\tts
pymacros.sty} file with colleagues or journals.

The only files that must be kept are {\tts foo.tex} (obviously) and {\tts
foo.pytex}. This pair of files alone is sufficient for successful execution of
LaTeX. The file {\tts foo.pytex} only needs to be recreated (using {\tts
pylatex.sh}) when changes have been made to the Python code in {\tts foo.tex}.

It is important to note that the Python code mined from the LaTeX source will be
written to a single file. Thus it is important that all parts of this file
interact harmoniously. If there is any possibility that one part of the (combined)
code may adversely effect other parts then some action must be taken. One solution
is to use language features of Python to avoid the clash, such as placing
conflicting code in separate functions. Another solution is to move the
conflicting code to separate LaTeX documents, run {\tts pylatex.sh} over each
document, then include the results in the original LaTeX source using
{\tts\verb|\input|} on the corresponding {\tts .pytex} files.

\subsection{Caution}

Be very careful -- each of the above named temporary files will overwrite any
existing files of the same name. An easy road to disaster lies this way. Suppose
you have an existing Python file named {\tts foo.py} and suppose you wish to catch
its output for later use in some other LaTeX document. You might start by creating
a wrapper file, {\tts foo.tex}, such as the following

\vspace{10pt}

\PySetup{action=verbatim}

% note: the * in the 1st column is to ensure the python preprocessor does not respond
%       to any of the \begin{...} or \end{...} lines. The \end{document} line is the
%       real problem as it terminates the preprocessing.

\bgroup
\bgcolour{white}
\begin{latex}
*  \documentclass[12pt]{pylatex}
*  \begin{document}
*     \begin{python}
*        \Input{foo.py}
*     \end{python}
*  \end{document}
\end{latex}
\egroup

\PySetup{action=show}

The {\tts pylatex.sh} will expand the {\tts\verb|\Input{foo.py}|} command to
include the contents of {\tts foo.py}. No damage done -- so far. But now {\tts
pylatex.sh} will read the newly merged file and will create its own version of
{\tts foo.py} without \emph{any} of the \pyLaTeX\ tags. Thus any subsequent
processing of {\tts foo.tex} will \emph{not} capture any Python output -- because
all of the Python tags have been deleted.

\subsection{The pypreproc.py and pypostproc.py scripts}

The job of the {\tts pypreproc.py} script is to harvest the Python code from the
LaTeX source. For a source named {\tt foo.tex} the script could be run using

\begin{lstlisting}
   pypreproc.py -i foo
\end{lstlisting}

This will produce {\tts foo.py, foo_.py} and {\tts foo.pyidx}. The file {\tts
foo.py} is an almost\footnote{It may retain a few comments.} exact copy of the
active Python code while {\tts foo_.py} is a version of {\tts foo.py} containing
extra Python commands to catch the nominated Python output. This file is passed to
Python to create the {\tts foo.pytxt} file which in turn is passed to {\tts
pypostproc.py} using

\begin{lstlisting}
   pypostproc.py -i foo
\end{lstlisting}

which should create the {\tts foo.pytex} file.

The pre and post processor scripts, {\tts pypreproc.py} and {\tts pypreproc.py},
would rarely be used on their own. Though if something fails in the execution of
the {\tts pylatex.sh} script it might prove useful to run these scripts on their
own. Bug reports are always welcome (working on the time proven axiom that no code
is ever bug free).

\subsection{The merge-tex.py script}

A common practice when writing LaTeX documents is to use a driver file to pull in
other smaller LaTeX documents (e.g., a driver for a book could pull in the
chapters as separate documents). Each of the chapters could contain some active
Python code -- so how can such code be made visible to the Python preprocessor
{\tts pypreproc.py}? That is the job of the {\tts merge-tex.py} script. It will
read each file and copy the contents to a single merged file (named {\tts
.merged.tex}). This file is then read by {\tts pypreproc.py}. Not all included
files will contain active Python code so {\tts merge-tex.py} only looks for lines
like {\tts\verb|\Input{foo.tex}|}. Other files included using {\tts\verb|\input|}
or {\tts\verb|\include|} are ignored by {\tts merge-tex.py}. Thus the {\tts
.merged.tex} need not be a faithful copy of the original source -- but that is not
a problem since {\tts .merged.tex} exists solely for {\tts pypreproc.py} to
harvest the active code after which it is no longer used.

The {\tts merge-tex.py} script is language agnostic -- all it does is read its
input and respond to any {\tts \verb|\Input|} lines. If the input file is {\tts
foo.tex} then a merged file {\tts bah.tex} can be created using

\begin{lstlisting}
   merge-tex.py -i foo.tex -o bah.tex
\end{lstlisting}

Note that the {\tts .tex} file extensions \emph{are} required (unlike {\tts
pypreproc.py} and {\tts pypostproc.py}).

Note also that {\tts merge-tex.py} will follow nested files up to 10 deep.

\section{Usage}

Using \pyLaTeX\ entails the addition of user defined tags, in the form of Python
comments, within the LaTeX source. These tags serve to connect the Python output
to the LaTeX source. A typical example is shown in the following code.

\vspace{10pt}

\PySetup{action=verbatim}

% Note: The * in the 1st column is to ensure the python preprocessor does not respond
%       to any of the \begin{...} or \end{...} lines. The \end{document} line is the
%       real problem as it terminates the preprocessing.
%       The * is hidden from LaTeX by way of the listinings option gobble=2.

\bgroup
\bgcolour{white}
\latexstyle
\begin{latex}
*  \documentclass[12pt]{pylatex}
*  \begin{document}
*     \begin{python}
\end{latex}
\pythonstyle
\begin{python}
*        from sympy import *
*        x = Symbol('x')
*        ans    = exp(-x)                # py (ans.01,ans)
*        taylor = ans.series(x, 0, 4)    # py (ans.02,taylor)
*        taylor = ans.series(x, 0, 8)    # py (ans.03,taylor)
\end{python}
\latexstyle
\begin{latex}
*     \end{python}
*     \begin{align*}
*        &\py*{ans.01}\\
*        &\py*{ans.02}\\
*        &\py*{ans.03}
*     \end{align*}
*  \end{document}
\end{latex}
\egroup

\PySetup{action=show}

This will lead to a pdf file that contains not just the Python output but also,
for reference, a copy of the Python source (though this can be suppressed, see the
section \hyperlink{sec:custom}{below} on customisation).

\vspace{5pt}

\begin{python}
   from sympy import *
   x = Symbol('x')
   ans    = exp(-x)                # py (ans.01,ans)
   taylor = ans.series(x, 0, 4)    # py (ans.02,taylor)
   taylor = ans.series(x, 0, 8)    # py (ans.03,taylor)
\end{python}
\vspace{-10pt}
\begin{align*}
   &\py*{ans.01}\\
   &\py*{ans.02}\\
   &\py*{ans.03}
\end{align*}

The key elements to note are the \pyLaTeX\ tags (e.g., {\tts py(ans.01,ans)}) and
the Python environment block. The tags are always part of a Python comment and are
always of the form {\tts py(foo,bah)} where {\tts bah} is a Python symbol (or any
printable entity) and {\tts foo} is the tag (later used in the LaTeX source). The
\pyLaTeX\ tag can be any string of characters from the set {\tts a-zA-Z0-9.\_}. In
the above example there are three tags, {\tts ans.01, ans.02} and {\tts ans.03}.
The dot postfix is not essential but it provides a simple way to record a sequence
of Python outputs. These tags are used later in the body of the LaTeX code and are
accessed in the above example using the \pyLaTeX\ macro {\tts\verb|\py|}. This
macro takes just one argument namely the corresponding \pyLaTeX\ tag. The macro
{\tts\verb|\py{foo}|} will expand to the Python output for the tag {\tts foo}.
Other macros are provided such as {\tts\verb|\py*{foo}|} which will expand to
{\tts foo := } followed by the Python output. The full set of macros are described
in the section \hyperlink{sec:pylatexmacros}{LaTeX macros}.

The \pyLaTeX\ tags can be placed anywhere within the Python block. In the above
example the tags were placed on the same line as the Python code. This is just for
aesthetic effect -- they could equally well have been located on following lines.
The \pyLaTeX\ tags should be unique within the LaTeX file. If the same tag name is
used more than once the output associated with that tag will be from the last
instance of that tag.

Note that the {\tts pypreproc.py} script will interpret {\tts py(foo)} as a
shorthand for {\tts py(foo,foo)}.

\subsection{Undefined tags}

If any of the \pyLaTeX\ macros are called for a tag that was \emph{not} defined
then \hbox{(??)} will be printed. Note that this may cause a LaTeX syntax error
when the \hbox{(??)} appears in an unexpected context (e.g., in cases where the
output of {\tts\verb|\py|} was expected to expand to one or more
{\tts\verb|\\|}'s).

\subsection{Tagged blocks}

There is a second form of tag, known as a tagged block, in which a block of Python
code is enclosed in a matching {\tts\verb|# pyBeg(foo)|},
{\tts\verb|# pyEnd(foo)|} pair. An example of a tagged block can be seen in the
following code. The tag is given the name {\tts Pascal} and can be accessed in the
LaTeX code using any of the \pyLaTeX\ macros, in this case {\tts\verb|\py|}. The
intention of tagged blocks is that they can be used to capture any Python output
generated within the tagged block (except the output that is caught by simple tags
such as shown in the previous example).

Here is a short example\footnote{This example is very \emph{inefficient} as it
uses recursive calls for \emph{every} element in the table.} that demonstrates the
use of a single tagged block.

\vspace{10pt}

\PySetup{action=verbatim}

% note: the * in the 1st column is to ensure the python preprocessor does not respond
%       to any of the \begin{...} or \end{...} lines. The \end{document} line is the
%       real problem as it terminates the preprocessing.

\bgroup
\bgcolour{white}
\latexstyle
\begin{latex}
*  \documentclass[12pt]{pylatex}
*  \begin{document}
*
*     \begin{python}
\end{latex}
\pythonstyle
\begin{python}
*        def build(n):
*            if n==0:
*               return [1]
*            else:
*               P = build(n-1)
*               return [1] + [P[i]+P[i+1] for i in range(n-1)] + [1]
*
*        def display(n):
*            for i in range(n):
*                ans = ""
*                for j in range(0,len(build(i))):
*                   ans = ans + "\m{" + str(build(i)[j]) + "}"
*                print (ans+"\cr")
*
*        # pyBeg (Pascal)
*        display(7)
*        # pyEnd (Pascal)
\end{python}
\latexstyle
\begin{latex}
*     \end{python}
*
*     \def\m#1{\hbox to 1cm{\hfill #1\hfill}}
*     \halign{\hbox to \textwidth{\hfill#\hfill}\cr\py{Pascal}}
*
*  \end{document}
\end{latex}
\egroup

\PySetup{action=hide}

\begin{python}
  def build(n):
      if n==0:
         return [1]
      else:
         P = build(n-1)
         return [1] + [P[i]+P[i+1] for i in range(n-1)] + [1]

  def display(n):
      for i in range(n):
          ans = ""
          for j in range(0,len(build(i))):
             ans = ans + "\m{" + str(build(i)[j]) + "}"
          print (ans+"\cr")

  # pyBeg (Pascal)
  display(7)
  # pyEnd (Pascal)
\end{python}

\clearpage

\PySetup{action=show}

The output of the above code (excluding the echoed Python code) is Pascal's triangle (as expected).

\def\m#1{\hbox to 1cm{\hfill #1\hfill}}
\halign{\hbox to \textwidth{\hfill#\hfill}\cr\py{Pascal}}

All Python code must be contained within the Python environment block, i.e.,
within a {\tts\verb|\begin{python}|} {\tts\verb|...|} {\tts\verb|\end{python}|}
pair. There is no facility to allow \emph{inline} execution of Python code (though
this is allowed in other packages, notably \PythonTeX). The reason for taking this
approach was to force a clear separation between native LaTex code and active
Python blocks. This makes it easier to locate the Python code. If an inline
calculation is needed then it is a simple matter of including the Python code in a
Python block and using a tag to catch and display the result.

Tagged blocks can be nested (though it is not clear what use this might serve) and
they can contain simple tags. The simple tags will always take priority over
tagged blocks in capturing Python output. Tagged blocks should respect the usual
rules of begin-end blocks -- they can nested but they must not overlap. The Python
pre and post processors (within the {\tts pylatex.sh} script) will report errors
when tagged blocks are not properly structured (i.e., overlapping, unmatched {\tts
pyBeg/pyEnd} items etc.).

\subsection{LaTeX macros}
\hypertarget{sec:pylatexmacros}{}

The \pyLaTeX\ package provides a number commands for typesetting tagged expressions.

\newbox\Slashpya
\setbox\Slashpya=\hbox{\tts\verb|\py{foo}|}

\newbox\Slashpyb
\setbox\Slashpyb=\hbox{\tts\verb|\py*{foo}|}

\newbox\SlashPya
\setbox\SlashPya=\hbox{\tts\verb|\Py{foo}|}

\newbox\SlashPyb
\setbox\SlashPyb=\hbox{\tts\verb|\Py*[bah]{foo}|}

\newbox\Slashhfill
\setbox\Slashhfill=\hbox{\tts\verb|[\hfill]|}

\newbox\SlashPySetup
\setbox\SlashPySetup=\hbox{\tts\verb|\PySetup{key=value}|}

\newbox\SlashDmatha
\setbox\SlashDmatha=\hbox{\tts\verb|\Dmath[bah]{foo}|}

\newbox\SlashDmathb
\setbox\SlashDmathb=\hbox{\tts\verb|\Dmath*[bah]{foo}|}

\newbox\SlashttTag
\setbox\SlashttTag=\hbox{\tts\verb|\ttTag{foo}|}

\newbox\SlashInput
\setbox\SlashInput=\hbox{\tts\verb|\Input{foo.tex}|}

\begin{longtable}{rl}
   {\copy\Slashpya}&\MyPar{0.70}{%
       Display the value of {\tts foo} without any additional decorations.}\\
   {\copy\Slashpyb}&\MyPar{0.70}{%
       Similar to \copy\Slashpya\ but adds {\tts foo$\colonEq$}
       immediately to the left of {\tts foo}.}\\
   {\copy\SlashPya}&\MyPar{0.70}{%
       Display the value of {\tts foo} and set the equation tag to be ({\tts
       foo}). Since this macro creates its own equation tag it should not be used
       in any maths environment that also creates an equation tag (e.g., {\tts
       align, equation} etc.) It can not be used in any of the {\tts breqn}
       environments ({\tts breqn} will report a package error).}\\
   {\copy\SlashPyb}&\MyPar{0.70}{%
       Use this version of \copy\SlashPya\ in any of the (starred) {\tts breqn}
       environments. The optional argument {\tts [bah]} specifies the spacing
       between the end of {\tts foo} and the right hand edge of the tag. The
       default is \copy\Slashhfill\ which forces the tag to the far right.}\\
   {\copy\SlashDmatha}&\MyPar{0.70}{%
       This is a shortcut for the {\tts dmath} environment. The optional and
       required arguments of \copy\SlashDmatha\ are passed onto the {\tts dmath}
       environment. See page (\pageref{ex:Dmath}) for an example.}\\
   {\copy\SlashDmathb}&\MyPar{0.70}{%
       This is similar to \copy\SlashDmatha\ but with the one small change that it
       applies to the {\tts dmath*} environment.}\\
   {\copy\SlashttTag}&\MyPar{0.70}{%
       This is a simple macro that typesets a tag name such as {\tts foo} in a
       small typewriter font enclosed in matching parenthesis, e.g., ({\tts
       foo}).}\\
   {\copy\SlashPySetup}&\MyPar{0.70}{%
       This command takes one argument in the form of a key=value pair. Its
       purpose is to set global options for the following Python blocks. The
       current list of options is limited to one key with three values. These are
       described in the following section.}\\
\end{longtable}

\subsection{Custom formats}
\hypertarget{sec:custom}{}

The \pyLaTeX\ package allows for some minor customisation of the formatting of the Python code. The macro
{\tts\verb|\PySetup|} can be used to set the preferred options using key-value pairs. There is only
one key as described in the following table.

\begin{tabular}{rl}
   {\tts action=show}&%
         \MyPar{0.70}{Make the Python code visible and active (i.e., cancel the
         {\tts hide} and {\tts verbatim} actions).}\\
   {\tts action=hide}&%
         \MyPar{0.70}{Hide the python code but still allow the Python code to be
         active.}\\
   {\tts action=verbatim}&%
         \MyPar{0.70}{This will make the Python code inactive (i.e., it will not
         be passed to Python).}\\[5pt]
\end{tabular}

Multiple calls to {\tts\verb|\PySetup|} can be made and apply to all subsequent
Python environments or until changed by a later call to {\tts\verb|\PySetup|}. The
default value is {\tts action=show}.

The \pyLaTeX\ package uses the {\tts listings} package which allows further
formatting changes to be made. For example, to add line numbers and a shaded
background to the Python code use

\begin{lstlisting}
   \lstset{numbers=left,backgroundcolor=\color{lightgrey}}
\end{lstlisting}

Many other options are available, see the {\tts listings} documentation for full
details.

\subsection{Python indentation}

Python has very strict (but simple) indentation rules that must be observed not
only within a single Python block but across all Python blocks. Why? Because all
of the Python blocks will be collected into a separate single Python code and that
code must observe the Python indentation rules.

\subsection{Error reporting}

None of the packages in this collection treat errors from the active code with any
degree of aplomb -- at best they report that an error occurred, at worst they
silently ignore the error leaving {\tts pdflatex} to pick up the pieces. This is
far from ideal. If in doubt, run the main script (e.g., {\tts pylatex.sh}) using
the {\tts -k -x} command line options then inspect the file {\tts foo.pytxt} for
any errors. If there are errors then you can debug the extracted code {\tts
foo.py} later returning the corrected code back to the LaTeX source {\tts foo.tex}.

\subsection{Matplotlib and macOS}

There is a well known issue when using Matplotlib on macOS where some Matplotlib
codes may fail. The
\href{https://matplotlib.org/faq/osx_framework.html}{Matplotlib documentation}
provides a number of suggestions including to use {\tts pythonw} rather than {\tts
python}. For such cases use the {\tts -P} flag to set the path to the {\tts
pythonw} command when invoking the {\tts pylatex.sh}. This has been tried and
tested under the Anaconda Python3 environment for macOS.

\section{Examples}

The {\tts examples} directory contains a small collection of complete \pyLaTeX\
codes that showcase the various features of the \pyLaTeX\ package. The Python
source contains inline comments that result in long lines of text that do not
comfortably fit on an A4 page in portrait mode. Thus most of the examples have
been formatted in A4 landscape mode (this is the default setting for the \pyLaTeX\
class). Consequently it is not practical to include those examples in this file.
The following table provides a very brief summary of each example (with hyperlinks
to the corresponding pdf's in {\tts ../python/examples/}).

\newbox\exa
\setbox\exa=\hbox{\href{../python/examples/example-01.pdf}{Example 1}}

\newbox\exb
\setbox\exb=\hbox{\href{../python/examples/example-02.pdf}{Example 2}}

\newbox\exc
\setbox\exc=\hbox{\href{../python/examples/example-03.pdf}{Example 3}}

\newbox\exd
\setbox\exd=\hbox{\href{../python/examples/example-04.pdf}{Example 4}}

\newbox\exe
\setbox\exe=\hbox{\href{../python/examples/example-05.pdf}{Example 5}}

\newbox\exf
\setbox\exf=\hbox{\href{../python/examples/example-06.pdf}{Example 6}}

\newbox\exg
\setbox\exg=\hbox{\href{../python/examples/example-07.pdf}{Example 7}}

\newbox\exh
\setbox\exh=\hbox{\href{../python/examples/example-08.pdf}{Example 8}}

\newbox\exi
\setbox\exi=\hbox{\href{../python/examples/example-09.pdf}{Example 9}}

\newbox\exz
\setbox\exz=\hbox{\href{../python/examples/summary.pdf}{Summary}}

\begin{longtable}{rl}
   \box\exa:&\MyPar{0.80}%
      {This is a collection of basic mathematical computations. It contains
      examples of simple tags and tagged blocks.}\\
   \box\exb:&\MyPar{0.80}%
      {This is the first of two examples drawn from the \PythonTeX\ website
      \href{https://github.com/gpoore/pythontex/}{(here)}. It shows a nice example
      of using a tagged block.}\\
   \box\exc:&\MyPar{0.80}%
      {This is the second example taken from the \PythonTeX\ website
      \href{https://github.com/gpoore/pythontex/}{(here)}. It shows a step-by-step
      computation of a simple triple integral.}\\
   \box\exd:&\MyPar{0.80}%
      {This example shows how {\tts Matplotlib} and friends can be used to
      construct a simple xy-plot.}\\
   \box\exe:&\MyPar{0.80}%
      {This example shows how problems with the placement of equation tags can be
      resolved by careful choice of the optional argument to
      {\copy\SlashPyStar}.}\\
   \box\exf:&\MyPar{0.80}%
      {This is a simple example that uses Python to compute the first few
      iterations of a Newton-Raphson method.}\\
   \box\exg:&\MyPar{0.80}%
      {This example contains a single tag-block. It captures basic system data.}\\
   \box\exh:&\MyPar{0.80}%
      {This example shows how to completely hide the Python code as well a trick
      for hiding just the tags.}\\
   \box\exi:&\MyPar{0.80}%
      {This example is a proof of concept example. It shows one approach for
      passing LaTeX information to the Python code. The code is not elegant but it
      does the job.}\\
   \box\exz:&\MyPar{0.80}%
      {There is no Python code in this example. Instead, the results from the
      above examples are included by inputting the corresponding {\tts .pytex}
      file.}
\end{longtable}

\section{Splitting long lines using breqn}

On some occasions the output from a computation may be too long to fit comfortably
on one line. In such cases some form of line splitting is required. A less than
ideal approach is to manually edit the output by inserting carefully chosen line
breaks. Not only is this approach tedious and inelegant it also requires the line
breaks to be reset whenever the document format is changed (e.g., from A4 to
letter size) or when some of the computations are changed (e.g., showing twice as
many terms in a series expansion).

A better approach is to use the {\tts breqn} package which uses sophisticated
algorithms to find good line breaks with minimal input from the user. In many
cases {\tts breqn} will produce an acceptable output. But it is not without its
own limitations\footnote{The {\tts breqn} documentation does note that it is a
work in progress.} as some of the following examples will demonstrate. The fact is
that there are no algorithms that will guarantee prefect line splitting as there
will always be some subjective element in what constitutes a good line break. The
following series of examples are intended as guide of what to expect when using
{\tts breqn} and also to demonstrate some possible remedies.

Here is a simple example based on a truncated Taylor series expansion of $1/(1+x)$
around $x=0$.
\bgroup
\lstset{gobble=2,numbers=left}
\begin{python}
   from sympy import *
   x = Symbol('x')
   ans    = 1/(1+x)                 # py (fun,ans)
   taylor = ans.series(x, 0,  6)    # py (ans.101,taylor)
   taylor = ans.series(x, 0,  9)    # py (ans.102,taylor)
   taylor = ans.series(x, 0, 12)    # py (ans.103,taylor)
   taylor = ans.series(x, 0, 15)    # py (ans.104,taylor)
   taylor = ans.series(x, 0, 30)    # py (ans.105,taylor)
\end{python}
\egroup
For an expansion with only a handful of terms the usual {\tts align} environment
produces an acceptable output as demonstrated in the following code and output.

\vskip 12pt

\bgroup
\bgcolour{white}
\begin{latex}
   \begin{align*}
      \py{fun} &= \py {ans.101}\tag{\ttTag{ans.101}}\\
               &= \py {ans.102}\tag{\ttTag{ans.102}}\\
               &= \py {ans.103}\tag{\ttTag{ans.103}}
   \end{align*}
\end{latex}
\egroup
\begin{align*}
   \py{fun} &= \py {ans.101}\tag{\ttTag{ans.101}}\\
            &= \py {ans.102}\tag{\ttTag{ans.102}}\\
            &= \py {ans.103}\tag{\ttTag{ans.103}}
\end{align*}
In this and the following examples the equation tags have been explicitly matched
to the corresponding {\tts sympy} expressions. This makes it somewhat easier to
follow the progress of a computation. The normal equation numbering (e.g., (1),
(2) etc.) can be recovered by deleting the calls to {\tts\verb!\tag{...}!}. The
{\tts\verb|\ttTag|} macro, defined in the \pyLaTeX\ package, does as its name
suggests -- typesets the tag in the {\tts\verb|\tt|} font.

The above works well for short expressions but for longer expressions it is much
better to use the {\tts breqn} package. The key points to note in the following
example are the use of the {\tts dmath} environment and the manner in which the
equation tags have been set.

\vskip 12pt

\bgroup
\bgcolour{white}
\begin{latex}
   \usepackage{breqn}
   ...
   \begin{dmath}[number={\ttTag{ans.105}}]
      \py {fun} = \py {ans.105}
   \end{dmath}
\end{latex}
\egroup
The corresponding output is
\Dmath[number={\ttTag{ans.105}}]{\py{fun} = \py{ans.105}}

The {\tts dmath} environment is one of a number environments provided by the {\tts
breqn} package. Its job is to chose sensible line breaks that produce a pleasant
output (though what constitutes \emph{pleasant} may be up for debate). Note that
all of the {\tts breqn} environments do \emph{not} support the {\tts\verb!\tag!}
macro for setting equation tags. The only way to do so is through the
{\tts\verb!number={...}!} optional argument as shown in the above example. To
suppress the equation label use the {\tts dmath*} environment.

\bgroup
\advance\leftskip1cm
\advance\rightskip1cm
\hypertarget{landing}{{\bf Note:}}
This sentence may seem out of place but its purpose is to demonstrate a claim made
later is this documentation that, with a suitably modified label macro, the {\tts
hyperref} package can be used to jump to the correct page when clicking on a
hyperlink for an equation. For example, clicking on this link \eqref{eq:target}
should take us to page \pageref{eq:target}. But now, back to the main discussion.
\par
\egroup

The {\tts breqn} package also provides a {\tts dgroup} environment. This can be
used to group a sequence of {\tts dmath} environments to align the output on a
targeted symbol (usually the first equals sign). Here is a short example

\vskip 12pt

\bgroup
\bgcolour{white}
\lstlatex{numbers=left}
\begin{latex}
   \begin{dgroup}
      \begin{dmath}[number={\ttTag{ans.103}}] \py {fun}  = \py {ans.103} \end{dmath}
      \begin{dmath}[number={\ttTag{ans.104}}]         {} = \py {ans.104} \end{dmath}
      \begin{dmath}[number={\ttTag{ans.105}}]         {} = \py {ans.105} \end{dmath}
   \end{dgroup}
\end{latex}
\egroup

and here is the corresponding output
\begin{dgroup}
   \begin{dmath}[number={\ttTag{ans.103}}] \py {fun}  = \py {ans.103} \end{dmath}
   \begin{dmath}[number={\ttTag{ans.104}}]         {} = \py {ans.104} \end{dmath}
   \begin{dmath}[number={\ttTag{ans.105}}]         {} = \py {ans.105} \end{dmath}
\end{dgroup}

There are a few points to be made here. First is the less then ideal placement of
tags. Second is the somewhat ungainly syntax. Both of these points will be
discussed in more detail shortly. Next, notice the {\tts\verb!{}!} preceding the
equal signs in lines 3 and 4. This supplies an empty left hand side for each
equation and is essential to ensure proper alignment (on the equals sign) across
all three equations. Unlike other maths environments, {\tts breqn} does not allow
you to specify which symbol to use as the alignment target -- that choice is made
deep within the inner workings of {\tts dmath} and friends. It will choose symbols
including {\tts\verb!=-+:()!}. If you wish to tell {\tts dmath} to not use a
particular symbol you can wrap that symbol inside {\tts\verb!\hiderel!} as in the
following example.

\vskip 12pt

\bgroup
\bgcolour{white}
\begin{latex}
   \begin{dgroup*}
      \begin{dmath*} f(x) \hiderel{=} \py {fun} = \py {ans.101} \end{dmath*}
      \begin{dmath*}                         {} = \py {ans.102} \end{dmath*}
   \end{dgroup*}
\end{latex}
\egroup
\begin{dgroup*}
   \begin{dmath*} f(x) \hiderel{=} \py {fun} = \Py*{ans.101} \end{dmath*}
   \begin{dmath*}                         {} = \Py*{ans.102} \end{dmath*}
\end{dgroup*}

Consider now the earlier example in which the equation tags were not well placed
and where the syntax was described as ungainly. The syntax can be tidied slightly
using one of the features of the {\tts breqn} package -- it allows the {\tts
dmath} and {\tts dmath*} environments to be wrapped in user defined macros such as

\vskip 12pt

\bgroup
\bgcolour{white}
\begin{latex}
   \newcommand*{\Dmath}[2][]{\begin{dmath}[#1]#2\end{dmath}}
\end{latex}
\egroup
This defines {\tts\verb!\Dmath!} as a macro that takes one required argument and
one optional argument (both of which are passed on to {\tts dmath}). It is not a
huge saving but even so it does save a few keystrokes. Here is one of the previous
examples rewritten using {\tts\verb!\Dmath!}.

\vskip 12pt

\bgroup
\bgcolour{white}
\begin{latex}
   \begin{dgroup}
      \Dmath[number={\ttTag{ans.103}}]{ \py {fun}  = \py {ans.103} }
      \Dmath[number={\ttTag{ans.104}}]{         {} = \py {ans.104} }
      \Dmath[number={\ttTag{ans.105}}]{         {} = \py {ans.105} }
   \end{dgroup}
\end{latex}
\egroup
The \pyLaTeX\ package defines {\tts\verb|\Dmath|} for the {\tts dmath} environment
as well as {\tts\verb|\Dmath*|} as a shortcut for the {\tts dmath*} environment.

The use of {\tts\verb|\Dmath*|} does save some keystrokes but it does not fix the
problem where the text is obscured by the tag. There seems to be no simple way to
tell {\tts breqn} to avoid such problems while retaining {\tts breqn}'s method of
placing the tags. The {\tts\verb|\Py*|} macro avoids this problem by presenting
{\tts dmath*} with a concatenated string built from the text (e.g., the output of
{\tts\verb|\py{foo}|}), some flexible white space (usually {\tts\verb|\hfill|})
and the tag (e.g., {\tts foo}). This string is processed by {\tts dmath*} and line
splits are inserted at its discretion. This will guarantee that the all of the
text and the tag will be displayed. The user defined whitespace can always be
chosen so that the tag does not overlap the text. This is a bare minimum of what
could be deemed an acceptable output -- non overlap of the text and the tag. The
output might not be optimal but at least it is readable. Here is the same example
as above but this time using {\tts\verb|\Py*|} to display the text and the tags.

\vskip 12pt

\pglabel{ex:Dmath}
\bgroup
\bgcolour{white}
\begin{latex}
   \begin{dgroup*}
      \Dmath*{ \py {fun}  = \Py* {ans.103} }
      \Dmath*{         {} = \Py*[\hskip 2cm] {ans.104} }
      \Dmath*{         {} = \Py*[\hskip 3cm] {ans.105} }
   \end{dgroup*}
\end{latex}
\egroup
\begin{dgroup*}
   \Dmath*{ \py {fun}  = \Py* {ans.103} }
   \Dmath*{         {} = \Py*[\hskip 2cm] {ans.104} }
   \Dmath*{         {} = \Py*[\hskip 3cm] {ans.105} }
\end{dgroup*}
The whitespace between the text and the tag is passed through the optional
argument of {\tts\verb|\Py*|} with the default set as {\tts\verb|\hfill|}. The
inner workings of {\tts\verb|\Py*|} sets the tag using {\tts\verb|\llap|} and thus
the whitespace optional argument measures the space between the right hand edge of
the tag and left hand end of the equation text. Note also that this example uses
the starred version of {\tts dgroup} and {\tts\verb|\Dmath*|}. This is to ensure
that {\tts breqn} plays no part in forming the tag (as that is handled by
{\tts\verb|\Py*|}).

The \pyLaTeX\ package defines both {\tts\verb|\Py|} and {\tts\verb|\Py*|}. The
{\tts\verb|\Py|} macro is intended for use only in the starred maths environments
(e.g., {\tts align*, equation*} etc.). Like {\tts\verb|\Py*|}, it also sets the
equation tag to match the expression but it does so using standard methods
(internally it calls {\tts\verb|\tag|}). This last point (that {\tts\verb|\Py*|}
uses {\tts\verb|\tag|}) also means that it can not be used in any of the {\tts
breqn} environments (doing so will cause LaTeX to issue a {\tts breqn} package
error).

Both {\tts\verb|\Py|} and {\tts\verb|\Py*|} support the usual method of labelling
and referencing equations using {\tts\verb|\label{foo}|} and
{\tts\verb|\ref{foo}|}. However, there are good reasons to use a modified version
of the {\tts\verb|\label|} macro (as described below) to improve the accuracy of
the label-reference pairs when using hyperlinks (i.e., so that the reference
points to the correct page where the label was issued).

\subsection{Hyperref, hyperlinks and breqn}

The {\tts breqn} package does support the {\tts hyperref} package though as
discussed
\href{https://tex.stackexchange.com/questions/193380/hyperref-pageref-links-point-t
o-first-page}{(here)} the hyperlinks to an equation may not work as expected
(clicking on a link may take you to the wrong page). The suggested fix is to
define equation labels via a modified label macro such as the following

\vskip 12pt

\bgroup
\bgcolour{white}
\begin{latex}
   \newcommand{\pglabel}[1]{\phantomsection\label{#1}}
\end{latex}
\egroup
An example of its use might be

\vskip 12pt

\bgroup
\bgcolour{white}
\begin{latex}
   \begin{dmath}[number={\ttTag{ans.105}}]
      \py{fun} = \py{ans.105} \pglabel{eq:target}
   \end{dmath}
\end{latex}
\egroup
\begin{dmath}[number={\ttTag{ans.105}}]
   \py{fun} = \py{ans.105} \pglabel{eq:target}
\end{dmath}
Then clicking on the link defined by {\tts\verb!\ref{eq:target}!} will bring the
reader to this page. An example of such a link was seen earlier in this document
(click \hyperlink{landing}{here} to jump back to that page).

\section{Licence}

This software is licensed under the MIT License (MIT). Please see the {\tts
LICENCE.txt} file for more information.

\section{Version history}
\leftline{\bf v0.1 (2018/08/22)}% 22 Aug 2018
\begin{itemize}
\item Initial public release.
\end{itemize}

\end{document}