hakyll-diagrams 0.1.0.0 → 0.1.0.1
raw patch · 2 files changed
+2/−346 lines, 2 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- README.md +0/−343
- hakyll-diagrams.cabal +2/−3
− README.md
@@ -1,343 +0,0 @@-# hakyll-diagrams--**Contents**-* [Overview](#overview)-* [Usage](#usage)- * [Input format](#input-format)- * [Code](#code)- * [Options](#options)- * [Metadata options](#metadata-options)- * [Haskell API](#haskell-api)- * [Package databases](#package-databases)-* [Similar projects](#similar-projects)---## Overview--Compiles any [diagrams](https://diagrams.github.io/) code found within markdown source files-and inserts the resulting figures into the generated HTML output. The figures can be embedded-as inline SVG code or referenced via external image files using `<img>` tags.--For example, when a block like this is found in a markdown file:--```` Haskell-``` diagram { svg:width=300 }-let- target = mconcat- [ circle 1 # lw 0 # fc red- , circle 2 # lw 0 # fc white- , circle 3 # lw 0 # fc red- ]-- background = roundedRect 8 8 0.1- # lw 0- # fc (sRGB24read "#808080")- # opacity 0.15--in target <> background-```-````--That code will be compiled, and replaced by the rendered SVG figure:----If we add a few attributes to the rendered SVG figure:--```` Haskell-``` diagram {- figcaption="An interactive figure. It reacts to mouse hover and each part is a link."- svg:width=400-}-let- hydrogen =- mconcat- [ proton- , electron # moveTo p0- , orbit- ]- where- orbit =- circle 2- # svgAttr "pointer-events" "stroke"- # href "https://en.wikipedia.org/wiki/Atomic_orbital"- # svgClass "svg_orbit"- electron =- circle 0.1- # fc blue- # lw 0- # href "https://en.wikipedia.org/wiki/Electron"- # svgClass "svg_electron"- proton =- circle 0.3- # fc red- # lw 0- # href "https://en.wikipedia.org/wiki/Proton"- # svgClass "svg_proton"- p0 = fromJust $ maxTraceP origin (angleV $ 3/8 @@ turn) orbit-- background =- roundedRect 5 5 0.1- # lw 0- # fc (sRGB24read "#808080")- # opacity 0.15--in hydrogen <> background-```-````--We will generate this figure:----And with the help of some additional CSS or JavaScript code, we can make it an interactive-figure. That will not be possible to be shown here, because GitHub has restrictions on-adding inline SVG and JavaScript code to the Markdown files, however that same figure with-interactive features is available-[here](http://renatogarcia.blog.br/posts/hakyll-diagram-example.html).--## Usage--### Input format--In a source file, any Haskell code within a *code block* having `diagram` as one of its-classes will be rendered to a diagram figure. In a markdown file, it means any code block-like this:--````{.markdown}-``` diagram {- <options>- }-<code>-```-````--Where `<options>` is a list of library and HTML tag attributes, fully described in the-[Options](#options) section, and `<code>` must consist of a single Haskell expression-whose resulting value has type [`Diagram SVG`](https://hackage.haskell.org/package/diagrams-core-1.5.1.1/docs/Diagrams-Core.html#t:Diagram).--#### Code--The code block must contain a single Haskell expression of type-[`Diagram SVG`](https://hackage.haskell.org/package/diagrams-core/docs/Diagrams-Core.html#t:Diagram).--The interpreter environment is configurable via the [`Options`] record, which serves as an-argument to the [`drawDiagramsWith`] function. All exports from modules listed in-[`globalModules`] and [`localModules`] will be available in the context.--#### Options--The options configure what the diagram rendering will produce as results, and specify any-additional attributes for the resulting HTML and SVG elements.--A valid options list must be in the format:--```-options := {option}-option := id | class | figcaption | attribute-id := "#" name-class := "." name-figcaption := "figcaption=" value-attritube := tag ":" name "=" value-tag := "figure" | "img" | "svg"-name := <any valid HTML attribute name>-value := <any valid HTML attribute value>-```--An input like this:--```` Text-``` diagram { img:src="external_figure.svg" figcaption="foo"- .my_class_a .my_class_b #my_id- img:alt="a circle" figure:myattr=foo img:width=10- svg:class="my_svg_class" svg:width=50- }-circle 10-```-````--Will generate an external SVG file named *external_figure.svg*, written under the Hakyll's-configured-[`destinationDirectory`](https://hackage.haskell.org/package/hakyll/docs/Hakyll-Core-Configuration.html#v:destinationDirectory).-The `<svg>` tag will have the following attributes:--``` HTML-<svg width="50.0000" class="my_svg_class" ... >-```--Besides generating an external file, that input will be replaced in the resulting HTML-file by a code like:--``` HTML-<figure id="my_id" class="my_class_a my_class_b" data-myattr="foo">- <img src="external_figure.svg" alt="a circle" width="10" />- <figcaption>foo</figcaption>-</figure>-```--Regardless of any options, a `<svg>` element will always be generated. If we have set an-`img:src="path"` attribute, the rendered SVG will be written to an external file at-*path*, and an `<img>` element will link to it. If we don't have an `img:src="path"`-attribute, the rendered SVG will be inlined in the HTML code.--If we have set a `figcaption="caption"` attribute, the `<svg>` or `<img>` element will be-nested in a `<figure>` element. Otherwise they will be inserted without a parent.--The attributes must be in the format: `tag:name=value`, and *tag* must be one of:-`figure`, `img`, and `svg`. This means that the pair `name=value` will be assigned to the-*tag* element. If that element would not be generated, such as when we don't have an-`<img>` tag because of an inlined SVG, or if the tag has any other value than those valid-three, it will be ignored without an error.--The `#id` and `.class` values will be assigned to the outermost element, whether it is-`<figure>`, `<img>`, or `<svg>`.--### Metadata options--We can use the Hakyll's [metadata-block](https://jaspervdj.be/hakyll/tutorials/02-basics.html#pages-and-metadata) to create-an [`Options`] record to be used as argument to the [`drawDiagramsWith`] functions that-will render that page diagrams.--This works starting from a base [`Options`] record, whose fields will be modified by the-values at the metadata block. Each one of the record fields can be assigned a value-through a metadata key named the same as that field prefixed with `dg.`.--- Each field must be formatted as a list where each element is separated by a comma `,`.-- Any occurrence of an ellipsis `...` will be replaced by the current value of that field- as in the base [`Options`].-- When setting either [`globalModules`] or [`localModules`], a value like `Utils` will- result in an unqualified import of *Utils* module. A value like `Commons as Cm` will- result in a qualified import of *Commons* module under *Cm* name.-- Any field not present will retain the same value as in the base [`Options`]. An empty- string `""` will set the field to an empty list.--When starting with base:--```Haskell-Options- { globalModules =- [ ("Prelude", Nothing)- , ("Diagrams.Prelude", Nothing)- , ("Diagrams.Backend.SVG", Nothing)- ]- , localModules = []- , searchPaths = ["app", "posts"]- , languageExtensions = ["NoMonomorphismRestriction"]- }-```--the metadata block:--```yaml-----dg.localModules: Utils, Commons as Cm-dg.searchPaths: lib, ..., foo-dg.languageExtensions: ""-----```--will result in:--```Haskell-Options- { globalModules =- [ ("Prelude", Nothing)- , ("Diagrams.Prelude", Nothing)- , ("Diagrams.Backend.SVG", Nothing)- ]- , localModules = [("Utils", Nothing), ("Commons", Just "Cm")]- , searchPaths = ["lib", "app", "posts", "foo"]- , languageExtensions = []- }-```--### Haskell API--All the API documentation is available in the Haddock generated [project-page](http://renatogarcia.blog.br/hakyll-diagrams).--The main functions are [`drawDiagrams`] and [`drawDiagramsWith`]. Both functions accept a-[Pandoc](https://hackage.haskell.org/package/pandoc-types/docs/Text-Pandoc-Definition.html#t:Pandoc)-data structure and transform it by replacing-[CodeBlock's](https://hackage.haskell.org/package/pandoc-types/docs/Text-Pandoc-Definition.html#v:CodeBlock)-having a `diagram` class with their rendered diagram figures, as explained in the [Input-format](#input-format) section.--The simplest way to integrate these functions into a [Hakyll's-rule](https://jaspervdj.be/hakyll/tutorials/03-rules-routes-compilers.html#basic-rules) is-with code like this:--``` Haskell-match "posts/*.md" $ do- route $ setExtension "html"- compile $- pandocCompilerWithTransformM- defaultHakyllReaderOptions- defaultHakyllWriterOptions- drawDiagrams-```--We can use either [`readOptionsFromMetadata`] or [`readOptionsFromMetadataWith`] function-to control at the input source level what [`Options`] will be used to configure the-interpreter environment when rendering the diagrams on that page. The [Metadata-options](#metadata-options) section explains the metadata block syntax.--One simple way to add this metadata reading functionality to the example code above is to-replace the `drawDiagrams` function by a `drawDiagrams'` defined as:--``` Haskell-drawDiagrams' :: Pandoc -> Compiler Pandoc-drawDiagrams' pandoc = readOptionsFromMetadataWith opts >>= flip drawDiagramsWith pandoc- where- opts = defaultOptions { searchPaths = ["app", "posts"] }-```--### Package databases--The [hint library](https://github.com/haskell-hint/hint?tab=readme-ov-file) is used to-interpret the Haskell code, and therefore all of its-[limitations](https://github.com/haskell-hint/hint?tab=readme-ov-file#limitations) will-apply here as well. In particular, if there isn't a `.ghc.environment.\<something>`-[package environment-file](https://ghc.gitlab.haskell.org/ghc/doc/users_guide/packages.html#package-environments)-(as generated by cabal-[`--write-ghc-environment-files=always`](https://cabal.readthedocs.io/en/3.4/cabal-project.html#cfg-field-write-ghc-environment-files)-option), setting either `HAKYLL_DIAGRAMS_PACKAGE_ENV` (a single path) or-`HAKYLL_DIAGRAMS_PACKAGE_DB` (N comma-separated paths) environment variables may be-required. If these environment variables are defined, their values will be used to set the-GHC-[`-package-env`](https://ghc.gitlab.haskell.org/ghc/doc/users_guide/packages.html#ghc-flag-package-env-file-name)-and-[`-package-db`](https://ghc.gitlab.haskell.org/ghc/doc/users_guide/packages.html#ghc-flag-package-db-file)-options respectively.--## Similar projects--There are two *diagrams* projects,-[diagrams-pandoc](https://github.com/diagrams/diagrams-pandoc) and-[diagrams-builder](https://github.com/diagrams/diagrams-builder), that implement-a portion of the functionality of this *hakyll-diagrams* library. They are not used-as dependencies because they would not allow some useful features. For example, with-*diagrams-builder* it is not possible to import a local module qualified, and it has-some [potential issues](https://hackage.haskell.org/package/diagrams-builder/docs/Diagrams-Builder-Modules.html#v:combineModules)-when combining them. With *diagrams-pandoc* we cannot add arbitrary attributes to a-specific HTML element, or generate an inlined SVG instead of an externally linked file.--There is also a homonymous [hakyll-diagrams](https://github.com/cdupont/hakyll-diagrams)-library that integrates the two diagrams libraries with hakyll, running them inside-the-[`Compiler`](https://hackage.haskell.org/package/hakyll/docs/Hakyll-Core-Compiler.html#t:Compiler)-monad. Since it uses those two diagrams libraries, it has the same limitations-discussed above. Because of this, I have decided to create a new hakyll-diagrams library-with all the desired features.----[`Options`]: http://renatogarcia.blog.br/hakyll-diagrams/Hakyll-Web-Pandoc-Diagrams.html#t:Options-[`drawDiagrams`]: http://renatogarcia.blog.br/hakyll-diagrams/Hakyll-Web-Pandoc-Diagrams.html#v:drawDiagrams-[`drawDiagramsWith`]: http://renatogarcia.blog.br/hakyll-diagrams/Hakyll-Web-Pandoc-Diagrams.html#v:drawDiagramsWith-[`globalModules`]: http://renatogarcia.blog.br/hakyll-diagrams/Hakyll-Web-Pandoc-Diagrams.html#v:globalModules-[`localModules`]: http://renatogarcia.blog.br/hakyll-diagrams/Hakyll-Web-Pandoc-Diagrams.html#v:localModules-[`readOptionsFromMetadata`]: http://renatogarcia.blog.br/hakyll-diagrams/Hakyll-Web-Pandoc-Diagrams.html#v:readOptionsFromMetadata-[`readOptionsFromMetadataWith`]: http://renatogarcia.blog.br/hakyll-diagrams/Hakyll-Web-Pandoc-Diagrams.html#v:readOptionsFromMetadataWith
hakyll-diagrams.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.0 name: hakyll-diagrams-version: 0.1.0.0+version: 0.1.0.1 synopsis: A Hakyll plugin for rendering diagrams figures from embedded Haskell code. @@ -31,7 +31,7 @@ will be replaced in the resulting HTML page by this figure: - <<docs-data/target.svg>>+ <<docs/docs-data/target.svg>> A thoughtful documentation with usage examples and results can be found at the [project repository](https://github.com/renatoGarcia/hakyll-diagrams).@@ -48,7 +48,6 @@ build-type: Simple extra-doc-files: docs-data/target.svg-extra-source-files: README.md tested-with: GHC == { 9.4.8, 9.12.2 }