Oddmuse is the wiki engine running all the wikis at emacswiki.org – including EmacsWiki itself. My main interests are:

See OddmuseRoadmap for my thoughts about the design of Oddmuse.

2018-09-18 Thoughts on using Perl 6

So, I’ve used Perl 6 for a few days. I’m trying to write a wiki, because that’s what I like to do, and that also what I use every day. I’ve been maintaining and running Oddmuse since 2003. I know what I want. I’ve been down every dead end, I sometimes feel. Now I want to learn the language using a real project and that’s what it is.

The current state, from a programming perspective:

  • It uses Cro as the web framework, meaning it can run stand-alone, without Apache or nginx. It’s no longer a CGI script. I expect that most people will still use a regular web server as the front end for all their applications because of caching, logging, encryption, access control and all that.
  • It uses Markdown to generate the HTML. I’ve started using Markdown more and more. I no longer recommend Wiki Creole.
  • It uses Mustache templates to generate the layout and everything around the actual wiki page “content.” No more printing as we go in order to appear faster.
  • The storage backend is a class that delegates everything to the actual storage class. Right now I’ve only implemented file-based storage, but if I keep all access going through this storage class then that will make replacing it with git or a SQLite a breeze.
  • For the moment, configuration happens via environment variables: which storage backend to use, which data directory to use if you use files as your backend, what links to show at the top, it’s all environment variables.
  • This means that translating the interface means setting a bunch of environment variables and editing the templates.
  • There are tests!

The software, from a user perspective:

  • View pages written in Markdown and rendered as HTML.
  • Edit pages as Markdown.
  • Fields available: text, summary, author, and a checkbox for minor changes
  • List recent changes.
  • A rudimentary filter for recent is available as a proof of concept: it allows you to specify how many items to see.
  • IP addresses are transformed into four octets and shown as little flag icons if no author was provided. This makes it likely that you can detect who edited a bunch of pages without revealing their IP number of host name.

Missing features:

  • file locking when writing files
  • show old page revisions
  • diff with old page revisions
  • merge in case of conflicts
  • expiration of old page revisions
  • admin passwords
  • banning regular expressions
  • locking the site
  • locking pages
  • rolling back changes
  • RSS feed
  • tags
  • search

Missing big ideas:

  • a plugin system
  • markup rules which users can add, ideally by merging grammars (this enables us to have rules that protect text from further processing, such as code blocks; this requires the notion of rule precedence)
  • a backend implementation using SQLite

More to come! I’m running out of time and I have to go. Here’s an idea: draft pages. They are like real pages but they don’t show up in search or feeds. Hah!

Anyway, I was talking to @tyil and thought that I should write this stuff down. Not sure who the intended audience is for these things. I feel like I’m too confused right now to understand where the problem is to be found, how can I create an issue, and where, and with what suggestion? Perhaps my future self is the audience for this blog post. One day I’ll wonder how newbies get into Perl 6 and what their issues are and I’ll be able to come back to this blog post and see myself struggling.

So, for a start, these are the things that immediately jumped out at me:

  • missing integration of Perl 6 docs into the man system
  • missing a good Cro manual for offline use (I brought the laptop along on a trip)
  • missing good search for when I know what I want but don’t know the signal, twiggils and operators

I bought Perl 6 Deep Dive by Andrew Shitov and I’m surprised at how quickly I’m running out of information in the book. It was a good read to get started and to motivate myself. Good enough to actually pull me into starting this project. That’s cool. But the next point is the sort of documentation I’ve had trouble finding.

For example:

I’m trying to have a class called Storage which delegates all the important method calls to another class which I want to load at run time. In this case, it’s going to be Storage::File. How to do it? I searched for “delegation” and the like and ended up on documents that were deprecated. I figured it would have to involve require somewhere, and then something like that “synopsis” or whatever it was. I don’t really care about the “synopsis” and “exegesis” and all the other funny ways the language was developed now that I’m actually trying to get stuff done. I’m a different kind of user, I know – but this is the kind of user that we will have to pull in. In the end I asked on the #perl6 channel on IRC and found something that works:

