*Note: If you are viewing this Readme on GitHub, its Blogdown-specific features will not render correctly. The Blogdown-formatted output is in `test/goldens/Readme.html`.* # [Blogdown](https://blogdown.io) Blogdown is a markup language based on Markdown, designed for writing blog posts. Blogdown's goals are: * Clean syntax for common blog post features absent from Markdown. * Ability to handle untrusted input. * Simple syntax, with no surprises. * Debuggability. * Near compatibility with common Markdown implementations. Because there is no Markdown standard and existing Markdown implementations [disagree wildly even on simple cases](http://johnmacfarlane.net/babelmark2/?text=Hello+world%0A*+this+is+a+list%0A%3E+this+is+a+quote), Blogdown cannot be 100% compatible with even a majority of Markdown implementations. While there have been attemps to create a common Markdown standard--most notably [CommonMark](http://commonmark.org/)--they are necessarily quite complex. The primary cause of this complexity is that Markdown insists on rendering *something* for every input, no matter how malformed. Blogdown is considerably simpler, and hopefully easier for authors to debug, because it fails on malformed inputs. With full compatibility out of the window, I have chosen to make some other small improvements on Markdown syntax. ## Installation ### With Cabal or Stack The recommended way to install any Haskell project is using [Cabal](https://www.haskell.org/cabal/) or [Stack](https://docs.haskellstack.org/en/stable/README/). With these tools, you can simply run `cabal install` or `stack build` respectively. ### Without Haskell Tooling Because configuring Cabal and Stack can be tricky for Haskell beginners, Blogdown supports installation without any Haskell tooling. First, install [GHC](https://www.haskell.org/ghc/), [Parsec](https://hackage.haskell.org/package/parsec) and [MissingH](https://hackage.haskell.org/package/MissingH), all of which are available through common Linux package managers. To compile static assets into Haskell files, run `ghci Setup.hs` and manually invoke `compileStaticFiles`. Then run `ghc -isrc -iassets -o Blogdown src/Blogdown.hs` in the repository's base directory. ## Usage The `Blogdown` binary reads from `stdin` and writes to `stdout`. Typical usage looks like: cat blogpost.md | ./Blogdown > blogpost.html If using `Blogdown` to process untrusted input for display in a web page, you **must** use the `--allowed-tags` and `--allowed-attributes` flags. ### Optional Styling and Scripts It is recommended to include `footnotes.css` and `footnotes.js` on any pages which make use of Blogdown-generated footnotes, which improve the appearance of footnotes and allow them to be shown inline. These can be inlined using the `--inline-css` and `--inline-js` flags respectively^[inline]. ### Optional Flags `Blogdown` accepts the following long-style flags: * `--allowed-tags`: Specifies a comma-separated list of HTML tags which should be rendered faithfully. All other tags are escaped, e.g. `` becomes `<a>`. If no list is supplied, all tags are escaped. * `--allowed-attributes`: Specifies a comma-separated list of HTML attributes which should be rendered faithfully. Any other attributes will be stripped from tags when they are rendered. If no list is supplied, all attributes are stripped. * `--allow-unsafe-tags`: By default, Blogdown will fail when it encounters a `"evil()"`. However, these are unlikely on non-malicious input, so this flag can be passed to attempt parsing these tags. * `--em-dashes`: If this flag is passed, `--` will be replaced with "—" in text. * `--footnote-backlinks`: If this flag is passed, footnotes will be preceded by a caret linking back to the point where the footnote is referenced. * `--footnote-index-from`: The index from which footnotes are numbered. Defaults to 0. * `--footnote-prefix`: Defines a prefix for the `id`s of footnotes. Recommended if multiple output files are included in a single HTML page, to avoid `id` collisions. * `--inline-css`: If this flag is passed, the recommended CSS will be inlined at the end of the output document. * `--inline-js`: If this flag is passed, the recommended JS will be inlined at the end of the output document. ## Syntax ### Differences from Markdown Most of the syntax of Blogdown should be familiar to Markdown users, but some new syntax has been added, and some existing syntax has changed. #### New Features Blogdown adds footnote support to Markdown. Footnotes can be referenced inline with \^\[*footnote-name*\], which will render as a superscript link to a *footnote-definition* at the end of the document, which is defined by \~\[*footnote-name*\] followed by the footnote contents. #### Markdown Incompatibilities Blogdown does not support the Markdown syntax of underlining text with `=` or `-` characters to define a header, as this comes at a large cost in the parser implementation^[underline-parser-complexity]. The `#` syntax for headers is supported instead. It also does not support using multiple trailing spaces to force a breakpoint at the end of a line. The `
` tag is supported instead. While tables are not a feature of base Markdown, some common Markdown implementations such as [Github Flavored Markdown](https://guides.github.com/features/mastering-markdown/#GitHub-flavored-markdown) support them. Blogdown also supports tables, but its implementation is slightly different from Github's, requiring `|` characters at the start and end of a row and using `+` instead of `|` in the separator between the (optional) table header and table body. Since Blogdown introduces new syntax, some valid Markdown will require escaping to render as expected in Blogdown. Additionally, while most Markdown implementations do not require escaping many special characters when their special meaning would not be valid, Blogdown always requires they be escaped. ### HTML Embedding Like most Markdown implementations, Blogdown documents can have HTML embedded inside them. However, Blogdown allows only a limited subset of HTML, specifically [XHTML](https://www.w3.org/TR/xhtml1), with the exceptions that unknown tags are permitted, and that any tag is allowed to be self-closing^[arbitrary-tags]. By default Blogdown will not allow `