Discount is free software released under the terms of a BSD-style license.
If you find it useful, please consider making a contribution to help support onward development.
Discount 2.2.7d, released 22-Aug-2023
This is my implementation of John Gruber’s Markdown text to html language. There’s not much here that differentiates it from any of the existing Markdown implementations except that it’s written in C instead of one of the vast flock of scripting languages that are fighting it out for the Perl crown.
Markdown provides a library that gives you formatting functions suitable for marking down entire documents or lines of text, a command-line program that you can use to mark down documents interactively or from a script, and a tiny (3 programs so far) suite of example programs that show how to fully utilize the markdown library.
My markdown also does, by default, various smartypants-style substitutions.
The markdown
program is a trivial compiler that reads in a markdown
file and writes out a html document or – if you use the -d
flag –
an outline showing the parse tree. It does have a few options;
-d
-F <flags>
-F 0x4
tells markdown
to not do the smartypants translations on the output.
(there are cases – like running the test suite – where
this is a useful feature.)-f <flags>
-F
, these are the names of the flags (you can get
a list of the supported flags with the -f?
option; supported
flags + synonyms with -Vf?
) optionally
prefixed with no
or -
to turn them off.
To reuse the example to disable smartypants, you’d do -f nopants
(“pants” is a synonym for “smarty” == smartypants.)-o file
file
-V
tells you a markdown version number and how the package was configured. For example
$ markdown -V
markdown: discount 2.2.2 TAB=8 DEBUG
tells you that this is markdown 2.2.2, and that the package was configured with support for sensible tabs & debugging malloc.
-VV
-V
, except it also returns the current values of many
of the flags that can be set with -f
or -F
.There are 17 public functions in the markdown library, broken into three categories:
MMIOT *mkd_in(FILE *f, int flags)
reads a markdown input file
and returns a MMIOT containing the preprocessed document.
(which is then fed to markdown()
for final formatting.)
MMIOT *mkd_string(char *bfr, int size, int flags)
reads the
markdown input file that’s been written into bfr
and
returns a preprocessed blob suitable for feeding to markdown()
.
This function exists because annotations uses mmap()
to
access message files instead of traditional file i/o. (If
you’re going to port Markdown to an AS/400, this function is
the droid you’ve been looking for.)
int markdown(MMIOT *doc, FILE *out, int flags)
formats a document
(created with mkd_in()
or mkd_string()
) and writes the
resulting HTML document to out
.
int mkd_line(char *bfr, int size, char **out, int flags)
allocates a
buffer, then formats the text string into that buffer.
text string, allocates a buffer,
The differences from markdown()
are it doesn’t support quoting,
footnotes (“reference links”,) multiple paragraphs, lists, code
sections, or pure html sections.
int mkd_generateline(char*bfr, int size, FILE *out, int flags)
formats the text string and writes the resulting HTML fragment to out
.
It is exactly like mkd_line()
except that it writes the output to
a FILE*
.
int mkd_compile(MMIOT *doc, int flags)
takes a document created by
mkd_in()
or mkd_string()
and compiles it into a tree of block
elements.
int mkd_generatehtml(MMIOT *doc, FILE *out)
generates html from
a compiled document.
int mkd_document(MMIOT *doc, char **text)
returns (in text
) a
pointer to the compiled html document, and (in the return code)
the size of that document.
int mkd_css(MMIOT *doc, char **out)
allocates a buffer and populates
it with any style blocks found in the document.
int mkd_generatecss(MMIOT *doc, FILE *out)
prints any style blocks in
the document.
int mkd_toc(MMIOT *doc, char **out)
allocates a buffer, populates it
with a table of contents, assigns it to out, and returns the length of
the buffer.
To get a table of contents, you must compile()
the document
with the MKD_TOC
flag (described below)
int mkd_generatetoc(MMIOT *doc, FILE *out)
writes a table of contents
to out; other than writing to a FILE*
, it operates exactly like
mkd_toc()
int mkd_dump(MMIOT *doc, FILE *f, int flags, char *title)
prints
a block structure diagram of a compiled document.
void mkd_cleanup(MMIOT *doc)
releases the MMIOT allocated for the
document.
char *mkd_doc_title(MMIOT *doc)
returns the % title
line.char *mkd_doc_author(MMIOT *doc)
returns the % author(s)
line.char *mkd_doc_date(MMIOT *doc)
returns the % date
line.void mkd_e_url(MMIOT*, char* (callback)(char*,int,void*))
sets up a callback function that is called whenever discount
processes a []()
or <link>
construct. The callback function
is passed a pointer to the url, the size of the url, and a data
pointer (null or supplied by mkd_e_data()
)void mkd_e_flags(MMIOT*, char *(callback)(char*,int,void*))
sets up a callback to provide additional arguments to the tags
generated by []()
and <link>
constructs. If, for instance,
you wanted to add target="_blank"
to every generated url, you
could just make a callback function that returned that string.void mkd_e_free(char *, void*)
is called to free any allocated
memory returned by the url or flags callbacks.void mkd_e_data(MMIOT*, void*)
assigns a
callback data area to the url & flags callbacks.The flags argument in
markdown()
, mkd_text()
, mkd_in()
,
mkd_string()
, mkd_compile()
, and
mkd_generatehtml()
is a mask of the following flag bits:
Flag | Action |
---|---|
MKD_NOLINKS | Don’t do link processing, block <a> tags |
MKD_NOIMAGE | Don’t do image processing, block <img> |
MKD_NOPANTS | Don’t run smartypants() |
MKD_NOHTML | Don’t allow raw html through AT ALL |
MKD_STRICT | Disable SUPERSCRIPT , RELAXED_EMPHASIS |
MKD_TAGTEXT | Process text to go inside an html tag; no emphasis or html expansion & embedded html will be stripped out. |
MKD_NO_EXT | Don’t allow pseudo-protocols |
MKD_CDATA | Generate code for xml ![CDATA[...]] |
MKD_NOSUPERSCRIPT | No A^B |
MKD_NORELAXED | Emphasis happens everywhere |
MKD_NOTABLES | Don’t process PHP Markdown Extra tables. |
MKD_NOSTRIKETHROUGH | Forbid ~~strikethrough~~ |
MKD_TOC | Do table-of-contents processing |
MKD_1_COMPAT | Compatability with MarkdownTest_1.0 |
MKD_AUTOLINK | Make http://foo.com a link even without <> s |
MKD_SAFELINK | Paranoid check for link protocol |
MKD_NOHEADER | Don’t process document headers |
MKD_TABSTOP | Expand tabs to 4 spaces |
MKD_NODIVQUOTE | Forbid >%class% blocks |
MKD_NOALPHALIST | Forbid alphabetic lists |
MKD_NODLIST | Forbid definition lists |
MKD_EXTRA_FOOTNOTE | Enable PHP Markdown Extra-style footnotes (warning: not the later version of multiple-paragraph ones.) |
MKD_NOSTYLE | Don’t extract <style> blocks |
MKD_NODLDISCOUNT | Disable discount-style definition lists |
MKD_DLEXTRA | Enable PHP Markdown Extra definition lists |
MKD_FENCEDCODE | Enable Github-style fenced code blocks. |
MKD_GITHUBTAGS | Allow dashes & underscores in element names |
MKD_HTML5ANCHOR | Use the html5 namespace for anchor names |
MKD_LATEX | Enable embedded LaTeX (mathjax-style) |
MKD_EXPLICITLIST | Don’t merge adjacent numbered/bulleted lists |
I have an experimental C++ binding that
lives on Github in
mkdio.h++. It implements a couple of RAII objects;
MKIOT
– can’t call the class MMIOT
because it clashes with the C
MMIOT
it wraps – for standard markdown (plus my extensions,
of course) and GFIOT
for github-flavo(u)red markdown. Alas, it
is undocumented, but the mkdio.h++
header file is pretty simple and
a trivial program that uses it is included in the mkdio.h++
sccs tree.
text
‘’ is translated to “text”."double-quoted text"
becomes “double-quoted text”'single-quoted text'
becomes ‘single-quoted text’don't
is “don’t.” as well as anything-else’t.
(But foo'tbar
is just foo'tbar.)it's
is “it’s,” as well as anything-else’s
(except not foo'sbar and the like.)(tm)
becomes ™(r)
becomes ®(c)
becomes ©1/4th
? ¼th. Ditto for 1/4
(¼), 1/2
(½),
3/4ths
(¾ths), and 3/4
(¾)....
becomes …. . .
also becomes …---
becomes —--
becomes –A^B
becomes AB. Complex superscripts can
be enclosed in ()
s, so A^(B+2)
becomes AB+2.My markdown was written so I could replace the fairly gross homemade
text to html prettifier that I wrote for annotations, so I’ve extended
it in a few ways; I’ve put support for paragraph centering in
so that I don’t have to hand enter the <center>
and </center>
tags
(nowadays I generate a css-styled <p>
block, because that’s xhtml
compatible instead of the now-depreciated <center>
block element.)
I’ve added support for specifying image sizes, and I’ve written a
not-earthshatteringly-horrible markup extension for definition lists.
->
and <-
.
->this is a test<-
produces
this is a test
=
widthx
height field to the image tag:
![dust mite](http://dust.mite =150x150)
produces
=
characters, then put the body of the list
item on the next line, indented 4 spaces.
=hey!= This is a definition list
produces
<dt>hey!</dt> <dd>This is a definition list</dd>
A definition list label is just a regular line of markdown code, so you can put links and images into it.
In discount 1.2.3, the definition list syntax has been
extended so that you can define sequential <dt>
blocks by doing
=tag1=
=tag2=
data.
which generates
<dt>tag1</dt>
<dt>tag2</dt>
<dd>data.</dd>
(If you want a definition list with a trailing empty tag, give it a body that’s just a html comment, like:
=placeholder!= <!-- this space intentionally left blank -->
produces
<dt>placeholder!</dt> <dd><!-- this space intentionally left blank --></dd>
In discount 2.0.4 I extended the definition list syntax to allow php markdown extra definition lists which means that source like
tag1
: data
now generates
<dt>tag1</dt>
<dd>data</dd>
Ordered lists with alphabetic labels (enabled by --enable-alpha-list
during configuration) are supported in the same way that numeric ordered
lists are:
a. first item
b. second item
generates
I wanted to be able to apply styles inline without having
to manually enter the <span class="
xxx">
…</span>
html. So I redid the [][]
code to support some new
“protocols” within my markdown:
abbr:
description<abbr title="
description">
…</abbr>
class:
name<span class="
name">
…</span>
id:
name<a id="
name">
…</a>
raw:
textText will be written verbatim to the output. The protocol
was inspired by a short thread on the markdown mailing list
about someone wanting to embed LaTeX inside <!-- -->
and
finding, to their distress, that markdown mangled it.
Passing text through in comments seems to be a path to unreadable madness, so I didn’t want to do that. This is, to my mind, a better solution.
<style>
…</style>
blocks and set them aside for printing
via mkd_style()
.> %class%
will become
<div class="
class">
instead of a <blockquote>
.PHP Markdown Extra-style tables are supported;
aaa | bbbb
-----|------
hello|sailor
becomes the following table:
aaa | bbbb |
---|---|
hello | sailor |
And much of the rest of the current table syntax (alignment, handling of orphan columns) follows the PHP Markdown Extra spec.
Pandoc-style document headers are supported; if the first three
lines in the document begin with a %
character, they are taken
to be a document header in the form of
% Document title
% Document author
% Document date
and can be retrieved by the library functions
mkd_doc_title()
, mkd_doc_author()
, and mkd_doc_date()
.
Note that I implement Pandoc document headers as they were documented in 2008; any Pandoc changes since then will not be reflected in my implementation.
If called with the MKD_FENCEDCODE
option, Pandoc-style
fenced code blocks are supported; blocks of code wrapped in ~~~
lines are treated as code just as if it was indented the traditional
4 spaces. Github-flavored-markdown fenced code blocks (blocks wrapped
in backtick lines) are also supported.
Both of these formats support the github-flavored-markdown class extension where you can put a word at the end of the opening backtick line and have the block given that class.
If called with the MKD_LATEX
option, text wrapped in $$
…$$
,
\[
…\]
, and \(
…\)
is passed unchanged (except for encoding <
,
>
, and &
) to the output for processing by a LaTeX renderer.
This collides with how Markdown escapes ‘[’, ‘]’, ‘(’, and ‘)’ – if discount is called with MKD_LATEX
, \(
and \[
will only map to (
and [
if corresponding \)
or \]
s are not found in the same paragraph.
--github-checkbox
flag, discount will understand
github-style checkboxes
and generate checkboxes using either html entities (--github-checkbox
w/o an argument) or <input>
elements (--github-checkbox=input
)When I run the standard test suite (version 1.0.3) from
daringfireball, MarkdownTest.pl
reports:
$ MARKDOWN_FLAGS=0x20004 ./MarkdownTest.pl --tidy --script=/usr/local/bin/markdown Amps and angle encoding ... OK Auto links ... OK Backslash escapes ... OK Blockquotes with code blocks ... OK Code Blocks ... OK Code Spans ... OK Hard-wrapped paragraphs with list-like lines ... OK Horizontal rules ... OK Inline HTML (Advanced) ... OK Inline HTML (Simple) ... OK Inline HTML comments ... OK Links, inline style ... OK Links, reference style ... OK Links, shortcut references ... OK Literal quotes in titles ... OK Markdown Documentation - Basics ... OK Markdown Documentation - Syntax ... OK Nested blockquotes ... OK Ordered and unordered lists ... OK Strong and em together ... OK Tabs ... OK Tidyness ... OK 22 passed; 0 failed.
When I run the old standard test suite from daringfireball,
MarkdownTest.pl
reports:
$ MARKDOWN_FLAGS=0x22004 ./MarkdownTest.pl --tidy --script=/usr/local/bin/markdown Amps and angle encoding ... OK Auto links ... OK Backslash escapes ... OK Blockquotes with code blocks ... OK Hard-wrapped paragraphs with list-like lines ... OK Horizontal rules ... OK Inline HTML (Advanced) ... OK Inline HTML (Simple) ... OK Inline HTML comments ... OK Links, inline style ... OK Links, reference style ... OK Literal quotes in titles ... OK Markdown Documentation - Basics ... OK Markdown Documentation - Syntax ... OK Nested blockquotes ... OK Ordered and unordered lists ... OK Strong and em together ... OK Tabs ... OK Tidyness ... OK 19 passed; 0 failed.
Most of the “how to get standards compliant” changes that went in were cleaning up corner cases and blatant misreading of the spec, but there were two places where I had to do a horrible hack to get compliant:
mkd_compile()
so that it would have top-level
paragraphs absorb adjacent list items, but I had to retain the
old (and, IMO, correct) behavior of a new list forcing a block
break within indented (quoted, inside lists) blocks..MKD_1_COMPAT
(0x2000) turns it on again for testing purposes.By default, yes, it does. The habit of compensating for broken editors that give no way to indent except for tabbing by setting tabstops to 4 is so intertwined with this language that treating tabs properly would be the moral equivalent of dropping nuclear devices into the testsuite.
But if you use a proper tabstop (8 characters), you can configure
markdown with --with-tabstop
and it will expand tabs to 8
spaces. If you’ve configured your markdown like this (markdown -V
will report TAB=
8) and you need to mark up text from other
sources, you can set the input flag MKD_TABSTOP
to revert those
documents back to the icky standard 4-space tab.
To build discount, untar your selected tarball, cd into the directory it creates, then do
configure.sh
to generate your Makefiles. After doing this, amake
should give you a functional stack of programs and libraries.Discount builds, for me, on MacOS 10.12, FreeBSD 4.8, NetBSD 8, Minix 3, and Debian Linux (dunno which version, but it’s a
systemd
joint that’s running a 3.10 kernel.) It may build on SLS Linux and Windows with mingw, but I’m not sure about that.
Version 2.2.7d One more maintenance release to fix a few more bugs:
[^1][^2]
) were being treated as a regular old
hyperlink because the code I put in originally was a huge old
monster bodge.<tags>
if ()
it
pukes up an error about a syntax error in a macro; pull
those tests out and conditionally #define a macro insteadversion 2.2.7b Another maintenance release to fix a bug in the Makefile; I didn’t have the proper dependencies for the pandoc_headers tool, so if a parallel make was tried it would fall over complaining about missing objects when it tried to link everything together.
version 2.2.7 A maintenance release to clean up a buffer overflow when generating label names (backported from the new v3 under [slow] development)
version 2.2.6 should have been released last fall, but I was too busy working on breaking the published interface so I could expand the flag structure to permit more than 32 feature flags. *sigh*
It’s not a huge release; it fixes a few bugs, tweaks a few things, and adds a couple of features:
version 2.2.4 fixes a couple of small buglets, adds a couple of new features, and tweaks the html5 support module to chase the html5 standard:
--github-checkbox
does the checkbox with html check entities--github-checkbox=input
does them with html <input>
elements
(set to disabled so that people can’t check and uncheck willy-nilly)mkd_shlib_destructor()
so it will run automatically
when the library unloads.--cxx-binding
option to configure.sh
to
generate a mkdio.h
that’s got an extern "C"
wrapper around it.HGROUP
from the list of html5 elements,
because the w3c working group decided to
punt itThe bugfix for not null-terminating a split line was reported by
Github user fCorleone, who was running
a input mangler program (afl) to stress
discount by feeding random garbage to it. It saw that the splitline()
function (used when breaking out embedded chunks of html) was not
null-terminating the split line chunks, and was throwing errors on that.
(this is something that clang
on modern macos catches if you use the
-fsanitize=address
option.)
I never actually use footnotes, so I’d been running for about a decade assuming that footnotes were one or maybe two lines, but github user somasis pointed out that this was wrong wrong wrong! Ooops; at least it was fixable w/o much pain and suffering.
HGROUP
was caught by (no longer registered) github user
Crypto-Anarchist in their own branch of discount, so I cherry-picked
that changeset and pulled it back into the mainline discount.
version 2.2.3a
2.2.3 has a configuration glitch (not properly testing for the
existance of S_ISSOCK, et seq) which 2.2.3a corrects. I also pulled
the plug on the single use of alloca()
in theme.c
(Windows MinGW
doesn’t support it properly(?) and in this one case I’m better off
just malloc()
ing the offending thing and letting it be garbage
collected when the program finishes.)
version 2.2.3 I turn around and blink, and suddenly 13 months have gone by while I slowly tested various beta versions of 2.2.3, and now it’s 2018 and a small collection of cosmetic, portability, and build tweaks, plus some and actually bad bugs have been cleaned up:
Have tools/branch
be a no-op if there’s no git
that I can use to check for my SCCS status.
Add user-contributed cmake support
check for non-null T(link) in the safelink function; rename paranoia.t to safelink.t, add a couple more tests for safelinks
tweak the safelink detection code to allow more types of url fragments
when finding the installer, check that -s works (doesn’t work on Minix 3?)
Correct makepage & theme to use the new set_flag() return scheme (0==success, !0==pointer to bogus flag)
if an unknown flag was in the middle of a comma-delimited flag string (like -flatex,bogus,footnote), the markdown program would incorrectly report the first flag as unknown (because set_flag returned 0 on error, 1 on success and the strtok() of the flag string had already replaced the commas up to that point with nulls.)
Change it so that set_flag returns null on successful processing and a pointer to the offending flag on an unknown one.
Tweak the install rule to install a GNU-style .pc file iff @MK_PKGCONFIG@ is not defined as #
Hand-resolve a conflict in the msvc Makefile
Add in paranoid list splitting [EXPLICITLIST] (the default behavior many many versions ago before I realized it wasn’t the standard) (and take the last of the 32-bit flag mask for it) between adjacent ordered and unordered lists.
Create a utility function [notspecial()
] for theme & mkd2html
– check a filename to see if it’s a special file that doesn’t
need to be deleted or to have a .html suffix added to it. It
only works on machines that have a stat() system call + the S_ISFIFO,
S_ISCHR, and S_ISSOCK macros, otherwise it thinks that nothing is special.
Add a README for the utilities in the tools subdirectory
Add the git branch name into the version string if we’re not on the master branch.
Add support for NMAKE and Visual C++ toolset. (courtesy of Martin Hofmann (tin-pot) fork of Discount).
Add a ‘dirty’ flag to the Document structure & set it whenever a callback changes (github issue #136) so that the next mkd_compile will regenerate the document.
Tweak superscript handling to be able to superscript something wrapped in html
Tweak the show_flags()
function so that if it’s called verbosely
it will show synonyms for named flags. (Calling it verbosely is
done by the V
option, which is overloaded for verbosity when listing
flags.)
Process html blocks in compile (as well as in compile_document();
compile_document()
needs to handle <style>
blocks and compile()
needs to
handle html blocks that are nested inside blockquotes, tables, lists, &tc.
Add –h1-title as an option to configure.sh; this enables code that uses the first h1 in a document as the document title (in mkd2html & theme)
add gethopt()
– a q&d getopt clone that
accepts both full-word & single character options – instead of doing
kludgy bespoke argument parsing in mkd2html & theme.
version 2.2.2 A few months worth of bugfixes, mainly for annoying bugs but one for a serious one:
In mkd_line()
I was doing a sneaky hack to take the rendered text
out of the MMIOT it was in which was fine if I was building discount
w/o --with-amalloc
, but horribly wrong --with-amalloc
; the return
from mkd_line()
is a freeable string, so my sneak (I was pulling
the contents of the rendered string out, then zeroing the pointers
in the MMIOT; if amalloc was active, the rendered string was in the
middle of a allocated block which could not be freed (and would cause
core dumps on some systems. Kludges always come back to bite you
in the ass)) was terribly terribly wrong.
Redo toc anchor generation to reduce namespace collisions (by encoding out of namespace characters to -XX- hex sequences (except space, which encodes to just -) in html4, %XX in html5 (formerly urlencodedanchor)).
Add html5anchor as a synonym for urlencodedanchor (urlencoded is depreciated, but will stick around like an unwelcome guest until the next major release) now that I’m doing html5 encoding there.
When generating a TOC, don’t anchor-encode the human-readable contents of the links .
“quote” “everything” “when” “I” “generate” “librarian.sh”
Horrifying kludge to deal with destination directories with spaces in them;
instead of using the shell to check for sed substitute markers (if I
do echo "$*" | sed -e 's/;/\\;/'
it collapses a layer
of backslashes needlessly. It’s awful enough to do
echo $* | sed -e 's/ /\\\\ /'
(so sed won’t eat the backslashes) but to do
sed -e 's/ /\\\\\\\\ /'
to keep sed + the shell from eating the backslashes is just
appalling) I generate the little C program config.sed
, which
generates the sed pattern, escaping the ;
and NOT collapsing
backslashes.
Ugh. It’s all pretty gross, but it looks like it works? At least for discount.
Always have mkd_xmlpage()
generate a title element, even if it’s empty
Add <form>
… </form>
to the set of known block tags
Use \r
instead of ^C
for the internal hard end of line marker
(which means if I don’t unescape it when rendering it won’t leave
^C
poop in the output.)
Bring the installation instructions a little closer to up to date.
When there’s either pkg-config
on the system or if the configure
option --pkg-config
is used, generate a pkgconfig .pc
file.
version 2.2.1 A few months of small bugfixes, a few tweaks, and some more conversion of static flags to runtime ones.
peek()
and poke()
to not sign extend on machines with
signed chars, so a 0xff character will not sign extend and
become an EOF. This breaks a test in muñoz.t (which
tripped the 0xff becomes EOF bug) so that
test needed to be rewritten.configure.sh
not do the WinDef.h
short circuit"config.h"
to pick up the definition of DWORD/WORD/BYTE
(windows support) & add a new label field for better TOC
label generationconfig.sub
with {scalar_type}->{scalar_type} on
windows machines.mkd_xmlpage()
so that it only uses the published interface.flag_t
structure
– or 64-bit int, which isn’t portable to old Unices – here we
come!) to make LaTeX support a runtime flag.argc > 0
& argv[0]
(after
shifting argc/argv by optind) but was checking argc > 1
&
argv[1]
, which was something less than useful.--enable-all-features
from configure.sh
(obsolete now after the mass conversion of features from
compile-time to run-time.)config.h
to the includes for amalloc (for the if #define
to make clang stfu)version 2.2.0 Many MANY tweaks over the last year, including…
MKD_LATEX
in 2.2.1) ($$..$$
, \(..\)
, and \[..\]
,
not $..$
))amalloc()
paranoia malloc library even more paranoid by
putting markers at the start and the end of each allocated block.configure.inc
<p></>*
was splitting into 2 lines when it should have
generated <p><p></>*</p>
)mkd_compile()
is called multiple times, actually recompile the
document if the flags change.configure.inc
to quote __cwd
& __d
so that a $__cwd
with
spaces in the path won’t make configure.sh
(or make install
) pukefwrite()
error check in mkd_generatehtml()
,mkd_xhtmlpage()
,mkd_xxx()
output functions (inspired by a patch written by
Koen Punt)mkd_document()
don’t pad the generated html with a 0 unless it’s
actually generated.configure.sh
message for the --with-
(foo) variables to
reflect what it’s actually doing with them.--with-
(foo), so pass those
settings into theme in a #defineconfigure.sh
just state that an option is not supported instead
of dying.version 2.1.8a When I put in the patch to …
I messed up the format string and made the mangled email address into a fixed bogus string. Sigh. Fixed (thanks to a patch from Alessandro Ghedini), updated (and I really have to expand the runtime configuration flags array to be long enough to fit 64 settings, but that’s a fix for a different day) and released.
version 2.1.8 After a year or so of letting the code sit and slowly accumulate fixes, a new version which fixes a wad of bugs and adds a few new features. Some of this code is front other people, and those changes will be marked with their names:
-
, which means send output to
stdout instead of to a file.SAMPLE_PFX=discount- make install.samples
to install the
sample programs with a package-specific prefix.CFLAGS=-m32 ./configure.sh
by using CFLAGS
for all build invokations of CC.
(Nathan Phillip Brink binki@gentoo.org)version 2.1.6 does nothing except for some bugfixes (and ignores some particularly scary ones that I /must/ fix soon) and adds two small features.
The bugfixes are:
\<[nonwhite]
sequences. Sigh.Markdown does not escape...
commit to
simply push out the backslash and back up to the start of
the <[nonwhite]
sequence, so -fnohtml will continue to work.<br/>
(via two spaces) as whitespace.The features are that I now use styles for table cell alignment instead
of align=
, and that I’m using the 3-clause BSD license for this
release (because there is one widely used closed-source license
that claims that you can’t dynamically link with code that uses
the 4-clause license. Fine. I’ll 3-clause this release to make
the stupid GPL happy.)
version 2.1.5a does even more cleanup to deal with clang, plus adds a few small features:
<style>
blocks as regular html.markdown
program, add
version 2.1.3 cleans up a couple of bugs that have been here for a while, plus tweaks the build process a bit for better compilation with the LLVM C compiler, mingw, and cygwin.
The bugfixes are
Stop tripping over tables with leading |
s; the first
implementation of tables treated leading |
s as the end
of an empty table cell. 2.1.3 corrects this to properly
be merely decoration.
As a side-effect, you now need to have all the rows of the
table either with a leading |
or not; you cannot mix and
match them, sorry.
For some mysterious reason I was treating the <br>
tag as
a block-level html tag, so my html blockifier would split paragraphs
with explicit <br>
s in them.
The table of contents code was apparently generating bad html (something I never noticed, because I never use that feature, alas!) but Stefano D'Angelo contributed a patch to clean up the generated html to make it correct.
version 2.1.2
tweaks table handling so that tables with leading |
’s
won’t end up generating empty false <td></td>
s, and that
tables with trailing |
’s won’t end up getting those pipes
included in the output.
version 2.1.1.3
corrects a defect in smartypants processing that has been
there since the beginning of time; I’d managed to misread
the reference smartypants documentation
and thought that 1 dash made an –
and 2 dashes
made an —
(it’s actually 2 and 3 dashes respectively.)
John Foerch read the documentation recently, noticed it was
wrong, and sent me a note pointing it out. Whoops! But it’s
fixed now (as is the this page, which is, regrettably, the only
documentation about smartypants.)
version 2.1.1.2 corrects one small defect in block handling, plus changes the format of the output for failed tests in the test suite.
The defect in block handling is that the reference implementation has text block absorbing adjacent code, so
~~~ text text text code ~~~
will generate
~~~
text text text code
~~~instead of a paragraph of text(s) followed by code
.
The change in failed test output makes it output first the source code of the failed test, and then the differences between the expected output and the generated output.
version 2.1.1.1
implements PHP markdown extra-style fenced code sections,
where your chunks of code are surrounded by ~~~
lines
instead of being indented 4 spaces.
Fenced code sections are a configuration option, not a
runtime option, and are enabled by using the configure.sh
flag --with-fenced-code
(FENCED-CODE in the version
string).
There are a few optimizations inside markdown.c
to support
fenced code detection without slowing the parser down, but
those optimizations don’t cause any of my test cases to fail.
Version 2.1.1 is still a fairly experimental release despite
this, so take some care with it.
version 2.1.0
cleans up a small collection of warts and build bugs,
plus adds some fairly small enhancements to the theme
and makepage
programs:
configure.sh
so that it generates all
its test scripts in the build directory.configure.sh
; 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.)opts[]
– I can’t initialize a bitfield
on plan9 cc.-E
flag to theme
to ignore context-sensitivity on
<?theme xxx?>
substitutions.older versions of the code are still available.