class Storage {
    my $class = %*ENV<storage> || 'Storage::File';
    require ::($class);
    has $!delegate handles <get-page put-page get-template put-change get-changes> = ::($class).new;

This illustrates two points: I might have found out about “handles” but I didn’t find it in the book. The index doesn’t mention “delegation”. Apparently this is called a “trait”. The index doesn’t mention “traits”. But even knowing all these keywords, I can’t find out about these things by starting with p6doc objects.

And that brings me to another topic: p6doc.

  • I didn’t realize that was a separate thing that I would have to install.
  • When you run p6doc --help, it tells you stuff about p6doc build and p6doc list. When you do that, you see a lot of topics. When you then try p6doc slurp or p6doc "sub slurp" you’ll get a No such type error. How does it work? What do I need to do?
  • When I run p6doc Str because I want to learn about join I find information about the vector flag. Searching for concat also doesn’t help. It must be some operator? Try p6doc operators, search for join, and then it dawns on me that it works on lists. Python: echo 'print(",".join(["1", "2"]))' | python3. Perl: perl6 -e 'say [1, 2].join(",")'. Oh well.

And then there are all those little things that bite.

  • ternary operator is x ?? y !! z instead of x ? y : z
  • regular expressions are very different now
  • map requires a comma after the block
  • here docs are different

And many other things besides. As I’m too new to the language I don’t understand why things have to be “same same but different”. I hope there’s is a grandiose pay-off, I guess?

Here’s an example of how access to the hash elements no longer uses braces but angled brackets, the regular expression is different, the braces aren’t used when creating the hash, and map takes a comma after the block:

    my $menu = %*ENV<menu> || "Home, Changes";
    my @pages = $menu.split(/ ',' \s* /);
    my %params =
	id => $id,
	pages => [ map { id => $_ }, @pages ];

The Pod is also subtly different and the documentation confused me a bit. There are many options. What the suggested way of doing it? Is this good? Should I be using #| instead?

    =head3 put-page
    =begin pod
    Pages are saved in the C<page> subdirectory with the <md> extension.
    =end pod

