OmniFlux - Single-Page Wiki

You're looking at a complete, self-contained wiki. This one file can be downloaded, the pages can be updated using Markdown, and then everything can be saved. It even supports autosaving when content changes! Try it now by pressing the "Edit" button in the upper right. Learn about supported Markdown.

After downloading, you're able to use this as a personal wiki, a project wiki, diary, a collection of organized notes, or simply an easy way to track potentially related pieces of information. It works entirely in the browser and does not require any server-side code. You can even use it on a mobile device.

Download options:

TL;DRWhereWhy / How
EasiestWithin this wikiOpen the sidebar, click Saving, then follow the instructions.
LatestOmniFlux DocsGet it from the source. Includes all documentation, a custom element, commented JavaScript and CSS, plus the solar flare image (about 108k). Right-click and "Save Link As."
SmallestTiny VersionMinified, no content. When every byte matters (about 21k).
CustomGitHub repositoryBuild your own!

Changelog - GitHub - License

Features

Linked image examples: Octocat Solar Flare
Octocat is external, the solar flare is completely within the wiki.

How to Use

Edit any page by pressing the Edit button or by pressing control+enter or cmd+enter. When editing, the Cancel button will not save your changes and the Save button will keep them. When editing, you can also press control+enter or cmd+enter to save.

