Skip to content
This repository


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP


Correct a nasty bug with SETEXT header detection when fenced code is …


2.1.5 adds
* MKD_NOSTYLE -- treat `<style>` blocks as regular html.
* some github flavored markdown support; gfm_...() input
  methods that put hardbreaks (== two spaces) at the end
  of every input line
* a whole bunch of tweaks to work around
  the tiny detail that clang is even more anal-compulsive
  than gcc is.
* support for github flavored markdown backtick-delimited
  code blocks (in addition to tilde-delimited codeblocks)
* in the `markdown` program, add
    1. -S flag (tell markdown to spit out style sections)
    2. -n flag (tell markdown not to output generated text)


Fixes for
1. tables with leading |s
2. \<br> being erroneously treated as a block-level html element

Tweaks for mingw, cygwin, and clang brokeness

Changes contributed by Stefano D'Angelo to clean up the toc html


Tweak table processing to not freak out when a table is framed
with leading and/or trailing |'s


Correct a long-standing bug in endash/emdash smartypants conversions.


Correct paragraph blocking to closer match the reference
(text blocks absorb adjacent code lines) and update the
test case error reporter to show the failed input and
the differences between the actual and expected output.


Found a bug in 2.1.1 when writing a weblog post about it!


Support PHP markdown extra-style fenced code blocks (delimited with
lines of three or more tildes.)   This involved some optimization of
the blockification code in markdown.c -- I now cache line type in the
line and have a cache filling function (`checkline()`) that will compute
the line type _once_ and then all the lookup functions can use this cache.
It's not significantly faster than the old code (1/100th of a cpu second
faster processing 10 450k documents) but it's also doing the line check for
fenced code blocks.


Version 2.1.0;
* modifications to `` so that it generates all
  the test scripts in the build directory
* more MacOS support in ``; check to see if `.dSYM`
  folders are created when a test script is compiled, and, if so,
  don't forget to delete them when they're cleaned up.
* `makepage` now accepts markdown option flags a'la the `markdown`
  program  (via `-Fxxxx`, `-fname`, or in the `MARKDOWN_FLAGS`
  environment variable.)
* strip bitfields out of `opts[]` -- I can't initialize a bitfield
  on plan9 cc.
* add a `-E` flag to `theme` to disable context-sensitive `<?theme xxx?>`


Tweak `` to write executables that it wants to execute
into `$__cwd`; some modern Linuces ship with `/tmp` marked `noexec`
and my chances of getting them to change that are about as good as
my chances of making the gcc cabal change gcc to be a C compiler


* Modify table handling to make it hew closer to the markdown extra i…

* Put an optimization in to make table detection faster
* Documentation patches from David Banks
* argument prototype tweaks for Solaris, from Allen Otis
* `--with-github-tags` configuration option to to include `-` and `_` in
  the acceptable characters for `maybe_tag_or_link()` (code from Ryan Tomayko's
  discount SCCS on github.)
