Proposal: Markdown, plugged in
Rad Geek
technophilia at radgeek.com
Sat May 15 17:41:01 EDT 2004
Markdown should allow plugins for link references.
See: <http://www.radgeek.com/markdown/>
Why? Because it's potentially very useful, and because it can be
implemented in Markdown without any real cost for those who don't use it.
It allows us to be lazy by writing convenient plugins that automate the
translation from human-readable references to URIs (for example, by
running over a list of commonly-used 'bookmarks', or by consulting an
InterWiki map and generating the link programmatically from the name of
the reference). It enhances something that Markdown does; and it does so
without requiring the internals of Markdown itself to be kludged. It lets
us be more lazy about irrelevant computer details, and it lets Markdown be
Markdown. And that's a good thing.
I've implemented a simple proof of concept, based on PHP Markdown 1.0b5.
I'm more comfortable with PHP than I am with Perl, so I did it in PHP; but
the implementation is very simple and should be easy to roll into
Markdown.pl (or into any other implementation of Markdown in a language
that supports callbacks).
Here's what it does: it allows anyone using Markdown to define a callback
which plugs into Markdown's link reference processing. If the callback is
defined, Markdown calls it whenever it encounters a reference-style link
whose reference is not explicitly defined within the Markdown blurb. The
callback either returns a link (in which case Markdown runs the link into
the HTML) or NULL (in which case Markdown treats it as an undefined link:
the Markdown cruft is left in-place). The plugin function can generate the
link however it pleases; Markdown doesn't need to care. (My implementation
demonstrates the use of a simple bookmark file, a crude function for
extracting the source of an article that is referenced within a post, and
the use of InterMap to generate links into Wikis.)
See <http://www.radgeek.com/markdown/> for a dingus demonstrating the
implementation. The technical details of the plugin interface are
explained in the PHP source itself, a text/plain serving of which is
linked from the Dingus.
Let me know what you think. It would be nice to see something *like* this
in future versions of Markdown--although of course the exact details of
the implementation are all up for grabs, and of course any decision is up
to those who actually do the work of maintaining those future versions.
For those who enjoy such things, I've included a much more longwinded
explanation of why I think this is a good idea, why it's a better idea
than the alternatives, and why it's natural for being incorporated into
Markdown (this is otherwise known as: a lot of talk over a very simple
thing). That follows below.
-RG
Markdown should allow plugins for link references. It should be pretty
clear why this would be useful; but it might also not be clear why it's
better than the alternatives. So let's stop for a moment and go over some
background points.
Point 1.
--------
Markdown is for "posting": it exists in order to make writing blobs of
content for the web *quick* and *natural*. It makes our lives easier
because it eliminates a lot of the repetitive work involved in
hand-writing blobs of raw (X)HTML. Computers are better than humans for
doing monotonous, repetitive work; Markdown shifts more of that work from
the human to the computer. Markdown does the grunt-work for us and lets us
keep our mind on writing. That's why Markdown is a good thing.
Point 2a.
---------
I write on a weblog; I expect that most of you do, too. A lot of my posts
link back to a source that I link to on a regular basis (other weblogs,
Salon, the New York Times, Slashdot...). In practice this means that a
*significant* percentage of the posts I write repeat at least one or more
of the following references, more or less verbatim, at the bottom of the
post:
[Alas, A Blog]: http://amptoons.poliblog.com/blog/
[Dive Into Mark]: http://www.diveintomark.org/
[New York Times]: http://www.nytimes.com/
[Salon]: http://www.salon.com/
[Slashdot]: http://www.slashdot.com/ "/.: News for nerds, stuff that
matters"
... and so on.
None of this is hard work. But it *is* work; I need to break out of what
I'm doing and either punch out a memorized URI or else spend a couple
seconds looking up the URI in a fresh tab. (If I don't break out at, say,
the end of a paragraph, I'm liable to forget to put the reference in at
the end at all.) I shouldn't have to do this. Why? Because my computer
could easily do it for me. Mapping from human-readable titles to URIs is
cognitive grunt-work that every web browser in the world does for you with
bookmarks. Markdown is good because it lets me be lazy about irrelevant
computer grunt-work. URIs are irrelevant computer grunt-work. So Markdown
should let me be lazy about URIs too.
Of course, we shouldn't expect Markdown to be all things to all people;
Markdown should be Markdown, and should do a limited number of things
well. But one of the things that Markdown does is offer links based on
human-readable references, rather than URIs; this just makes the reference
system easier to use.
Point 2b.
---------
Besides weblog posts, one of the obvious potential applications for
Markdown syntax is to drop it into a Wiki package for use as
WikiFormatting. But any WikiFormatting worth its salt needs to be able to
link to other entries in the Wiki without requiring the user to type any
URI cruft. It's pretty clear how you could map this behavior into Markdown
syntax without too much pain: that is, by treating references that aren't
explicitly defined elsewhere within the Markdown blob as intra-Wiki links
(or, if they're qualified by a namespace, as inter-Wiki links). Wiki
packages allow you to programmatically generate the URI of a given entry
within the Wiki; but Markdown has no way of knowing about that.
Point 3.
--------
Of course, the problem with (2a), (2b), and any related application is
that they're tricky to generalize. Markdown.pl (or markdown.php) are
single files that do a simple thing very well. They shouldn't have to
undergo the kludging needed to make Markdown aware of where other files
are or how to generate Wiki URIs. One thing you might be inclined to
suggest is just to write a second filter to run right after Markdown: if a
link has an undefined reference, Markdown just leaves it in the Markdown
format, just as it was. It wouldn't be hard to write a second text filter
to scrape the Markdown output and do whatever should be done to the links
that remain.
But I don't think that's a good solution, for a couple of reasons. One of
the reasons is purely ideological, and the other is purely practical, but
they do have a certain conceptual connexion between them. The ideological
reason for concern is this: the "references" on links are conceptual
elements *of Markdown*; `[this][]` and `[that][this]` are only links to
the resource referenced as "this" from within Markdown's syntax and
semantics. So if a text filter is processing the references on Markdown
links, it should be (in some sense) from *within* Markdown, not as a
filter run over Markdown's output (which is in (X)HTML, not in Markdown).
The practical reason is this: Markdown's syntax might *change*. In
particular, the link syntax might change. (We have, for example, discussed
the merits of `[[this]]` or `[this]` as a synonym for `[this][]`.) If
Markdown's link syntax changes then the post-processing filter would
*also* have to change to keep consistent with Markdown. That's because the
post-processing solution doesn't operate from *within* Markdown. If it
operated from within Markdown, then *Markdown* could tell it what marks up
a reference, rather than making the author keep up with those details at
each new release.
Of course, swapping out one regex for another in your post-processor is
*not* hard work at all. But it *is* work; it's monotonous and repetitive
work that Markdown could do for you. Indeed, it's work that Markdown
*should* do for you. The question is how you do that without kludging
Markdown to include a bunch of extra stuff that doesn't generalize well
from one setting to the other.
A Solution.
-----------
A solution to the difficulty may be blindingly obvious. The software that
should know how to generate links into a Wiki is the Wiki software; the
software that should know what links you commonly use on your weblog is
your weblog software. So why not create an interface that lets Markdown
identify the references, and then passes them on to the software that it's
dropped into for figuring out what to do with them?
That means a plug-in for the plug-in. In practice, all we have to do is
define a callback function that is set before we call the Markdown()
filter.
Of course, Markdown includes a syntax for *explicit* references. We
shouldn't interfere with Markdown syntax; we should be able to extend
Markdown references but not to break them. (In any case, if a user
*explicitly* defines the URI for a reference within the Markdown blob, who
is Markdown, or the weblog/Wiki/etc. software, to say otherwise?)
Soexplicit references should take precedence; so what we'll do is change
the anchor-parsing subroutines within Markdown to *fall back* to the
plugged-in function if, and only if, Markdown can't find the reference on
its own. The plugged-in function returns a link, in which case Markdown
runs the link into the HTML output; or else it returns failure, in which
case Markdown falls back to its own default: it leaves the Markdown cruft
in place, without any modification.
If no plug-in function is defined, Markdown just falls straight into its
own defaults, and goes on its merry way.
If we do it this way, Markdown can easily be dropped in to many more web
writing environments than it can now. We can do less work in dealing with
irrelevant computer stuff; we can concentrate more work on writing. With a
defined interface, people can easily swap popular and/or useful modules
for extending Markdown's references, and new versions of Markdown won't
break older modules being used with them, even if the syntax changes
substantially, as long as the internal interface stays the same. Markdown
doesn't have to be kludged to deal with non-generalizable stuff; we don't
need to generalize, because plug-in functions specify what needs to be
specified for a given environment. Any hacking that needs to be done is
limited to simple plugin functions, and hacking simple plugin functions is
better than hacking Markdown itself.
The reference system is extended to do an even better job at what,
conceptually, it's supposed to do. Markdown stays Markdown; we all get to
be lazier. And that's a good thing.
At least, so it seems to me.
Comments?
--
Charles Johnson <technophilia at radgeek.com>
AIM: AiPuch
WWW: http://www.radgeek.com/
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
More information about the Markdown-discuss
mailing list