Skip to content

Org-based wiki system for multiple workgroups with namespace support

License

Notifications You must be signed in to change notification settings

akirak/org-multi-wiki

Repository files navigation

org-multi-wiki

This is a package for working with multiple Org-based knowledge base sites inside a single Emacs session. It uses alphapapa’s helm-org-ql for searching, which makes navigation and entry creation seamless.

Build Status org-multi-wiki on MELPA helm-org-multi-wiki on MELPA

Table of contents

Features

org-multi-wiki is an Org-based wiki system for Emacs with the following features:

  • It supports working with multiple isolated directories inside a single Emacs session. It lets you define namespaces to uniquely identify content groups. You can search contents from one or more of the namespaces and create a new entry in any of them.
  • It supports org-ql for searching contents in wikis. org-ql is an expressive query language designed for Org mode. A helm support is included.
  • It adds a custom wiki link type to org-mode to resolve locations of wiki files across namespaces.
  • The directory of each namespace can be either recursive or non-recursive. If it’s set to recursive, org-multi-wiki also searches Org files in subdirectories recursively.

Prerequisites

  • Emacs 26.1 or later
  • Org 9.3 or later
  • dash.el
  • s.el
  • org-ql
  • helm-org-ql, if you use helm-org-multi-wiki (recommended)

Installation

This package is available on MELPA as org-multi-wiki and helm-org-multi-wiki.

Configuration

Below is an example configuration through use-package:

