dīxī (v. fp. s. perf. act. ind.) to speak, to declare.
This project is a simple wiki developed based on a firm theoretical foundation. The details are explained in the section “What makes this special?” below.
dixi supports editing of any version of a page,
and the changes will be propagated through to the latest
version in a way that makes sense.
It is also able to revert changes (or the composition of several changes) from deep in a document’s history and preserve every other change.
Right now the wiki doesn’t support many bells and whistles, such as administrator control or user accounts, but they’re coming.
You can get
dixi from Hackage, by using
to install it.
cabal update cabal install dixi
You can also build it from source, using
cabal sandbox init cabal install --only-dependencies # be warned, this will take some time cabal configure cabal build ./dist/build/dixi/dixi
If you prefer, you can also use
stack rather than
stack build stack exec dixi
stack-*.yaml files are available in the repository for various snapshots. By default, we support two recent LTS Haskell versions as well as a recent nightly stackage.
The configuration file is in YAML format, and by default should
config.yaml in the current directory. Happily,
dixi will prompt
you to create a file with the default configuration if it can’t find the file.
The default configuration is simply:
time: format: '%T, %F' # C style format string for displaying times timezone: Etc/UTC # Time zone as found in tzdata port: 8000 # TCP port to run on storage: state # Directory to store data, must be writable. readerFormat: org # Pandoc format to use. Can be any of: # commonmark, rst, markdown, mediawiki, # docbook, opml, org, textile, html, # latex, haddock, twiki, t2t url: http://localhost:8000 # base url of your application, for links processors: # a list of pandoc document processors to use - wikilinks # right now, we only have the wikilinks processor static: static # Directory to store static files like stylesheets, # served under the /static/ url. # This option can be omitted and static files will # not be served by dixi, if you'd rather nginx # or apache do it for you. stylesheet: style.css # Name of the stylesheet file to use. # If dixi is serving static files, you will # be prompted to create a default stylesheet # in the static directory if one doesn't exist. math: katex # How to handle LaTeX math, can be one of: # plain, mathml, latexmathml, mathjax, katex # CDN scripts are loaded when any of the last three # methods are chosen.
You can also tell
dixi to look elsewhere for a
providing the file’s path as a command-line argument, e.g:
dixi is running, just navigate to
localhost:8000 (or whatever port
dixi is configured to run on)
and you will be shown the (presumably blank) Main Page. The toolbar at the top provides most useful tools.
Other pages are located at
/Page_Title. Underscores are displayed as spaces in the output, and spaces
in the URL are converted to underscores.
Internal wikilinks can be made by making a link that goes nowhere, or by using built-in wiki syntax if your input format supports it
[[a wikilink]] (for org mode) [a wikilink]() (for markdown) [[a wikilink]] (for mediawiki) [[a wikilink|Custom title]] (for mediawiki)
This processing can be disabled by removing the
wikilinks processor in the list in the configuration file.
The entire wiki can also be accessed and modified by a JSON API. Basic API documentation can be generated by running
the “test suite” provided in the cabal file, which will in fact generate a markdown file named
or otherwise whatever name is provided as the first command line argument. If you’re using stack, simply run
and view the results.
HTML documentation can then be generated via
pandoc or other tools, using the
buttondown style provided, courtesy of
stack test && stack exec pandoc -- docs.md -s -c buttondown.css -o docs.html # or in cabal... cabal test pandoc docs.md -s -c buttondown.css -o docs.html # Assuming pandoc is in your path.
Tons! I’ll use GitHub issues to keep track of features I’d like to add, so look over there.
What makes this special?
Most wikis do not take much care in their implementations. They’re buggy, monstrious pieces of software that violate basic principles of software engineering as well as exhibiting complete disregard for computer science.
It turns out, computer scientists and software engineers have long sinced developed tools, both in theory and practice, that allow us to implement wikis a lot better than has been done previously.
- The use of the theory of patches (really, just the groupoid structure of patches) to allow us to easily compose and revert patches. This is embodied in my patches-vector library.
- The use of operational transformation to move patches relative to other patches, and handle merging, which is also in my patches-vector library.
- The use of efficient composition trees to allow us to efficiently compute the composition of several changes, and also to eliminate the need to store each version of the document independently.
- The use of property-based testing to formally specify all of the above and test each implementation against
its specification, which is rigorous and thorough. For
patches-vector, the groupoid laws and several transformation properties are checked. For
composition-tree, several properties are derived from the fact that a composition tree is a data refinement of a list.
- The use of the acid-state library to store these composition trees, which provides proper ACID guarantees for immutable Haskell data structures.
- The use of the servant library to specify the API and web server for the wiki in a concise, and type-safe way, minimising errors in the CRUD logic, and preventing broken links statically.
- The use of the Haskell programming language, which provides the type- and eco-systems necessary to make this kind of rigorous software engineering possible.
The other noteworthy thing is that the excellent library pandoc is used, which makes the wiki rather full featured without me having to do very much in the area of document formatting.