* in the `markdown` program, `-f?` gives a list of the known flags.
* `--with-id-anchor`` configuration options to have the table of contents code
  emit `id=` instead of the dummy `<a name=` anchor I replaced it with (`name=`
  is depreciated in xhtml, and may vanish.


Further work on markdown extra-style footnotes;
- documentation
- add `mkd_ref_prefix()` function to change the footnote ids from `fn`...
  to a user-defined one
- clean up one bug where I didn't initialize the markdown extra footnote flags

Plus a small patch to correct minor documentation typos


Support php markdown extra-style footnotes (with flag MKD_EXTRA_FOOTN…


* Rework the TOC code so that it uses an `a name=` anchor
  instead of `hx id=` (because the id= may pick up css unexpectedly.)
* in `linkyformat()`, don't pass in `&imaget` for image formats; pass
  in null instead and add a paranoia check to default to &imaget if
  the passed-in footnote is null.
* tweak the librarian generator so it doesn't require ln -s for static libs
* Repair a defect in the way >%class%es are handled;
  css class names are `{-_.A-Za-z}{-_.A-Za-z0-9}*` (plus some unicode characters
  which I don't support yet.)


Version 2.0.4, which contains the following changes:
 1. add shared library support
 2. correct some typos
 3. Add manpages for the example programs makepage(1) and mkd2html(1)
 4. Initialize the random number generator and tag list separately,
    just in case someone really wants to do multiple initialize/deallocate
 5. Add a library destructor function (mkd_shlib_destructor) to
    discard the kw array before unloading a shared library.
 6. Put in a bunch of useless code to make gcc STFU.
 7. Be more picky about what comes before a ^ if we're superscripting
 8. Unclosed html/style blocks revert to being regular old markup.
    True, the markup will contain the opening tag (and most of the
    other html from that block) but it will be regular old markup
    with additional garbage added in.
 9. Null-terminate the strings generated by mkd_line(), mkd_css() and mkd_toc().
10. Flip the order of arguments to mkd_generatecss(); should be 1,size, not size,1
12. It turns out that non-toplevel paragraphs consume adjacent code blocks :-(
13. Rework (again) indentation inside list items.
    Indent should never be > 4 for enumerated lists; this means that I have to
    test and cut back large indents and change my test cases to account for
    leading whitespace on deeply (2 spaces + enumerated marker + 1 space) indented
14. Add a raft of testcases to cover the new features + bugfixes.
15. Add markdown extra style definition list support
     *  Add a configuration flag (--with-dl={discount|extra|both} to
	select which way to  do  definition lists.    Put a DL= into
	version.c so the user can see how this (compile time because
	it's a beta) is configured.
     *  If dl is turned off at compile time, mark it off in version.c


More tweaks to shared library support; new manpages; typo correction.


Fixes to css.c and toc.c to keep them from corrupting
their environments as part of null-terminating their


Several bug fixes, some chrome, and a new feature
First, the bugfixes:

 1. In `mkd_css()`, don't check that `*res` is non-null.
 2. if definition lists are turned off, note that in version.c
 3. unclosed html & style blocks now revert to being plain old
    markdown instead of being accepted as unclosed blocks of
    html or style.
 4. Add a `mkd_shlib_destructor` function so people who use it
    as a run-time load(and unload)able shared library can clean
    up the dynamically allocated html tag list before unloading
    the library.
 5. repair markdown extra-style dl handling so that skipped blank
    lines are garbage collected.
 6. Flip the order of arguments to `fwrite()` inside `mkd_generatecss()`;
    it was `size, 1` (write 1 element size bytes long; fwrite will
    return 1 or 0) and it should be `1, size` so I can get back the
    number of bytes actually written.

Then the chrome:

 1. Add prototypes for `mkd_initialize()`, `mkd_shlib_destructor()`,
    and `mkd_deallocate_tags()` to make gcc stfu.
 2. null terminate the buffers generated by `mkd_css()`, `mkd_toc()`,
    and `mkd_line()` (in the same fashion as elsewhere; the null
    termination is allocated, but the returned size doesn't count
    it.  This way a `fwrite()` writes out the proper number of
    characters, but a naive `fputs()` won't charge off into terra
 3. Be more picky about what comes before a superscript "`^`";
    alphanumerics plus ")" are good, other nonspace characters
    are not.

And finally the feature:

 *  Shared libraries are now supported through the `--shared` flag
    to ``.   MacOS, FreeBSD, and Linux only, though.


1. Tweak indentation inside list items (ensure that indents are never…
… > 4)

2. It turns out that non-toplevel paragraphs consume adjacent code blocks :-(


Put in markdown extra-style definition list support.
It's only a little bit more hideous than the discount definition
support, and it's more "standard" (if I include discount, there
are three markdown implementations that support it?) than my design.


Update the documentation for the new flock of MKD_ flags


1. In `theme`, add the pseudo-tag `<?theme config?>`, which writes a
   listing of all of the runtime settings to the output file.
2. Add a couple of functions that write the current runtime configuration
   (either a flags value (`mkd_flags_are`) or of an MMIOT (`mkd_mmiot_flags`))
   to a FILE.    `markdown -VV` prints out the flags for now, and the
   functions are there for other people to use as they desire.
3. Change the autolink prefix to closer fit to the reference dingus;
   if a `<url>` has a known protocol prefix, it does not need a
   leading `//` after the prefix.
4. Add test cases for <> links (regular and markdown 1 compat), split
   the superscript tests out from smarty.t
5. Modify superscript grabbing so that it grabs parenthetical
   and alphanumeric blocks
6. Rework (again!) the guts of `linkylinky` to support markdown
   1.0.2b8-style `<`..`>` links: these are like the original
   format I implemented before I rolled them out while chasing
   compatability in that a url starting with '<' contains _all
   characters_ until an unescaped '>' is encountered.