(use-package org-multi-wiki
  :config
  (org-multi-wiki-global-mode 1)
  :custom
  (org-multi-wiki-namespace-list '((personal "~/org/personal/")
                                   (ops "~/org/ops/")
                                   (programming "~/org/programming/")
                                   (client1 "~/projects/client1/client1-docs/")
                                   (client2 "~/projects/client2/client2-docs/")))
  ;; Namespace of a wiki
  (org-multi-wiki-default-namespace 'personal))

(use-package helm-org-multi-wiki)

First configure org-multi-wiki-namespace-list variable. It is a list where each item is a list of the following items:

  • A symbol to identify the wiki, called namespace
  • A directory containing Org files.

You can append a plist to the list to set options on each namespace.

You also have to turn on org-multi-wiki-global-mode for activating several function advices and the custom link type.

For more options, see org-multi-wiki customization group.

Namespace predicate for org-ql

You can also define a predicate for org-ql to test if an entry is inside a particular namespace:
(org-ql-defpred wiki (namespace)
  "It is inside a particular namespace."
  :body (org-multi-wiki-in-namespace-p (intern namespace)))

You can use the predicate in helm-org-multi-wiki to display entries in a particular namespace, e.g. wiki:namespace keyword.

Integration with org-recent-headings

org-recent-headings is a package which lets you quickly jump to a recently visited heading. To track headings visited by org-multi-wiki, you may want to add the following configuration:
(with-eval-after-load 'org-recent-headings
  (add-hook 'org-recent-headings-advise-functions
            #'org-multi-wiki-follow-link)
  (add-hook 'org-recent-headings-advise-functions
            #'helm-org-ql-show-marker)
  (add-hook 'org-recent-headings-advise-functions
            #'helm-org-ql-show-marker-indirect))

Usage

The current namespace

Most commands in this package work with a single namespace: the current namespace.

To open a file in the current namespace, use org-multi-wiki-visit-entry command. To switch the namespace, use org-multi-wiki-switch.

Optionally, you can work on a specific namespace by calling functions with a namespace. For example, org-multi-wiki-visit-entry with a universal prefix argument (C-u) lets you select a namespace.

helm-org-multi-wiki

helm-org-multi-wiki command is the main entry point in this package. It uses helm-org-ql for search and a dummy source for entry creation. It is included in helm-org-multi-wiki.el.

By default, it lets you select a heading or create a new entry in the current namespace.

With a universal prefix argument (C-u), you can select wikis. You can select multiple namespaces with C-SPC.

Running on particular namespaces

You can also use it as a function which accepts a namespace or a list of namespaces. You can define your own command to search queries in a specific wiki.
(defun helm-org-multi-wiki-project1 ()
  (interactive)
  (helm-org-multi-wiki '(project1)))

When multiple namespaces are given, you can select a directory in which you want to create a new file. This is available as alternative actions (tab) in the dummy source of Helm.

The package also provides helm-org-multi-wiki-all, which performs search on all namespaces.

Quickly creating an entry in a particular namespace

The dummy source has a dedicated keymap helm-make-helm-org-multi-wiki-dummy-source-map which lets you bind keys to create an entry in a particular namespace:
(general-def :keymap 'helm-org-multi-wiki-dummy-source-map :package 'helm-org-multi-wiki
  :prefix "C-c C-c"
  "p" (helm-org-multi-wiki-def-create-entry-action programming))

With this configuration, you can create an entry in programming wiki from the minibuffer input by pressing C-c C-c p.

helm-org-multi-wiki-def-create-entry-action macro defines an interactive function which exits the running helm session and visits an entry.

Inserting a link

helm-org-multi-wiki-insert-link lets you select a heading from all namespaces and inserts a link to the heading.

If there is an active region, it replaces the selected text with a link.

Moving contents

You can move an existing subtree to an wiki using org-multi-wiki-create-entry-from-subtree command.

Details

wiki link type

This package adds wiki link type to org-link-parameters.

The link format complies to one of the following formats:

  • Linking with a custom ID: NAMESPACE:[subdir/]TITLE[::#customid]
  • Linking with a heading: NAMESPACE:[subdir/]TITLE[::*heading]

NAMESPACE is the namespace of a wiki. It is omitted when linking to the same namespace. Note: This behaviour can be altered by setting org-multi-wiki-allow-omit-namespace to nil.

TITLE can be either the base name of an escaped file name (i.e. without .org) or its original top-level heading. :: and its following part is omitted when linking to a top-level heading in a file.

File resolution is done by attempting the following schemes, in that order:

  1. It tries to find a file with the base name of the exact TITLE.
  2. It escapes TITLE into a safe file name and tries to find a file with the base name.
  3. It tries to find a file with a top-level heading matching TITLE in the directory.

subdir is not supported now, but it will be added when this package supports recursive file search.

File name escaping

org-multi-wiki does some escaping of file names. The escaping function consists of multiple steps such as:
  • Split the title by whitespace, capitalize each word, and concatenate them. The result is usually upper camel cased.
  • If a word contains at least one upper case alphabet, the word is not capitalized and case is retained.
  • It eliminates symbols other than hyphens, dots, and underscores.
  • It eliminates words such as “a”, “an”, and “the”.
  • It keeps non-ascii characters such as Chinese and Japanese.

It is designed to be both filename-safe and friendly to the modern world with technical terms. However, you can alter the logic by setting org-multi-wiki-escape-file-name-fn to another function.

Linking to a particular heading in a file

You can link to a heading in a file either with a heading text or with a custom ID property.

Linking with a custom ID is generally safer, because custom IDs don’t change when you change headings. To enforce generation of a custom ID when storing a link, set org-multi-wiki-want-custom-id variable to t.

Note that a link to a top-level heading does not contain a link fragment, i.e. a heading or a custom ID by default. See the following subsection for changing this behaviour.

Entry levels and entry templates

It is recommended that you include at least one heading in each Org file in wiki. The following structure is not recommended:

#+title: My wiki page
\* First heading

Instead, the following structure is recommended:

\* My wiki page
\** First heading

I write READMEs of my open source projects in this style, and if you use helm-org-ql, you won’t be able to reach a file without a heading.

Following this principle, the default file template of this package generates a heading rather than a file header. To change the template, set org-multi-wiki-entry-template-fn variable..

Also, links to top-level heading don’t contain a link fragment by default. This is because top-level headings are considered page titles in the structure and each file should contain only one top-level heading. However, depending on your needs, you may want to include multiple top-level headings in a single file. You can include a fragment in a link to a top-level heading using one of the following options:

  • Set org-multi-wiki-top-level-link-fragments to t, which is globally effective
  • Set :top-level-link-fragments option in org-multi-wiki-namespace-list, which is locally effective

Buffer names

To let the user easily distinguish between wikis, org-multi-wiki renames file buffers according to their respective namespaces when it opens Org files:

screenshots/helm-org-multi-wiki-multi-ns-1.png

To turn off this behavior, set org-multi-wiki-rename-buffer to nil.

Customizing the helm source

Although helm-org-multi-wiki is based on helm-org-ql, it allows further customizations to make it slightly different from the original package:
  • It can display items when no query is given in the minibuffer. By default, it displays top-level items. You can customize this via helm-org-multi-wiki-default-query variable. This should be an S-expression query accepted by org-ql.
  • It allows you to customize the query parser by setting helm-org-multi-wiki-query-parser to a different value. By default, it uses the plain query parser of org-ql.
  • You can change the keymap and the action by setting helm-org-multi-wiki-map and helm-org-ql-actions, respectively, By default, it uses the same values as helm-org-ql.

Alternatives

There are several knowledge base systems for Emacs based on Org mode.

org-brain and org-roam are especially powerful ones. org-brain is based on the idea of concept mapping, and org-roam is a rudimentary replica of another software named Roam. org-multi-wiki is not based on such a specific framework. It focuses on search and entry creation and has built-in support for multiple namespaces. It provides an infrastructure for building your own wiki system on top of Org mode.

plain-org-wiki is the direct inspiration of this package. org-multi-wiki supports multiple namespaces and takes advantage of helm and org-ql for providing a rich querying interface.

License

GPLv3

About

Org-based wiki system for multiple workgroups with namespace support

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published