    method put-page (Page $page!) is export {
	my $dir = %*ENV<dir> || '.';
	my $path = "$dir/page/$($page.name).md";
	spurt $path, $page.text, :enc('UTF-8');

Anyway, that’s the kind of stuff I’m thinking about when I write Perl 6 code.

Oh, and recently my application has this super aggravating tendency: Often, when making changes (and this only started showing up recently!), I get an error.

♻ Restarting edit (edit)
⚠ edit ===SORRY!===
⚠ edit This type (NQPMu) does not support associative operations

The strange thing is that no matter what change I make, that fixes it. So now I have a second shell open where I just do the following:

echo >> lib/Storage/File.pm6

And then it works!

♻ Restarting edit (edit)
📓 edit Listening at http://localhost:20000

Apparently, all I have to do is trigger a recompilation.

When I’m testing, same thing.

dir=. storage=Storage::File prove6 -l -v t/edit.t

This causes an error:

This type (NQPMu) does not support associative operations
t/edit.t .. Dubious, test returned 1
No subtests run
All tests successful.

Test Summary Report
t/edit.t (Wstat: 256 Tests: 0 Failed: 0)
Non-zero exit status: 1
  Parse errors: No plan found in TAP output
Files=1, Tests=0,  4 wallclock secs
Result: FAILED

The fix is simple:

echo >> lib/Storage/File.pm6

The result:

    ok 1 - Status is acceptable
    ok 2 - Content type is acceptable
    ok 3 - Body is acceptable
ok 1 - GET /edit/About
    ok 1 - Status is acceptable
    ok 2 - Content type is acceptable
    ok 3 - Body is acceptable
ok 2 - POST /save
ok 3 - page name correct
ok 4 - page content saved
ok 5 - changes correct
ok 6 - year
ok 7 - time
ok 8 - major change
ok 9 - page name
ok 10 - code
ok 11 - summary
    ok 1 - Status is acceptable
    ok 2 - Content type is acceptable
    ok 3 - Body is acceptable
ok 12 - POST /save
ok 13 - year
ok 14 - time
ok 15 - minor change
ok 16 - page name
ok 17 - author
ok 18 - summary
t/edit.t .. ok
All tests successful.
Files=1, Tests=18,  6 wallclock secs
Result: PASS

How weird is that? I asked on the #perl6 channel and one of the people there was curious and was interested in fixing this. Sadly, I was unable to produce a small working example. I tried for quite a while. I have no idea what causes this.


Comments on 2018-09-18 Thoughts on using Perl 6

Sadly, I was unable to produce a small working example. I tried for quite a while. I have no idea what causes this.

I can try something without a small example, as long as you can provide any example that reproduces the issue in at least a semi-reliable fashion. Basically we have a bunch of tools that can run stuff on any given rakudo commit, and bisect if necessary. Just ping me on #perl6 if you have that (a zip file or something like that will do) and I’ll try to find out if it’s a new issue or if it existed before, and we’ll see what caused it if it’s new.

– AlexDaniel 2018-09-18 22:28 UTC

Add Comment

2018-09-08 What would a new Oddmuse be?

I was at the Swiss Perl Workshop and bought Perl 6 Deep Dive by Andrew Shitov. I’m again enthused by the idea of writing an application in Perl 6.

What would a new Oddmuse be like? If I’d write a new wiki using Perl 6 instead of Perl 5, I’d like to keep the name. It’d be Oddmuse 6 for a while, and then it’d simply be Oddmuse again.

Here’s how I would start:

  • install rakudo-star
  • install cro
  • create a stub ✓
  • implement a view action ✓
  • use Markdown::Text to render text ✓
  • text is loaded from text files in a page directory ✓
  • implement an edit action ✓
  • text is saved in text files ✓

I guess this is how far I got with Oddµ: A Small Wiki Written in Go, more or less. At the time I still believed in WikiCreole. But there’s more.

  • old revisions are kept in a a keep directory, like today
  • write an OpenAPI Specification as we go along
  • a log file for recent changes is still used, don’t use git or the like because I want data to be ephemeral and old revisions to fade away into oblivion
  • meta data is kept in a separate file, not mixed with the text file
  • implement a changes action
  • implement a feed action
  • implement a history action
  • implement a rollback action
  • implement a diff action including the highlighting of changed words
  • implement merging of files
  • implement error handing for merge conflicts, unlike now where the conflict is saved
  • add HTTPS
  • add passwords
  • implement banning of URL fragments and regular expressions matching text for admins
  • implement page locking and site locking for admins

This would result in a small, functional wiki. The user interface wouldn’t be template based, just like it isn’t template based right now. I think this is necessary to make it easy to mix and match extensions.

I think that, like before, we should move as much as possible into modules. So once we’re at this stage, we need to think about ways people can “compose grammars” for their text rendering.


Comments on 2018-09-08 What would a new Oddmuse be?

Hey! :)

So it has been a while since I touched Oddmuse, but here are some of my (previous) random realizations.