7. Version 2.0.2; fix a glitch in new-style `[]` processing that
   would collapse two sequential new-style `[link]`s into one
   no matter how much space was between them.  The reference dingus
   only coalesces adjacent new-style `[link]`s together if they
   are physically adjacent or have one space between them.


Fix a bug in embedded _'s with strict|norelax; add a couple more test…
… cases

for table of contents support


Version 2.0 (codename "never trust a .0 release") moves all of the
previous compilation options over to runtime options, breaks the
user interface, and fixes a bug or two in the table-of-contents


Version 1.6.8 -- ~~strikethrough~~ and cleanup of `code`


Correct a small defect with mismatched backticks


Two bugfixes; fix a coredump in theme, fix misparsing of escaped []'s
1) In theme, when figuring where to put the `.html` for an output file,
   take into account the teeny detail that the source filename might
   not have an extension to strip off.
2) Escape both the `in` and `out` characters in the `parenthetical()` function.
3) testcases for #2


Version 1.6.5

Fix bugs:

  1. properly handle html comments w/o spaces
  2. fix nested list handling with unindented
     list items.
  3. Add config.h to the dependency lists for
     cols & echo, so those functions will properly
     rebuild after a reconfig.
  4. More plan9 fixes from Josh Wood; this one
     adds the flag `_C99_SNPRINTF_EXTENSION` to tell
     the APE cc that, yes, I do really want to be
     using snprintf() and I know that C99 has it
     return the size it wants to populate.
  5. don't describe `<style>` blocks as `mystery node` during `markdown -d`

New features:

  1. add a VALID_DOCUMENT magic flag to the MMIOT
     structure, so that if someone attempts to double-free
     it, the second attempt will just not work instead of
     causing a core dump.
  2. restructure the blocktag[] array into a STRING(), so
     users can add additional block tags as they desire.
  3. in relation to this, add the library function `mkd_add_html5_tags()`,
     which adds (globally, and non-removably) a handful of
     new tags for html5 support.


1.6.4: 1 bugfix, 2 creeping features, and some new testcases
The bugfix is that I now split content that comes on a line after
the closing tag in a html block, so a line line
    <p>blah blah blah</p>foo foo foo
becomes two lines
    <p>blah blah blah</p>
    foo foo foo

(the older version would pass the trailing junk through without
markup, and occasionally get confused about following content.)

