KeepNote Documentation


For troubleshooting see the Frequently Asked Questions (FAQ).

Developer notes

This section contains notes that will most likely only be of interest to other developers working on KeepNote or making software compatiable with KeepNote.


For information on producing new translations of KeepNote, please see: README.translations.txt. You will need to be familiar with the unix/linux/mac command-line. Please email me for more information.

Extension development

KeepNote uses extensions (i.e. plugins) to provide extra optional features. This allows the core application to remain simple and light-weight while allowing each user to enable different extra features depending on their needs. Also, features implemented in extensions can be developed at their own pace and maintained by many different developers. Extensions are written in the the python language, and can provide almost any feature that the core application can (which is also written in python). Here, we describe the details of developing an extension.

Extension file format

Extensions are distributed as a package with the file extension *.kne (see the extensions page for an example). By convention, the name of the package should be short and if it contains multiple words should delimit words with underscores (e.g. backup_tar.kne).

The package file is simply a zip file of a single directory with the following structure:

extension_directory should be the same name as the package. Thus, backup_tar.kne would contain a single directory backup_tar.

info.xml provides a manifest of the contents of the extension. It has the following format:

<?xml version="1.0" encoding="UTF-8"?>
    <string>Notebook Backup (tar)</string>
    <string>Matt Rasmussen</string>
    <string>Backups a notebook to a gzip tar file (*.tar.gz)</string>

The extension tag is required and the nested dict tag is also required. The contents of the dict tag follows the plist XML format. The dict should have the following keys and values:

__init__.py provides the source code of the extension written in the python programing language. See Programming an extension for more details on writing a __init__.py file.

Optional data files may be included in the extension directory. These can be GUI definitions (*.glade), images, or other static information (read-only).

See the source files keepnote/extensions/backup_tar/__init__.py and keepnote/extensions/export_html/__init__.py for more examples of how to implement extensions.

Programing an extension (__init__.py)

The main source code of an extension is provided in the __init__.py file contained within the extension's main directory (extension file format). At a minimum, the python file should contain a single class named Extension that subclasses from the class keepnote.extension.Extension. If the extension has any graphical features (most do) then the class should subclass keepnote.gui.extension.Extension. The base class provides a number of methods that can be overwritten in order to implement different features of the extension.

Life time of an extension. Once an extension is installed it is by default enabled, however users can optionally disable an extension if they want to temporarily remove its features. The list of enabled and disabled extensions are recorded in the preferences of the user. When the application first starts, all enabled extensions are loaded automatically. Extensions are then notified of particular events throughout the lifetime of the application through a series of callback methods available within the Extension class.

Notebook file format

The data structure of the notebook is a directed graph of nodes. Each node contains an optional payload (typically a chunk of HTML) and a set of attributes. The most common graph (and the only one implemented as of 0.5.2) is a tree or hierachy.

KeepNote currently implements a file and directory format for writing notebooks to disk. The node hierarchy is implemented as a nested set of directories, one directory per node. Directory names are ignored. For user convenience, KeepNote happens to name directories similar to the node's title attribute. Care must be taken to strip invalid characters (such as "/") from node title's before using them as directory names.

Attribute encoding

Each node directory must contain a meta data file called node.xml. This file describes the attributes of the node. Here is an example:

<?xml version="1.0" encoding="UTF-8"?>
<attr key="title">Title of my note</attr>
<attr key="expanded">0</attr>
<attr key="nodeid">fb4f99f5-e3d6-46d3-bf57-61ce46707cde</attr>
<attr key="modified_time">1235451081</attr>
<attr key="expanded2">0</attr>
<attr key="content_type">text/xhtml+xml</attr>
<attr key="created_time">1226172668</attr>
<attr key="info_sort_dir">1</attr>
<attr key="order">1</attr>
<attr key="info_sort">order</attr>

The root tag is node which contains a version tag and a list of attr tags which describe the node's attributes. The order of attr tags is insignificant. Attributes are key-value pairs. The key of an attribute is given in the html attribute key and the value is the data within the attr tags. Each attribute type has its own format for its data. Some attributes are more important than others. For example, the nodeid and content_type attributes are required but other attributes are optional and may be program specific.

In the future, I plan to allow attributes to be multi-valued, namely, they can occur multiple times in the node.xml file. The order in which attributes of the same type appear will be significant. An attribute type must be declared multi-valued in order to use this feature. This will allow implementing attributes that represent things such as "tags" or "labels".

Attribute definitions

Payload encoding

Each node may optionally have a payload, i.e. additional data that is application specific. The "page" node in KeepNote (i.e. content_type="text/xhtml+xml") is the most common node with a payload, which is a XHTML document and its associated images. KeepNote requires this document to be named page.html. Images associated with the document can have any name (except node.xml and page.html) and are referred to within the XHTML document using relative filenames. Only a subset of XHTML is supported by KeepNote.

Notebook-wide metadata

Lastly, a notebook has metadata that pertains to the entire notebook. This is stored in files and directories present at the base directory of the notebook. There is a XML file called notebook.nbk which contains simple preference information for the notebook (e.g. default font, custom icon names). There is also a directory called __NOTEBOOK__ that will contain support files for the notebook (e.g. custom icons, cached data in a database format, etc). Note, the filename "__NOTEBOOK__" is reserved and cannot be used by any nodes in the notebook.