  • The user interface can be wiki-based. That is, a top page can be used to render everything, as if that page was a template by itself. It can be markdown or whatever, as long as you can extend it enough to be able to call internal-ish functions from it. This is similar to sidebar / gotobar oddmuse extensions, just one tiny step ahead.
  • Another potentially crazy idea is to make any editable thing a page, e.g. settings and what not. That page does not have to be editable, e.g. it can be hardcoded internally to always be the same, but that can open a lot of potential for other awesome things.
  • Cro is the right choice, yes.
  • Grammar-based parsing would be ideal, but parsing wiki markup with grammars is a pain (one challenge is that any input is valid)… I actually experimented with it for quite a bit and even managed to do multiple grammars (e.g. basic Markdown and basic Creole) which can then be combined to achieve Markdown + Creole parsing. It does work, it can be done, but it needs quite some manpower which I currently can’t provide.
  • As of today, avoid DBIish and keep file-based db. There are multiple stability issues with DBIish, so even if you wanted to use a proper DBMS you’d regret it…
  • Maybe JSON for storing pages? I don’t know… I’m slightly worried about attacks focusing on edge cases in json parsing. But that’d be an easy and good start I guess.
  • Make page store backend as a separate module/plugin (can be in the same file though, that doesn’t matter). Just so that those who need Git backend can easily plug it in when, or so that eventually people can use a DBMS if they want to.

FWIW, I’m quite happy with most of the things in oddmuse5. So if it was the same thing, but with biggest pain points (html5, CSP, etc.) resolved, I’d be a happy user again :)

Ah, also you’d probably need caching just like in oddmuse5 (because Rakudo is currently slow-ish). It’s a useful mechanism for other things too.

– AlexDaniel 2018-09-09 16:59 UTC

Thanks for the feedback! Now all I need to do is find some time. :)

– Alex Schroeder 2018-09-10 10:25 UTC

Oddmuse 6, first commit! :)

– Alex Schroeder 2018-09-12 16:22 UTC

Rewriting it to be based on Template::Mustache. Still 100% Text::Markown. No revisions, no recent changes, no CSS. Not even page editing works. But there’s already and edit link and it shows the raw text if you click on it.


– Alex Schroeder 2018-09-13 15:59 UTC

Hi Alex,

I am proud I sold the book to you at the Swiss Perl Workshop 2018. Interesting blog, interesting plan. I hope you succeed and will give a good presentation about it next year at the Swiss Perl Workshop 2019.

I hope you don’t mind, but my happiness lead me to writing about you on Facebook, and I posted in the Perl6 group (which is open, no need for an account to read; an account is needed to write though).

– Wendy van Dijk 2018-09-13 18:50 UTC

Thanks! :)

– Alex Schroeder 2018-09-13 21:54 UTC

Very interesting! A small, tractable wiki in the spirit of oddmuse would be fab!

I checked out the repo, and noticed that the first paragraph of the README is quite confusing: “...based on Perl 5 ... instead of Perl 5...”

– Robert Lemmen 2018-09-14 12:03 UTC

Hah! Thanks for the heads up. Fixed!

– Alex Schroeder 2018-09-14 17:05 UTC

Editing pages works. CSS added. Tests added.

– Alex Schroeder 2018-09-17 09:02 UTC

Sadly, Git::PurePerl only does checkout and clone, Git::Simple is archived by the author and all the forks are lagging behind instead of forging ahead, Git::Wrapper leads to a 404, wow, the situation is bad for Perl 6 Modules about git. Maybe LibGit2 will do it?

sudo apt install libgit2-dev
zef install LibGit2

This fails with an error... but this works:

zef install https://github.com/CurtTilmes/perl6-libgit2.git

– Alex Schroeder 2018-09-17 11:06 UTC

I ran out of steam on LibGit2 a while back. It has the basics, but LibGit2 is really, really big (and complicated), so not everything is in there yet. – if it is missing anything you need, file an issue, and I may find some time to implement some more. It actually has a lot more functionality than is completely documented, if you can’t figure something out, file an issue and I’ll try to write some more docs. The tests can be helpful to figure out how to use it too.

I’m also trying to add more Perl 6-ish ways to do things conveniently, so if something seems harder than it should be, file an issue..

I’ll try to figure out why the install failed for you.

If you do want a database, I agree DBIish has issues, but I’m using DB::Pg with PostgreSQL pretty heavily and it has been solid for me. If anything breaks with it for you, please file an issue. I recently fixed a bug with embedded NULLs in arrays I haven’t yet released, so there will be a new release of it soon.

– Curt Tilmes 2018-09-18 01:19 UTC


– Alex Schroeder 2018-09-18 12:49 UTC

