diagrams-haddock
Preprocessor for embedding diagrams in Haddock documentation
http://projects.haskell.org/diagrams/
Version on this page: | 0.3.0.10@rev:1 |
LTS Haskell 6.35: | 0.3.0.10@rev:1 |
Stackage Nightly 2017-01-17: | 0.4.0.1 |
Latest on Hackage: | 0.4.1.2@rev:1 |
diagrams-haddock-0.3.0.10@sha256:c77d5d5a908d03ba9fc545f977ced5d393a22e6de5b9d00deb4fb7fddd4a366d,3939
Module documentation for 0.3.0.10
- Diagrams
diagrams-haddock
diagrams-haddock
is a preprocessor which allows embedding images
generated using the diagrams
framework within Haddock
documentation. The code to generate images is embedded directly
within the source file itself (and the code can be included in the
Haddock output or not, as you wish). diagrams-haddock
takes care of
generating SVG images and linking them into the Haddock output.
Installing
Just cabal install diagrams-haddock
. If you have any trouble, ask
in the #diagrams
freenode IRC channel, or file a ticket on the
bug tracker.
On the design of diagrams-haddock
Before getting into the details of using diagrams-haddock
, it should
be noted that diagrams-haddock
has been carefully designed so that
you only have to maintain a single copy of your source files. In
particular, you do not have to maintain one copy of your source
files with embedded diagrams code and another copy where the diagrams
code has been replaced by images. If you find yourself scratching
your head over the quirky ways that diagrams-haddock
works, now you
will know why.
An important caveat
diagrams-haddock
modifies files in place! While we have worked
hard to ensure that it cannot make catastrophic changes to your files,
you would be wise to only run diagrams-haddock
on files under
version control so you can easily examine and (if necessary) undo
the changes it makes. (Of course, being a conscientious developer,
you would never work with source files not under version control,
right?)
Adding diagrams to source files
Haddock supports inline links to images with the syntax <<URL>>
. To
indicate an image which should be automatically generated from some
diagrams code, use the special syntax
<<URL#diagram=name&key1=val1&key2=val2&...>>
. The URL will be
automatically filled in by diagrams-haddock
, so when you first
create an inline image placeholder you can simply omit it (or put any
arbitrary text in its place). For example, you might write
<<#diagram=mySquare&width=200&height=300>>
indicating an image which should be generated using the definition of
mySquare
, with a maximum width of 200 and maximum height of 300.
(Incidentally, this syntax is used because everything following the
#
symbol will be ignored by browsers.)
Continuing with the above example, you must also provide a definition
of mySquare
. You must provide it in a code block, which must be set
off by bird tracks (that is, greater-than symbols followed by at least
one space). For example,
-- > mySquare = square 1 # fc blue # myTransf
-- > myTransf = rotateBy (1/27)
In this case, mySquare
has type Diagram SVG R2
. Additionally, you
may give identifiers of type IO (Diagram SVG R2)
; in that case the
IO
action will be run to determine the diagram to render. This can
be useful, for example, when producing a diagram built from some
external data or using randomness.
You can choose to have the code block included in the Haddock output
or not, simply by putting it in a Haddock comment or not. Note that
the code block defining mySquare
can be anywhere in the same file;
it does not have to be right before or right after the diagram URL
referencing it.
Code block dependency analysis
diagrams-haddock
does a simple dependency analysis to determine
which code blocks should be in scope while compiling each diagram.
First, it locates a code block containing a binding for the requested
diagram name. Then, it pulls in any code blocks containing bindings
for identifiers referenced by this code block, and so on transitively.
(Note that this analysis is overly simplistic and does not take things
like shadowing into account; this may sometimes cause additional code
blocks to be included which would not be included with a more careful
analysis.)
This has a few implications. First, code blocks containing irrelevant bindings will not be considered. It is common to have code blocks which are intended simply to show some example code—they may not even be valid Haskell. However, as long as such code blocks do not contain any bindings of names used by a diagram, they will be ignored. For example:
-- The algorithm works by doing the equivalent of
--
-- > rep = uncurry replicate
-- >
-- > algo = map rep . zip [1..]
--
-- as illustrated below:
--
-- <<#diagram=algoIllustration&width=400>>
--
-- > algoIllustration = ...
The first code block shown above (beginning rep = ...
) contains some
bindings, but none of those bindings are referenced by any diagram
URLs, so the code block is ignored.
Another convenient implication is that supporting code can be put in separate code blocks and even shared between diagrams. For example:
-- > makeitblue d = d # fc blue # lc blue
--
-- Here is a blue circle:
--
-- <<#diagram=blueC&width=200>>
--
-- > blueC = circle 1 # makeitblue
--
-- And here is a blue square:
--
-- <<#diagram=blueS&width=200>>
--
-- > blueS = square 1 # makeitblue
This also means that diagrams are recompiled only when necessary. For
example, if the definition of blueC
is changed, only blueC
will be
recompiled. If the definition of makeitblue
is changed, both
blueC
and blueS
will be recompiled.
Invoking diagrams-haddock
Invoking the diagrams-haddock
tool is simple: just give it a
list of targets, like so:
diagrams-haddock foo.hs baz/bar.lhs ~/src/some-cabal-directory
-
For file targets,
diagrams-haddock
simply processes the given file. -
Directory targets are assumed to contain Cabal packages, which themselves contain a library.
diagrams-haddock
then finds and processes the source files corresponding to all modules exported by the library. (Note thatdiagrams-haddock
does not currently run on unexported modules or on the source code for executables, but if you have a use case for either, just file a feature request; they shouldn’t be too hard to add.)
Also, if you simply invoke diagrams-haddock
with no targets, it will
process the Cabal package in the current directory.
diagrams-haddock
also takes a few command-line options which can be
used to customize its behavior:
-
-c
,--cachedir
: When diagrams are compiled, their source code is hashed and the output image stored in a file like068fe.......342.svg
, with the value of the hash as the name of the file. This way, if the source code for a diagram has not changed in between invocations ofdiagrams-haddock
, it does not need to be recompiled. This option lets you specify the directory where such cached SVG files should be stored; the default is.diagrams-cache
. -
-o
,--outputdir
: This is the directory into which the final output images will be produced. The default isdiagrams
. -
-d
,--distdir
: When building diagrams for a cabal package, this is the directory in whichdiagrams-haddock
should look for thesetup-config
file (i.e. the output ofcabal configure
). An explicit value for this flag takes precedence; next,diagrams-haddock
checks whether there is an active hsenv environment, and if so usesdist_<hsenv name>
; otherwise, it defaults to usingdist
. -
-i
,--includedirs
:diagrams-haddock
does its best to process files with CPP directives, even extracting information about where to find#include
s from the.cabal
file, but sometimes it might need a little help. This option lets you specify additional directories in whichdiagrams-haddock
should look when searching for#include
d files. -
--cppdefines
: likewise, this option allows you to specify additional names that should be#define
d when CPP is run. -
--dataURIs
: embed the generated SVG images directly in the source code with data URIs (the default is to generate external SVG files and link to them). See the section below for a discussion of the tradeoffs involved. -
-q
,--quiet
:diagrams-haddock
normally prints some logging information to indicate what it is doing; this option silences the output.
Workflow and Cabal setup
There are two ways one may include generated SVG images with your
documentation: as data URIs, or as external images. The two options
are discussed below, along with pros and cons of each. Note that in
either case, consumers of your library (including Hackage itself) do
not need to have diagrams-haddock
installed in order to build your
documentation.
Using data URIs
If you pass the --dataURIs
option to diagrams-haddock
, any
generated images will be embedded directly in your source file (and
hence also in the HTML ultimately produced by haddock
) as
data URIs. To use
this method,
- Include inline diagrams code and URLs in your source code.
- Run
diagrams-haddock --dataURIs
. - Commit the resulting URL changes to your source files.
The benefit of this scheme is that there are no extra files to deal
with, and no need to alter your .cabal
file in any way. The
downside is that it significantly bloats your source code, and may
make it extremely inconvenient to edit without some sort of tool
support (e.g. an editor that can “collapse” certain sections of the
source file).
Using external images
By default, diagrams-haddock
generates external SVG image files.
This makes for much less invasive changes to your source files, but
requires some work to manage the extra files. To use this method,
- Include inline diagrams code and URLs in your source code.
- Run
diagrams-haddock
. - Commit the resulting URL changes to your source files and the produced SVG files.
- Arrange to have the SVG files installed along with your package’s Haddock documentation (more on this below).
The generated SVG files need to be copied in alongside the generated Haddock documentation. There are two ways to accomplish this:
-
As of
Cabal-1.18
, the.cabal
file format has acquired anextra-doc-files
field, specifying files which should be copied in alongside generated Haddock documentation. So the preferred method is to add something likeextra-source-files: README.md, CHANGES.md, diagrams/*.svg extra-doc-files: diagrams/*.svg
to your
.cabal
file. Note that you must list the generated images in both theextra-source-files
field (so they will be included in your package tarball) and theextra-doc-files
field (so they will be copied alongside generated Haddock documentation). Hackage is now built onCabal-1.18
, so uploading a package using theextra-doc-files
field in this way works just fine. -
If you need to make your documentation buildable with a pre-
1.18
version ofcabal-install
, it is possible to take advantage ofcabal
’s system of user hooks to manually copy the images right after the Haddock documentation is generated. Add something likebuild-type: Custom extra-source-files: diagrams/*.svg
to your
.cabal
file, and then put something like the following in yourSetup.hs
:import Data.List (isSuffixOf) import Distribution.Simple import Distribution.Simple.Setup (Flag (..), HaddockFlags, haddockDistPref) import Distribution.Simple.Utils (copyFiles) import Distribution.Text (display) import Distribution.Verbosity (normal) import System.Directory (getDirectoryContents) import System.FilePath ((</>)) -- Ugly hack, logic copied from Distribution.Simple.Haddock haddockOutputDir :: Package pkg => HaddockFlags -> pkg -> FilePath haddockOutputDir flags pkg = destDir where baseDir = case haddockDistPref flags of NoFlag -> "." Flag x -> x destDir = baseDir </> "doc" </> "html" </> display (packageName pkg) diagramsDir = "diagrams" main :: IO () main = defaultMainWithHooks simpleUserHooks { postHaddock = \args flags pkg lbi -> do dias <- filter ("svg" `isSuffixOf`) `fmap` getDirectoryContents diagramsDir copyFiles normal (haddockOutputDir flags pkg) (map (\d -> ("", diagramsDir </> d)) dias) postHaddock simpleUserHooks args flags pkg lbi }
It may not be pretty, but it works!
File encodings
For now, diagrams-haddock
assumes that all .hs
and .lhs
files
are encoded using UTF-8. If you would like to use it with source
files stored using some other encoding, feel free to file a feature
request.
The diagrams-haddock library
For most use cases, simply using the diagrams-haddock
executable
should get you what you want. Note, however, that the internals are
also exposed as a library, making it possible to do all sorts of crazy
stuff you might dream up. Let us know what you do with it!
Reporting bugs
Please report any bugs, feature requests, etc., on the github issue tracker.
Changes
v0.3.0.10 (2015-12-06)
- allow
haskell-src-exts-1.17.*
v0.3.0.9 (2015-11-20)
- Allow
lucid-svg-0.6
- Fix broken v0.3.0.8
v0.3.0.8 (2015-11-15)
- Don’t use this version.
v0.3.0.7 (2015-09-22)
- Allow
lens-4.13
,linear-1.20
, andtasty-0.11
v0.3.0.6 (2015-07-19)
0.3.0.5 (10 July 2015)
- Allow `lucid-svg-0.5
v0.3.0.4 (2015-05-26)
0.3.0.3 (29 April 2015)
- Allow `diagrams-svg-1.3.1
0.3.0.2 (29 April 2015)
- allow QuickCheck-2.8 in test suite
0.3.0.1 (20 April 2015)
- ghc-7.10 compatability
0.3 (19 April 2015)
- Allow
diagrams-builder-0.7
,diagrams-lib-1.3
, anddiagrams-svg-1.3
0.2.2.14 (2 April 2015)
- allow
lens-4.9
- allow
vector-space-0.10
0.2.2.13 (13 Jan 2015)
- Allow
vector-space-0.9
- Allow
lens-4.7
- Allow
Cabal-1.22
- Allow
tasty-1.10
0.2.2.12 (20 November 2014)
- Allow
lens-4.6
- Allow
text-1.2
- Allow and require
haskell-src-exts-1.16
0.2.2.11 (22 August 2014)
- Allow lens-4.4
0.2.2.10 (5 June 2014)
- allow
diagrams-builder-0.6
0.2.2.9 (2 June 2014)
- allow
lens-4.2
in the test suite as well
0.2.2.8 (28 May 2014)
- allow
diagrams-lib-1.2
,diagrams-core-1.2
- allow
cabal-1.20
- allow
mtl-2.2
- allow
lens-4.2
0.2.2.7 (16 April 2014)
- allow
haskell-src-exts-1.15
in test suite
0.2.2.6 (15 April 2014)
- allow
haskell-src-exts-1.15
0.2.2.5 (7 April 2014)
- switch to tasty framework for tests, and allow
QuickCheck-2.7
0.2.2.4 (20 March 2014)
- allow
lens-4.1
0.2.2.3 (8 March 2014)
- allow `lens-4.0` in test suite too
0.2.2.2 (6 March 2014)
- allow diagrams-lib-1.1
0.2.2.1 (12 February 2014)
- allow lens-4.0
0.2.2 (27 January 2014)
- require diagrams-builder-0.5
0.2.1.6 (15 January 2014)
- allow text-1.1
0.2.1.5 (31 December 2013)
- allow text-1.0
- allow lens-3.10 for the test suite
0.2.1.4 (26 November 2013)
- require diagrams-builder-0.4.2, allowing the use of IO actions
producing diagrams
0.2.1.3 (24 November 2013)
- update `README`: `extra-doc-files` field in `.cabal` is now supported
by Hackage
- allow diagrams-lib-1.0 and diagrams-svg-1.0
0.2.1.2 (14 November 2013)
- allow base-4.7
- allow lens-3.10
0.2.1.1 (14 October 2013)
- bug fix: correctly handle hsenv environments with no name
0.2.1 (11 September 2013)
- prettier progress output and error logging
- allow Cabal-1.18
- require diagrams-svg >= 0.8.0.1
0.2 (2 September 2013)
- Take active hsenv into account when looking for distdir (closes #18)
- add an option to generate data URIs instead of external SVGs
- base generated diagram file names on module name + diagram name,
so diagrams with the same name in different files no longer
clobber each other
0.1.2.0 (1 September 2013)
- part before # is now optional when writing a new diagram URL
0.1.1.2 (22 August 2013)
- update for haskell-src-exts 1.14
- 'extra-html-files' is now called 'extra-doc-files'
0.1.1.1 (1 August 2013)
- allow
diagrams-lib-0.7
anddiagrams-svg-0.7
0.1.1.0 (23 June 2013)
- Add -d option for specifying dist dir
0.1.0.1 (27 March 2013)
- bump upper bounds:
- allow lens-3.9
- allow QuickCheck-2.6
0.1.0.0 (23 March 2013)
Initial release!