The creeping features are
 1. Ryan Tomayko modified rdiscount to do smartypants with
    `'re`, `'ll`, `'ve', '`m', and `'d` so I sucked those
    changes into the baseline code.
 2. `earthboundkid`@github suggested the new pseudo-protocol
    `lang:<whatever>` which would expand into
    `<span lang=<whatever>`...`</span>`

The additional testcases are to catch mishandled backslashes
in code sections (most recently documented at
<>.)   This defect was
corrected in version 1.6.3, and I testcased it then, but
more tests are always good.


Rework the backtick & code block handlers to
  a. remove some truely ancient cruft, and
  b. clean up the backtick quoting to make
     it more dingus-compliant.


Version 1.6.2:
  * another pass at the emmatcher to make certain that
    pathological indentation won't produce bad xhtml
  * fix a bug in autolink that made a hanging prefix
    generate a bogus `<a` tag.
  * restrict the depth of a ETX header to `<h6>`
  * write a manual page for callback functions.
  * don't emphasise `_` or `*` when they're in the
    middle of whitespace.
  * unescape trailing '  's when they're in the middle
    of a code section or `[]()` link.
  * tighten the parser for footnote links so that a
    construct like `[]-<]:` won't erroneously become
    a footnote.


1.6.1 patches two scripting security holes (discovered at Reddit)
and tweaks three edge cases to make them behave more like the
reference implementation.


1.6.0 adds one
new feature that's large enough to require a version bump;
I've now added callback routines so that a program that uses
discount can

1. modify the urls found in `[]()` and `<link>` constructs,
as well as
2. supply extra arguments to the tags generated by `[]()`
and `<link>` constructs.

Not fully documented yet, because I'm still working on


Two bug fixes:
  - lines with |'s in them are treated as tables
  - tables without data don't display (should display
    the header block)

One feature:
  - allow sizes like =xW or =Hx to scale images.


Fix a bug in html blocks which would cause discount to dump core if
the end block tag was not closed.


Version 1.5.6:
1. feature fix to make malformed tags behave
   more like the way the reference implementation
2. Add a test for bzero() or memset()
3. and remove a place where I used bzero()
4. Documentation changes contributed by Josh Wood


Fix a defect where I expanded the align() [tables] array instead
of shrinking it.


1.5.4: correct the table of contents code


1.5.3: []() tags are only valid if there's no whitespace
       between the ] and the following (


1.5.2: two bug fixes
  1. Allow consecutive >%div% blocks
  2. [footnote]: links can appear anywhere and
     are ignored for formatting.


1. Correct the transposed generation of `</table>` and `</tbody>`
2. Document tables.
3. Add `<iframe>` to the list of block html entities.


1.5: Markdown Extra-style table support


 1. Add More Plan9 + documentation patches from Josh Wood
   2. Tweak the paragraph wrapping in `generate()` so that all
      paragraphs in a multiple-paragraph item/blockquote will
      be properly wrapped with `<p>`...`</p>` (or whatever is
   3. Attempt to follow indentation better inside lists, so
      a list item with multiple paragraphs is parsed correctly
      when the second (& up) paragraphs are indented the same
      as the first paragraph.


* * * * * * * * *
 1. Add `<map>` to the html blocks we know about.
 2. Redo most of the test cases so they won't
    use `grep` except in exceptional cases.
 3. To prettify the test case output, modify
    `cols.c` so that it more-properly handles
    utf-8 characters.
 4. Make autolink hew closer to the reference (reddit)
 5. Fix a bug in generate.c where `MKD_NO_EXT` was not being handled.
 6. Add -fext to the options for the markdown program
 7. [Plan9] documentation corrections from [Josh Wood]
 8. Find and fix a bug where a url with an embedded double quote
    is printed out with that doublequote in plaintext.
 9. Some more code primping to make [anal-compulsive pseudo-C
    compilers](abbr:gcc) stfu.
10. Redo `puturl()` and the url grabbers to do debackslashification
    in `puturl()`


Version 1.4.3 adds one new feature (Plan9 support, contributed by Josh
Wood) and goes back into the horrible snakepit that is
compatable behavior with edge cases.


All the 1.4.1pre0 features, plus a rewritten version of `linkylinky()`


Some fairly large changes & bugfixes:
1. Three bugs reported by Mike Schiraldi:
    * If -fautolink is turned on, a naked @ becomes a mailto:
       link.  Fixed by only triggering `maybe_tag_or_link()` on
       alphabetic characters.
    * If -fnohtml is set, forced linebreaks become &lt;br/>.
       Fixed by filtering out nonprinting nonwhitespace characters
       on the input and using ^C as the <br/> generator character
       instead of converting the forced linebreak directly to <br/>.
    * inline links (via []()) don't allow spaces or escaped ) characters.
       Fixed by rewriting `linkyurl()` so it builds a new `Cstring` for (which needs to be deleted after use, so I added a new
       `deallocate` field to the bookmark record for `linkylinky` to use,)
       changing the link gobbler to absorb input until a terminator instead
       of until whitespace or a terminator) and allowing \ to escape ), =,
       or ".
2. Change the `Qchar()` function so that it take an integer argument instead
   of a char.  (reported by Josh Wood from the plan9 port.)
3. Some bugs I discovered
    *  Flag the raw: pseudo-protocol so that it will be disabled when
       DENY_HTML is set.
    *  Rework `maybe_tag_or_link()` so it better rejects random stuff
       that begins with a `<`.
4.  Add the new `abbr:` pseudo-protocol (the html `<abbr>` tag)


Add two features suggested by Mike Schiraldi (;
   1. "autolinks" -- expand unbracketed urls into links
      (flag MKD_AUTOLINK, -fautolink in the markdown program)
   2. "safe links" -- don't linkify footnotes where the link protocol
      isn't a well-known protocol (currently http: https:,ftp:,news:)
      (flag MKD_SAFELINK, -fsafelink in the markdown program)

Also do a couple of performance and sanity tweaks:
   1. Reorder the logic of maybe_tag_or_link() to process mailto: before
      other link types, and explicitly if() ... else the control flow
   2. make the protocols[] array into an name/size structure, so I don't
      have to spend time doing strlen() when running isautoprotocol().


Found some bugs in the previous tag


Version 1.3.6 -- change the way html blocks are parsed so that
funnily ordered blocks are more likely to be properly detected.
Something went wrong with that request. Please try again.