Anyway, I am happy to report that I have a form of recent changes:

Screenshot of Recent Changes

As you can see, the IP numbers are pseudo-anonymized and colour coded.

– Alex Schroeder 2018-09-18 13:20 UTC

Add Comment

2018-07-19 Paginated Feeds

Recently, @jamey was talking about feed pagination (RFC 5005). I finally got around to adding the necessary code to Oddmuse and deploy it for all my sites. So if you check out Recent Changes and click on RSS with pages you should get a feed for all the pages changed in the last month (ignoring minor changes), and if your feed reader supported it, you could fetch previous pages of the same feed and thus scroll through the backlog until somewhere around 2003 those edits would dry up and there’d be nothing left but empty pages.

I’m currently not implementing the first page link so your feed reader wouldn’t realize that it should stop going back in time. It will follow links forever but eventually loops things will get strange. I just tried to see how far back in “negative time” we can go and if we try it with Recent Changes, you’ll get a page saying “Updates since 1900-01-00 00:00 UTC up to 1970-01-01 00:00 UTC”. I guess 1900 is the limit, then. 😂


Comments on 2018-07-19 Paginated Feeds

Sadly, the Journal RSS Extension – which I use a lot – doesn’t fit into the existing RC/RSS framework.

– Alex Schroeder 2018-07-19 12:03 UTC

Add Comment

2018-06-06 Away from GitHub

Microsoft is buying GitHub. Mastodon is abuzz with discussions. Let’s remind ourselves of Embrace, extend, and extinguish, the phrase used internally by Microsoft to describe its strategy for entering product categories involving widely used standards, extending those standards with proprietary capabilities, and then using those differences to disadvantage its competitors, according to Wikipedia. 🤢

Just read through the examples on that page. 🤮

So I want to move away from GitHub.

Git itself is federated. You can pull from anywhere and push wherever they allow you to. Some of the things you cannot do, however:

  • send patches via the website
  • track issues
  • browse code and documentation online

What other functionality do you use? I think that’s all I do.

Maybe I’ll just create a software wiki for myself which implements these features and leave it at that. This requires a few things:

  1. hosting my own git repositories ✔️
  2. a platform to manage tickets ✔️
  3. notifications by mail ✔️

I have a proof of concept up and running. It’s based on Oddmuse and a bunch of additions in the config file.

I suspect it’s either going to be that, or something like Fossil. The main drawback is that nobody else uses it, however. All those Mercurial users know what I’m talking about. I know that I don’t like to contribute to projects using “unpopular” version control software.

Fossil has tickets and it serves a website for its repositories. I dislike the database stuff but SQLite has a good reputation and at the end of the day all the .git directories are gobbledygook to me anyway.

I don’t really need code browsing via the web. That’s why I don’t need cgit, I think. I hardly ever do it. Sometimes I link to particular lines of code when I comment on an issue, perhaps. I guess I do kind of miss the cheap README.md = project homepage and project documentation.

A feature I sometimes used was online text editing: I sometimes fixed typos in documents which resulted in automatic pull requests on GitHub and that was useful and cool.

The other alternatives like GitLab and Gitea have a reputation for needing a lot of resources, so that’s bad.


Comments on 2018-06-06 Away from GitHub

JWZ comments: “Anyway, this is your periodic reminder that Microsoft is a vile garbage fire of a company.”

– Alex

I guess I do kind of miss the cheap README.md = project homepage and project documentation.

cgit actually kind of has this, I just discovered. Just sprinkle this in your /etc/cgitrc:


(above scan-path, if you put that in your cgitrc).


· http://koldfront.dk/git/fffs/about/

(I haven’t fixed the broken image link yet).

Adam 2018-06-06 14:51 UTC

Nice! And works for me: Face Generator README.

Current setup:

# cgit config
# see cgitrc(5) for details





Anything else I would need?

– Alex Schroeder 2018-06-07 06:14 UTC

Note to self: I use git clone ssh://git@alexschroeder.ch:882/home/git/face.git where as others will use git clone https://alexschroeder.ch/cgit/face.