Links to other pages are done by linking to the ID as a location hash. The index page has no ID, like [Main Page](#). Other pages have an ID, like [Markdown Syntax](#markdown).

Create a new page by making a link to it. Edit any page and paste in the Markdown to link to a page, like this example: [New Page](#new-page). By clicking the link, you will see the edit screen to create the content for the page as shown here: New Page.

The "Overview" section in the sidebar is under your control. Change the Overview page and it will automatically get copied to the sidebar.

The sidebar generates the "Index" entries for every page in the wiki. It will use the first heading found on the page, like # Page Title. If no heading is found, it converts the ID into a page title.

To delete a page, start by editing it. From there, either remove all content and press Save, or you can press the Delete button. The page will be removed from the index and the sidebar.

Credits

CSS-based navigation is from 1.5KB Single-File Wiki. It's fantastic.

The original method for converting Markdown to HTML started from the 1.5KB Single-File Wiki as well, but has diverged significantly. Now, DOM elements are used and the code takes advantage of limited recursion. Also, the Markdown syntax has been expanded and previous patterns were changed to be more stringent.

The CSS-powered slide-in menu comes from The "Checkbox Hack" (and things you can do with it) with a fancier hamburger icon courtesy of Definitely Pure HTML/CSS animated Hamburger.

HTML to Markdown conversion walks the DOM (an approach similar to Downshow), but the similarities end there. This is an entirely different implementation.

The ability to add a single copy of an image and reference it on multiple pages, yet still treat it as an image is leveraging <svg><use /></svg>, which is able to reference any element in the document. RFC 2397 explains the data URL scheme and shows how to embed additional information.

Markdown Syntax

Markdown is supported, though not all features are included. This page will explain all of your available options, including common patterns that are not supported.

When something is marked as "not supported", you could contribute code through a pull request.

Basic formatting

Use italics, bold, and both. This works evenwithinwords. Also, strikethrough and underline. You can even combine these.

*italics*, **bold**, and ***both***.
~~strikethrough~~, ~underline~, and ~*combined*~.

Paragraphs are one long line. These will become a single paragraph. Do not use newlines inside of a paragraph unless you want the paragraph broken onto another line, like the following message:

When you use newlines
Then a break will be added
Make your own haiku

Avoid

Using _underscores_ for emphasis (bold, italics, both) will not work.

Headings

Headings 1 through 6 are supported. Put the corresponding number of # symbols at the beginning of a line.

## Headings

Avoid

The alternate method of using a line of ------ or ====== underneath the heading is not supported.

Lists

  1. Ordered lists are supported.
  2. Just prefix each list item with a number and a period.
1. First Item
2. Second Item
- First Item
- Second Item

You can also use nested lists.

- Naughty List
  1. Tyler
  2. Brian
- Nice list
  - Basically everyone else

Task lists are allowed and they can be nested. When you click on a task to mark it complete or incomplete, it updates the wiki. If autosave is enabled, the updated wiki is also saved.

- [ ] Not done
- [x] Done

Avoid

Starting the numbering of a list with any number other than 1 is not supported.

Using + or * for list items will work, but they will be converted to - when editing the list again.

Images and Links

URLs are converted automatically: https://fidian.github.io/omniflux

Link to an external page: OmniFlux

[Link Text](https://example.com/)

Linking to an internal page is accomplished in two different ways. When the link text matches the ID, you can surround in double brackets, like Changelog and Fair Comparison, When you want a custom name for a page, you link using a standard link, like Main Page and Markdown Info.

[[Changelog]] and [[Fair Comparison]]
[Main Page](#) and [Markdown Info](#markdown)

External image: Octocat (the "alt text" is also converted to a title)

![Octocat](https://fidian.github.io/omniflux/octocat.svg)

Linking around an external image: Octocat

[![Octocat](https://fidian.github.io/omniflux/octocat.svg)](https://fidian.github.io/omniflux/octocat.svg)

Images that are uploaded into the wiki can be referenced and used in any page, like this solar flare: Solar Flare

![Solar Flare](#solar-flare.jpg)

Avoid

Links can have titles by adding a description after the URL, but that's unsupported.

Do not use angle brackets (< and >) around a URL to turn it into a link. Similarly, URLs without http:// or https:// in front are not linked.

Email addresses are not linked automatically.

Reference-style links are not supported, which is where a link is used in one or more spots, but the URL is maintained elsewhere.

Uploading images into the wiki will make it significantly increase in size.

Code

Short passages of code can stand out by using a single backtick at the start and end of the inline passage, like this.

You can enter a block of code by having a line of three backticks in a row to start the section and another three backticks in a row to end the section. Edit this page to see many examples of embedded code blocks.

Code fences are supported and language information is preserved.

While code fences support language information, no highlighting happens at this stage in order to keep the wiki small. If you want it, check out Code Highlighting for instructions.

Avoid

Code fences can specify a language, but no special highlighting happens by default.

Indenting a block of code with 4 spaces will not turn it into a code block.

Backticks within a code block are not supported.

Blockquotes

Start each line with > to have a blockquote.

This is an example.
Markdown inside is supported.

Nested blockquotes work.
Use > > (or more) at the beginning of the line.

> This is an example
>
> > Nested blockquotes work.

Avoid

Make sure to use exactly 1 space. This parser will not convert lines with 0 spaces into blockquotes. Lines with more than 1 space will have the extra space parsed as though it is part of the Markdown content, which could have unintended consequences.

Tables

Standard Markdown works for tables, plus alignment is supported. Headings are required.

Tables are automatically formatted in the Markdown to align on columns for easier editing. This happens every time, so don't worry about extra whitespace or formatting while editing. OmniFlux will clean it up for you!

LeftCenterRight
ShortMedium LengthSuper Long Entry
Medium LengthSuper Long EntryShort
Super Long EntryShortMedium Length

Markdown formatting within cells is allowed.

| Left | Center | Right |
| ---- | :----: | ----: |
| 1    |   1    |     1 |
| 10   |   10   |    10 |
| 100  |  100   |   100 |

Avoid

Nested pipe characters within a table is not supported, not even within backticks for code.

Horizontal Rules

Three or more dashes in a row on a line by itself produces this line.


---

Avoid

Probably avoid overusing these. Headings are a better way to separate content.

Custom Elements

You can add a custom element by simply including the JavaScript and HTML. See Custom Elements to learn more.

<custom-element>Hello!</custom-element>

Completely Unsupported

Embedding HTML within the Markdown is not supported, except for custom elements. This is a tricky thing to do, especially since the conversion needs to accurately be bidirectional. However, you can accomplish this using the raw-html Custom Element example.

The <del> tag isn't created when using ~~~text~~~.

Anchors, like #[jump-here] since the wiki uses CSS-based navigation that relies on the location hash and there's a concern about duplicating a page ID and a user-generated ID.

Footnotes.

Rule Processing

When converting Markdown to HTML, there are a bunch of rules that need to get applied in a particular order. Also, sometimes rules need to build on themselves, such as when an image is linked. The rule processing engine is a generic way to process a string through a set of rules and have handlers decide how each interaction unfolds.

The Markdown first will look for block-level markup. Each time a chunk is found, that chunk is processed fully. This means the Markdown is converted to DOM elements for that block level element and any inline elements within the block.

Inline elements are a bit more tricky due to possibly wanting recursion and sometimes not. For instance, using backticks for code means anything within needs to be excluded from further processing, but one could have a bolded word in a link.

Rule Definitions

Each rule is governed by a pattern and a handler. When the pattern matches text, the match result is passed in as arguments to the handler. This supports groups. Take, for example, this rule for strikeout text, or the second rule for erasing newlines.

[/~~(.+?)~~/, (entireMatch, txt) => dom('s', txt)

[/\n+/, () => []]

If the first pattern was matched against the string "one ~~two~~ three", then the handler's entireMatch variable will be "~~two~~" and the txt variable will be "two".

Each handler needs to return completely processed HTML as an array of DOM elements or strings that will be escaped. HTML strings are not allowed to be returned.

Markdown Processing Quick Overview

First, block handlers will look for block-level elements. When a match is found, it must handle the block and all of the inlines within. Typically a block handler will match the beginning and end of a section of a document and then will pass chunks of text to an inline processing function. If there is something that a block-level handler does not match, that content is entirely discarded.

The rule processing order will try to find the rule that matches the earliest. If there are multiple that match, the one that is listed first in the rule set will be used. Block-level processing doesn't care too much about this, but inline markup will. Take, for instance, a linked image in Markdown: [![ALT](image_url)](link_url). The pattern for the link will be processed and it needs to match the entire link (including the image portion), then that handler needs to call a function to parse ![ALT](image_url) into HTML.

Changelog
Code Highlighting
Custom Elements
Fair Comparison
Markdown Syntax
Rule Processing
Saving with WebDAV
Upgrading

Changelog

Is your version a little stale or missing some features? Learn how to upgrade!

Upgrading OmniFlux

You can copy all of your pages to a new copy of OmniFlux in order to upgrade it to the latest version. The upgrade process also will copy any extra <script> and <style> elements that were added. These will be placed just after the core script and styles to make the wiki function.

The process is painless.

  1. Save a copy of your existing wiki to your local drive.
  2. Load up a new version of OmniFlux from the documentation site.
  3. Open the sidebar and go to "Actions".
  4. (Optional) Erase all pages by clicking "Remove All Pages".
  5. Import your old content by clicking "Import Pages" and selecting the saved wiki from step 1.
  6. Save the upgraded wiki.

What gets copied?

In addition, the sidebar is updated after the import to reflect the new state of the wiki.

Code Highlighting

You are able to include Prism or another library within the wiki in order to highlight code blocks. Code fences in Markdown will automatically add class="language-xxxx" to the <code> element, allowing tools like Prism to work.

  1. Go to the download page for Prism.
  2. Select the desired theme.
  3. Select additional highlighting languages you want.
  4. Keep the browser window open and edit a saved copy of this wiki.
  5. Copy and paste the extra JavaScript needed for Prism to a new <script> element added just before the closing </body> tag. See below for an example.
  6. Copy and paste the necessary CSS into a new <style> element added just before the closing </head> tag. See below for an example.
  7. See the section titled "Problems" for an additional <script> element.
  8. Save the wiki HTML and verify that code fences are highlighted by reloading the wiki in your browser.

Upgrades will keep your extra CSS and JavaScript as long as you add them as new <style> and <script> elements.

Where to add CSS

Look for the closing </head> tag.

</style></head><body><div class="of_articles"><article class="index">

Add your own <style> tag just before </head> and the necessary CSS within.

</style>
<style>
/* Add your CSS here, within a new <style> element. */
</style>
</head><body><div class="of_articles"><article class="index">

Where to add JavaScript

Look for the closing </body> tag.

</script></body></html>

After the </script> tag and before </body>, add your own <script> tag.

</script>
<script>
/* Add your JavaScript here, within a new <script> element. */
</script>
</body></html>

Problems

Sadly, Prism does not handle addition of <code> elements dynamically. See issue #1115 for others wanting this same feature. However, you can have this happen by adding another <script> element. Like before, you want this one just before </body>, which will be just after the new <script> that was added to set up Prism.

<script>
MutationObserver(mutations => {
  for (const mutation of mutations) {
    if (mutation.type === 'childList' &&
        mutation.target.nodeName === 'ARTICLE' &&
        mutation.addedNodes.length > 0) {
      Prism.highlightAllUnder(mutation.target);
    }
  }
}).observe(document.body, { childList: true, subtree: true });
</script>

Another issue is that some plugins, like toolbar plugins, will add extra elements to the HTML. This makes the HTML to Markdown conversion think that there is extra text. For instance, the "Copy to Clipboard Button" does this, which adds a "Copy" paragraph in the Markdown. Be careful when adding plugins and ensure they don't modify the DOM dramatically.

đŸ–Ģ list-of-names.csv

This is a really short CSV file with a list of names and if they have been naughty or nice.

list-of-names.csv

đŸ–ŧ solar-flare.jpg

This is a small image that's embedded into the wiki. When you use it elsewhere, the image's data is referenced from this page, which means the image acts and works like a real image everywhere except it's data is never repeated.

You can use it like this: ![Solar Flare](#solar-flare.jpg)

solar-flare.jpg

Fair Comparison

All of the wikis compared here are ones that work with no installation, no server-side software, and nothing more than just a web browser. Make sure to read the reviews and pick the system that would work best for your purposes.

If you know of other self-contained wikis in this same vein, please let me know by opening an issue.

Wiki SoftwareStatusOne FileEditingSizePluginsStorage
1.5KB Single-File WikiPOCYesMarkdown9kNoHTML + Template
Feather WikiMatureYesWYSIWYG / MD56kYesJSON
OmniFluxNewYesMarkdown21kNoHTML
TiddlyWikiMatureYesMarkdown2,490kYesJSON
WOASOldNoWikiText408kNoJSON
WOAS ForkMatureYesWikiText732kNoJSON
XiePOCYesMarkdown9kNoHTML

The table above and each section below will provide statistics and figures about the wikis in order to more easily compare across projects.

1.5KB Single-File Wiki

Goal: How small can a fully editable wiki possibly be?

AttributeValue
StatusProof of Concept
One FileYes
EditingMarkdown
Size9 kilobytes
ExtensibleNo
StorageHTML + Template
Embed FilesNo
Local SavingYes, file downloader
Server-Side SavingNo
SearchingNo

Pros

Lightweight, CSS-based wiki that only needs JavaScript for editing. This is what inspired OmniFlux.

Viewable without JavaScript. Relies on CSS for navigation.

Cons

Content is stored twice, once as rendered HTML and once as a template that contains the raw Markdown.

Markdown conversion is somewhat buggy at times for specific examples.

Feather Wiki

Goal: A practical, extensible personal wiki that lives in a single file.

AttributeValue
StatusMature
One FileYes
EditingWYSIWYG / MD
Size56 kilobytes
ExtensibleYes, through custom JavaScript
StorageJSON
Embed FilesYes, images only
Local SavingYes, file downloader
Server-Side SavingYes, WebDAV
SearchingYes, through plugins

Pros

A more traditional, page-based navigation style than TiddlyWiki. Lots of community support for various customizations.

Much, much lighter than TiddlyWiki.

Cons

Many quirks on screens with different sizes, such as buttons being off screen to save edits, though a helping of additional CSS could clear most of these up.

Unfriendly to source code management tools, such as git because of the extremely long lines.

OmniFlux

Goal: A modern knowledge base packed into a tiny standalone HTML file.

AttributeValue
StatusNew
One FileYes
EditingMarkdown
Size21 kilobytes
ExtensibleNo
StorageHTML
Embed FilesYes, all kinds
Local SavingYes, file downloader and File API
Server-Side SavingYes, WebDAV
SearchingYes, built-in

Pros

You're looking at an OmniFlux wiki right now!

Viewable without JavaScript. Relies on CSS for navigation.

Cons

It's not designed to be extensible through plugins or additional code, but any script and style elements you add will be preserved during upgrades. Because there's no API to tie into, this is not listed as being "extensible."

With the goal of bidirectional conversion between HTML and Markdown, embedding arbitrary HTML within Markdown is not supported (custom elements are allowed).

TiddlyWiki

Goal: The everything-in-one-file platform for notes, wikis, and personal knowledge management.

AttributeValue
StatusMature
One FileYes
EditingMarkdown
Size2,490 kilobytes
ExtensibleYes, through custom JavaScript
StorageJSON
Embed FilesYes, all kinds
Local SavingYes, File downloader
Server-Side SavingYes, WebDAV or via plugins
SearchingYes, built-in

Pros

The leader of the pack. One of the earliest (if not the first) single-page wikis.

Strongly encourages plugins to handle all sorts of things. Extremely flexible and configurable. Works with a variety of server-side software to support saving remotely.

Cons

With ultimate configurability comes the largest size.

Navigation is unlike typical websites. Each "page" opens above the current content, so small pages are encouraged.

WOAS

Goal: Carry an entire wiki on a USB drive and edit it anywhere.

AttributeValue
StatusOld - Non-functional in modern browsers
One FileNo - requires a JAR to save
EditingWikiText
Size408 kilobytes
ExtensibleNo
StorageJSON
Embed FilesYes
Local SavingYes, JAR applet
Server-Side SavingNo
SearchingYes (unverified)

Pros

Worked well when it came out. Supported a style of markup like Wikipedia.

Supported AES encryption for pages.

Cons

Outdated and no longer loads because browsers don't allow loading Java applets any longer. Because there's an immediate check to see if file saving works, the entire wiki is not viewable.

WOAS Fork

Goal: Preserve and modernize the classic portable wiki experience.

AttributeValue
StatusMature
One FileYes
EditingWikiText
Size732 kilobytes
ExtensibleNo
StorageJSON
Embed FilesYes
Local SavingYes, file downloader
Server-Side SavingNo
SearchingYes

Pros

Updated version of WOAS that supports saving in newer browsers. Supports a style of markup like Wikipedia.

Supported AES encryption for pages.

Cons

Fairly large for what you get, though space is cheap.

Xie

Goal: Generate self-contained wiki documents from Markdown with almost no overhead.

AttributeValue
StatusProof of Concept
One FileYes
EditingMarkdown
Size9 kilobytes
ExtensibleYes, through custom JavaScript
StorageHTML
Embed FilesNo
Local SavingYes, file downloader
Server-Side SavingNo
SearchingNo

Pros

This shows promise as it is extremely lightweight.

Cons

Unfortunately, while editing pages and trying to add content, it appears to get confused on which page is being edited. Also, multiple copies of the same page get added to the DOM. However, these bugs aren't devastatingly bad and could be fixed with a little more time invested.

Saving with WebDAV

WebDAV (Web-based Distributed Authoring and Versioning) is a set of extensions to the standard HTTP protocol. While basic HTTP is generally read-only (used for viewing web pages), WebDAV allows users to collaboratively edit, manage, and move files on a remote web server over the internet.

OmniFlux can use a WebDAV server (or a lightweight version that simply supports PUT) to upload a copy of itself back to the server. Here is a small list of supported software:

Custom Elements

A custom element is where the HTML standard is extended by user-provided JavaScript. This can be for appearance only or you are able to also add functionality. Check out MDN's Using custom elements for further information.

OmniFlux allows embedding of custom elements as block-level Markdown. They are not allowed as inline elements.

<custom-element attr="value" more="ok">
This content is sent to the custom element.
</custom-element>

When converted to HTML, the custom element tag and all of its contents are copied exactly as how the Markdown showed it.

When upgrading, any custom <style> and <script> tags are preserved, so your custom elements will continue to work.

Embedding HTML as Markdown is not supported by OmniFlux's parser, but one can accomplish nearly the same thing using a custom element.

raw-html Example

In this scenario, the raw-html custom element will not be defined and it will still work. That's because any custom element wrapping Markdown will be preserved exactly as-is.

Here is an example of wrapping content with raw-html tags.

<raw-html><p style="font-size:3em">BIG!</p></raw-html>

And it looks like this:

BIG!

But why does this work?

  1. OmniFlux detects that there is a custom element, <raw-html>...</raw-html>.
  2. OmniFlux doesn't know what custom elements are defined.
  3. The safest path here is to copy the HTML from the Markdown to the resulting document.
  4. The browser sees the custom element and it's not defined, so <raw-html> and its matching close tag are ignored, but the contents are preserved.

It's a really great situation that requires no code editing in order to embed HTML. The only downfall is if the custom element gets defined, which could then break all pages that use it.

Tilt Example

This is an example of creating a custom element and embedding it into the wiki, then using that same custom element to show something fancy. This is what the Markdown would look like to embed a custom element.

<tilt-container>OmniFlux</tilt-container>

It will render like this.

OmniFlux

To include the tilt container custom element, you need to add JavaScript into OmniFlux. You create a new page and embed the code for the custom element. Take a look at Tilt Custom Element and edit the page. The good news is that upgrading will copy over the custom elements.

Tilt Custom Element

This page defines the <tilt-container> custom element. Edit the page to see how it's done!

Read more about <raw-html>, embedding, and using Custom Elements.

OmniFlux!

If you make changes to this custom element, you will need to save and reload the wiki to have the element refreshed.

Unsaved Changes
Autosaving
đŸ—Žī¸Ž Overview

Changelog
Code Highlighting
Custom Elements
Fair Comparison
Markdown Syntax
Rule Processing
Saving with WebDAV
Upgrading

đŸ”ī¸Ž Search
â—‹ī¸Ž Index
đŸ”—ī¸Ž Backlinks
đŸ’Ĩī¸Ž Broken Links
â‡Šī¸Ž Saving Press Ctrl+S
or ⌘ Cmd+S
â‡Šī¸Ž Saving

Save wiki locally:

Save wiki to server:

Save automatically locally:

Save automatically to server:

âœĻī¸Ž Actions

Change sidebar and page title

Remove all pages
Delete custom CSS and JS

Change current page ID
Updates all links

Copy in content

Embed a file

✔ Saved