Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/akirak/org-multi-wiki

Org-based wiki system for multiple workgroups with namespace support
https://github.com/akirak/org-multi-wiki

emacs knowledge-base-system note-taking org-mode wiki

Last synced: 7 days ago
JSON representation

Org-based wiki system for multiple workgroups with namespace support

Awesome Lists containing this project

README

        

# -*- mode: org; mode: org-make-toc -*-
* 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 [[https://github.com/alphapapa/org-ql][helm-org-ql]] for searching, which makes navigation and entry creation seamless.

#+BEGIN_HTML

Build Status

org-multi-wiki on MELPA

helm-org-multi-wiki on MELPA
#+END_HTML
** Table of contents
:PROPERTIES:
:TOC: siblings
:END:
- [[#features][Features]]
- [[#prerequisites][Prerequisites]]
- [[#installation][Installation]]
- [[#configuration][Configuration]]
- [[#namespace-predicate-for-org-ql][Namespace predicate for org-ql]]
- [[#integration-with-org-recent-headings][Integration with org-recent-headings]]
- [[#usage][Usage]]
- [[#the-current-namespace][The current namespace]]
- [[#helm-org-multi-wiki][helm-org-multi-wiki]]
- [[#running-on-particular-namespaces][Running on particular namespaces]]
- [[#quickly-creating-an-entry-in-a-particular-namespace][Quickly creating an entry in a particular namespace]]
- [[#inserting-a-link][Inserting a link]]
- [[#moving-contents][Moving contents]]
- [[#details][Details]]
- [[#wiki-link-type][wiki link type]]
- [[#file-name-escaping][File name escaping]]
- [[#linking-to-a-particular-heading-in-a-file][Linking to a particular heading in a file]]
- [[#entry-levels-and-entry-templates][Entry levels and entry templates]]
- [[#buffer-names][Buffer names]]
- [[#customizing-the-helm-source][Customizing the helm source]]
- [[#alternatives][Alternatives]]
- [[#license][License]]

** 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=
- [[https://github.com/alphapapa/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=:

#+begin_src emacs-lisp
(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)
#+end_src

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
:PROPERTIES:
:CREATED_TIME: [2020-12-12 Sat 23:36]
:END:
You can also define a predicate for =org-ql= to test if an entry is inside a particular namespace:

#+begin_src emacs-lisp
(org-ql-defpred wiki (namespace)
"It is inside a particular namespace."
:body (org-multi-wiki-in-namespace-p (intern namespace)))
#+end_src

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
:PROPERTIES:
:CREATED_TIME: [2020-12-12 Sat 23:37]
:END:
[[https://github.com/alphapapa/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:

#+begin_src emacs-lisp
(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))
#+end_src
** 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 [[https://github.com/alphapapa/org-ql#helm-org-ql][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
:PROPERTIES:
:CREATED_TIME: [2020-02-22 Sat 14:34]
:END:
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.

#+begin_src emacs-lisp
(defun helm-org-multi-wiki-project1 ()
(interactive)
(helm-org-multi-wiki '(project1)))
#+end_src

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
:PROPERTIES:
:CREATED_TIME: [2020-02-22 Sat 14:35]
:END:
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:

#+begin_src emacs-lisp
(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))
#+end_src

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
:PROPERTIES:
:CREATED_TIME: [2021-02-09 Tue 00:06]
:END:
=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
:PROPERTIES:
:CREATED_TIME: [2020-02-09 Sun 16:01]
:END:
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
:PROPERTIES:
:CREATED_TIME: [2020-03-14 Sat 20:04]
:END:
=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:

#+begin_example
#+title: My wiki page
\* First heading
#+end_example

Instead, the following structure is recommended:

#+begin_example
\* My wiki page
\** First heading
#+end_example

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
:PROPERTIES:
:CREATED_TIME: [2020-03-24 Tue 00:53]
:END:
To let the user easily distinguish between wikis, =org-multi-wiki= renames file buffers according to their respective namespaces when it opens Org files:

[[file: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
:PROPERTIES:
:CREATED_TIME: [2020-03-24 Tue 00:53]
:END:
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.

[[https://github.com/Kungsgeten/org-brain][org-brain]] and [[https://github.com/jethrokuan/org-roam][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.

[[https://github.com/abo-abo/plain-org-wiki][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