– Alex Schroeder 2018-06-07 07:15 UTC

The only things I have besides what you’ve got is:


and I’ve set root-title and root-desc

Adam 2018-06-08 15:31 UTC


– Alex Schroeder 2018-06-08 15:36 UTC

I’m also using this opportunity to splitting subfolders out into new repositories for some projects. The GitHub help pages are still useful. :)

– Alex Schroeder 2018-06-09 20:25 UTC

Free Software Needs Free Tools. «The only cost, we are told, is that the tools themselves are nonfree or run as network services with code we cannot see, copy, or run ourselves. In their decisions to use these tools and services—services such as BitKeeper, SourceForge, Google Code and GitHub—free software developers have made “ends-justify-the-means” decisions that trade away the freedom of both their developer communities and their users. These decisions to embrace nonfree and private development tools undermine our credibility in advocating for software freedom and compromise our freedom, and that of our users, in ways that we should reject.»

– Alex Schroeder 2018-06-21 19:06 UTC

Add Comment

2018-05-27 Privacy Policies

I’ve been writing some privacy policy statements...

I will need a few more: Community Wiki, Campaign Wiki, etc. But they’ll all be basically copies of the Oddmuse Wiki Privacy Statement. I might have to adapt the markup but basically that’s it. From an admin perspective, they’re all set up the same way: they use the same software and the logs all use the same logrotate configuration.


Add Comment

2018-05-24 Feeds

I think I’m going to unsubscribe from all the blogs that don’t provide full articles in their feed. If they do that, I need to click through and open a browser. That makes me think people want to show me their ads and I’m doing my very best to block them. They probably don’t like me blocking the ads, and I don’t like seeing the ads, so it’s better to part ways, I think. And now I can use feh as the external browser for newsboat, I guess. (feh is a simple image viewer.)

Sometimes I guess the fault lies with the authors of tools and the defaults they picked. What were they thinking? Then again, the Oddmuse default feed (my own wiki and blog software) also defaults to showing the default instead of the full text. Gah.


  • default RSS feed, which works for a wiki but not for a blog
  • the preferred feed I manually added to the configuration of my site such that it gets picked up by tools people point at my site


Comments on 2018-05-24 Feeds

Another thing I noticed on your default feed is it includes comments (I like that!). Is there a way Oddmuse can combine the full feed with comments in full? Call it the “deluxe” feed, if you will!



– At PresGas at freeradical dot zone 2018-05-25 17:21 UTC

I noticed that my markup rule for Mastodon accounts assumes all lower case for account names. Heh. 😏

– Alex Schroeder 2018-05-25 22:20 UTC

I’ll have to investigate the full feed thing. It should be possible for sure.

– Alex Schroeder 2018-05-25 22:21 UTC

https://alexschroeder.ch/wiki?action=rss;full=1 Perhaps?

– Alex Schroeder 2018-05-25 22:22 UTC

Hey! I believe that does it. Trying it out on newsboat/newsbeuter (haven’t fully migrated my server to 18.04 Xubuntu) shortly, but Firefox’s view looks good

– At PresGas at freeradical dot zone 2018-05-26 02:12 UTC

Add Comment

2018-03-17 Oddmuse and the EU

I have started working on a plan for Oddmuse regarding the EU Data Protection Directive, today. You can read about it on the Oddmuse Wiki.

The basic idea is that I want to get rid of IP numbers as far as possible. I got rid of hostnames a while back already. But IP numbers are still to be found all over the place.

My plans:

  1. run the strip-host.pl script for all my sites
  2. work on the remaining issues as listed on link above


Add Comment

2018-03-05 Troff

When writing for this wiki, I am always conscious of how it will look using Gopher. Basically raw mode. This includes thinking about line breaks. And I end up not liking inline linking so much. It makes the plain text really hard to read. But writing the plain text with manual line breaks on a handheld device runs into the problem that iOS will autocapitalize all line beginnings. You have to “fix” that manually. And it uses “real” quotes, which are neither ASCII nor Latin-1 so older Gopher clients fail to display them correctly.

Into all this mess comes a Gopher post by dbucklin about using Troff. That’s an old formatting tool from the very early days. Way older than LaTeX, and that’s pretty old, too. It’s an excellent introduction for somebody who knows nothing about it. I want to give it a try because all the the things that are old but that have been kept alive by enthusiasts have their own ways of being super efficient.

I guess that’s why I use Emacs, too. It’s weird, but it works, if you adapt to it’s way of working. These things are like living fossils. We like to think that those are species that split off from the rest millennial ago and thus they are “primitive” but not so: they just evolved on their own, for exactly the same amount of time, and they are just as adapted to their niche as whatever mainstream is to its niche.

Anyway, looking at troff was very cool, but I think I will continue to manually write Markdown on these wiki pages and I just hope that future changes to this site will be able to automatically migrate from one format to the next. Then again, if you look at the old pages, you will see how well that worked in past as I switched markup rules. If you look hard enough, you will see how badly it worked, actually.

There is a lot of cover-up at work. HTML is being cached, for example. But every global search-and-replace operation that touches a page discards the cached HTML and regenerates it and therefore if those global search-and-replace operations don’t do their job, the leftover markup is broken, and the HTML cache is useless.

Oh well. Here is to hoping that Markdown will last longer than WikiWiki markup, UseModWiki markup, or WikiCreole markup. At least it’s not limited to just the wiki world!

I’m sure there is a Troff markup wiki somewhere. It would Be beautiful in plain text, HTML, or PDF. (I assume?) But I will stick to manually formatting the text I write in Markdown, for now.

That reminds me that my implementation of CommonMark is still sorely lacking.


Add Comment

2018-02-12 Gay Halifax

Every now and then I’m surprised to learn that the Rainbow Community for Halifax, Nova Scotia uses Oddmuse for their site. Daniel MacKay runs the site and that makes him the biggest Oddmuse user other than me, I think.

Oddmuse is the wiki engine running this site. A wiki is a kind of light weight content management system with an emphasis on simplicity (ideally, hah!). Basically anybody is can edit pages. Originally there was not much more to it than that and projects like Smallest Wiki showed how you could get these going in just a few lines of code. Or this wiki I wrote in Go a few years ago: Oddµ.

If you want to come and talk to us, fire up your IRC clients and join us on Freenode, in the #oddmuse channel. The link takes you to a web chat thing so that you can get a feel for it without having to struggle with an IRC client.


Add Comment

2018-02-02 Markdown

I’m having fun implementing the CommonMark Spec 0.28 for Oddmuse using their spec file for automated testing. Current status:

# Looks like you failed 493 tests of 624.

Implementing simple stuff is fun. :)


Comments on 2018-02-02 Markdown

OK, sometimes it is not as fun it could be:

This is not emphasis, because the closing * is preceded by whitespace:
*foo bar *

This is hard for the Oddmuse parser because it works like a state machine and prints immediately when looking at every token. So for Oddmuse, starting at the first * it sees a legal beginning of emphasis and prints <em> without considering whether there is a legal end to this emphasis. Oddmuse will print the closing tag when the paragraph ends. But that’s not what CommonMark wants us to do. And I can’t use a simple positive look-ahead as that will fail in this situation as the closing emphasis is actually within a code element and thus it seems to me that I need to parse and backtrack in order to solve this problem. Gaaaah.

*foo `bar* bar`

– Alex Schroeder 2018-02-03 13:03 UTC

Add Comment



Please make sure you contribute only your own work, or work licensed under the GNU Free Documentation License. Note: in order to facilitate peer review and fight vandalism, we will store your IP number for a number of days. See Privacy Policy for more information. See Info for text formatting rules. You can edit the comment page if you need to fix typos. You can subscribe to new comments by email without leaving a comment.

To save this page you must answer this question:

Please say HELLO.