<!---
SPDX-FileCopyrightText: © 2023 Christian BUHTZ <c.buhtz@posteo.jp>

SPDX-License-Identifier: GPL-3.0-only

This file is part of the program "Hyperorg" which is released under
GNU General Public License v3 (GPLv3). See LICENSES directory
or go to <https://spdx.org/licenses/GPL-3.0-only.html>.
-->
[![REUSE status](https://api.reuse.software/badge/codeberg.org/buhtz/hyperorg)](https://api.reuse.software/info/codeberg.org/buhtz/hyperorg)
[![Mastodon @buhtz@fosstodon.org](badge_mastodon.svg)](https://fosstodon.org/@buhtz)
[![Common Changelog](https://common-changelog.org/badge.svg)](https://common-changelog.org)
[![Liberapay buhtz](badge_liberapay.svg)](https://liberapay.com/buhtz)
[![Ko-fi buhtz](badge_kofi.svg)](https://ko-fi.com/buhtz)

# Hyperorg - An Org to HTML converter

_Hyperorg_ converts [Org Mode](https://orgmode.org/) and
[Org-roam](https://www.orgroam.com/) files into a navigable
[HTML](https://en.wikipedia.org/wiki/HTML/) representation of a
[Zettelkasten](https://en.wikipedia.org/wiki/Zettelkasten/), preserving its
link structure and backlinks. It is designed to make an Org-roam vault
accessible without requiring [Emacs](https://www.gnu.org/software/emacs/) or a
web server.

The **project** is active. It is in constant development implementing [new
features](https://codeberg.org/buhtz/hyperorg/issues?q=&state=open&labels=40047)
and fixing
[bugs](https://codeberg.org/buhtz/hyperorg/issues?q=&state=open&labels=40046).
See the [development roadmap](#development-roadmap) and the
[milestones](https://codeberg.org/buhtz/hyperorg/milestones) about what is
coming and the
[changelog](https://codeberg.org/buhtz/hyperorg/src/branch/latest/CHANGELOG.md)
about what has been.  Don't hesitate to voice your wishes and opinions by
utilizing the [issue section](https://codeberg.org/buhtz/hyperorg/issues) or
the Mastodon account [@buhtz@fosstodon.org](https://fosstodon.org/@buhtz).

The **Team** currently consists of a single person: the original author and
sole maintainer, [buhtz](https://buhtz.codeberg.pages).
[Donations](https://codeberg.org/buhtz/about-me#about-christian-buhtz)
via
<a href="https://liberapay.com/buhtz">
    <img src="https://codeberg.org/buhtz/about-me/raw/branch/main/liberapay.svg"
    width="24px" height="24px" />
    Liberapay</a> and
<a href="https://ko-fi.com/buhtz">
    <img src="https://codeberg.org/buhtz/about-me/raw/branch/main/kofi.png"
    width="24px" height="24px" />
    Ko-fi</a> support the maintainer personally rather than this specific
project, as he is involved in
[several open-source
projects](https://codeberg.org/buhtz/about-me#projects). Alternative donation
methods are available on request.

<sub>July 2026</sub>

## Table of contents
- [Installation](#installation)
- [Usage](#usage)
- [Feature List](#feature-list)
- [Design Goals](#design-goals)
- [Comparison to similar tools](#comparison-to-similar-tools)
- [Motivation - Why _Hyperorg_ exists](#motivation-why-_hyperorg_-exists)
- [Development roadmap](#development-roadmap)
- [Contributing](#contributing)
- [Example](#example)
- [Technologies & Standards](#technologies-standards)

# Installation
> [!IMPORTANT]
> Always prefer the **official repository** of your GNU/Linux distribution.
> _Hyperorg_ is [available on Debian
> GNU/Linux](https://tracker.debian.org/pkg/hyperorg) and therefore other
> Debian-based distros.  See [this list](https://repology.org/project/hyperorg)
> about availability in other distros.

**Regular installation for users**:

See the [Releases](https://codeberg.org/buhtz/hyperorg/releases) section or
run the following command to install the _latest stable release_ from upstream
repository:

```
$ pipx install https://codeberg.org/buhtz/hyperorg/archive/v0.2.0.zip
```

If `pipx` is not available on your system check your GNU/Linux distributions
package repository or install it from PyPi (`pip install pipx`).

**Editable installation for developers to contribute**:

First of all fork/clone/copy the repository to your local machine.
```sh
$ git clone https://codeberg.org/buhtz/hyperorg.git
$ cd hyperorg
```

Use a virtual environment and the extra `[develop]`.

```sh
# Create the environment
$ python3 -m venv .venv

# Activate the environment
$ source .venv/bin/activate

# Install
$ pip3 install --editable .[develop]
```

When you are finished with your working session, don't forget to deactivate the
environment.

```sh
$ deactivate
```

# Usage

```
$ hyperorg ~/orgfolder ~/htmlfolder
```

This will take all `*.org` files in the folder `~/orgfolder` and store them
converted to HTML in `~/htmlfolder`. Open the `index.html` file in the
output folder to see the result.

These are all available options:
```
usage: hyperorg [-h] [--hardlinks] [-s] [-v] [-d] [--version] inputdir outputdir

positional arguments:
  inputdir       Source directory with org-files.
  outputdir      Destination directory for html-files.

optional arguments:
  -h, --help     show this help message and exit
  --hardlinks    Use hardlinks instead of symlinks for images and other
                 attachments in the input directory.
  -s, --show     Open result in default browser.
  -v, --verbose  Give detailed information.
  -d, --debug    Debug output.
  --version      show program's version number and exit
```

# Feature List

- Convert all nodes in an Org-roam vault (collection of org files) into HTML.
- Preserves links between nodes.
- Generates backlinks for each node.
- Generates a comprehensive index of all nodes.
- Not stopping on malformed nodes, or broken links, but emitting clear
  warnings.

# Design Goals

- Functions out of the box, no configuration needed.
- Operates as a standalone application, eliminating the requirement for Emacs.
- Serverless local use of HTML files.
- Robust handling of parsing issues.
- Adheres to World Wide Web Consortium (W3C) standards for HTML5 and CSS
  (`<!DOCTYPE html>`).
- No JavaScript or other dynamic web techniques, except when really necessary
  (e.g. MathJax).

# Comparison to similar tools

_Hyperorg_ takes an existing Org-roam **link graph**, exports it
**out-of-the-box** as a navigable HTML structure and does not require
configuration.

The Org-roam vault is treated as a graph of nodes, not just a collection of
independent files. ID-based links are first-class, meaning that `id:` links are
resolved as real graph edges between nodes, not treated as plain text
links. Backlinks are generated as part of the regular output. Every page
includes incoming references automatically.  All of this works without
configuration.

Similar tools like `org-export`, `org-publish` or _Hugo_, do model files and
publishing rules, while _Hyperorg_ models the org-roam graph itself as the
direct basis for HTML generation.

# Motivation - Why _Hyperorg_ exists

The creation of _Hyperorg_ was initially driven by two aspects. First, there
was the need to make an Org-roam vault accessible on systems without an Emacs
available. Second, there was the experience that there is no known solution
available to reliably handle the `id:` links in Org-roam nodes and to meet the
requirements of a Zettelkasten scenario.

In addition, the project was influcenced by practical constraints regarding the
authors personal skill set and a lack of motivation and intent to learn or
adapt to extensive configuration systems in other tools. Alternative tools
doesn't meet all mentioned design goals and features, not because they are not
good but they simply target on different use cases and design goals.

# Development roadmap

- **Short term**
  - Primary focus is on improving maintainability and testability of the grown
    codebase via rearanging and refactoring it. See meta issue
    [#195](https://codeberg.org/buhtz/hyperorg/issues/195).
- **Medium term**
  - [Next release after `0.2.0`](https://codeberg.org/buhtz/hyperorg/milestone/5750).
    ([#85](https://codeberg.org/buhtz/hyperorg/issues/i85)).
  - Implement feature: Table of content
  - Several more features.
  - Improve visual appearance and sexyness via color scheming and more. See
    [CSS-related issues](https://codeberg.org/buhtz/hyperorg/issues?labels=180551) and
    [#66](https://codeberg.org/buhtz/hyperorg/issues/66).
- **Long term**
  - Integrate the necessary features of `orgparse` and remove that dependency.
  - Separate the parser component into its own project to make it accessible to
    others.

# Contributing
Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details about how to
contribute to the project. Details about the concecpt, code structure and
design decisions can be found in
[`examples/org/20250912150340-hyperorg_design_concept.org`](https://codeberg.org/buhtz/hyperorg/raw/example/org/20250912150340-hyperorg_design_concept.org).

The following communities have supported this project with contributions to
discussions, tips, other valuable contributions and also inspirations.

- The communities around [Emacs](https://www.gnu.org/software/emacs/),
  [Org-roam](https://www.orgroam.com/),
  [Org-mode](https://orgmode.org/) and
  [ox-hugo](https://ox-hugo.scripter.co/).
- [Regex101](https://regex101.com)
- [StackOverflow](https://stackoverflow.com)
- [debianforum.de](https://debianforum.de)
- And others.

# Example

On the left side of this screenshot, an _Emac's_ window displaying an _Org_
buffer can be seen, while on the right side, the same content is prestend in
_HTML_ format.  ![Example Screenshot](misc/screenshot01.png)

Here you can observe the identical content presented in both raw _Org_ and
_HTML_ formats.

<table>
<tr>
<th style="vertical-align:top;width:50%">Org</th>
<th style="vertical-align:top;width:50%">HTML</th>
</tr>
<tr>
<td>

```Markdown
:PROPERTIES:
:ID:       13ec1e89-abc9-4d43-a4a4-3005a1c9dfc7
:END:
#+title: Foo
#+date: [2022-03-09 Mi 09:30]
* Introduction
This node is named "foo" and should link to "bar".
This is the link: [[id:e4bd446b-216b-4e34-8d10-428b6fa5e257][bar]]

* H1 Heading
** H2 Heading
Governments of the Industrial World, you weary giants of flesh and steel, I
come from Cyberspace, the new home of Mind. On behalf of the future, I ask
you of the past to leave us alone.

- You are not welcome among us.
- You have no sovereignty where we gather.

We have no elected government, nor are we likely to have one, so I address
you with no greater authority than that with which liberty itself always
speaks.

1. I declare the global social space we are building to be naturally
   independent
2. of the tyrannies you seek to impose on us.

Source: [[https://www.eff.org/de/cyberspace-independence]]

** A https link

[[https://codeberg.org/buhtz/hyperorg][The "hyperorg" repository]]

* About backlinks
See the autogenerated backlinks in the next section. The node "bar" does link
to this node "foo".
```

</td>
<td>

```html
<!DOCTYPE html>
<html lang="de">
<head>
    <meta name="generator" content="hyperorg" />
    <meta name="generator_version" content="0.1.0" />
    <meta name="generator_website" content="https://codeberg.org/buhtz/hyperorg" />
    <meta charset="UTF-8" />
    <link rel="stylesheet" href="style.css" />
    <link rel="stylesheet" href="pygments.css" />
    <title>Foo</title>
</head>
<body>
    <nav>
            <ul>
                <li><a href="index.html">Index</a> (1013)</li>
                <li><a href="index__filetag__no_tags_.html">(no tags)</a> (514)</li>
                <li><a href="index__filetag_Bib.html">Bib</a> (277)</li>
                <li><a href="index__filetag_Wiki.html">Wiki</a> (166)</li>
                <li><a href="index__filetag_Meta.html">Meta</a> (43)</li>
                <li><a href="index__filetag_Project.html">Project</a> (19)</li>
            </ul></nav>
    <main>
        <h1>Foo</h1>
        <section>
            <header><div><span class="label">date:</span>&nbsp;[2022-03-09 Mi 09:30]</div>            </header>
<h2>Introduction</h2>
<p>This node is named &quot;foo&quot; and should link to &quot;bar&quot;. This is the link: <a href="20240319084651-bar.html">bar</a></p>
<h2>H1 Heading</h2>
<h3>H2 Heading</h3>
<p>Governments of the Industrial World, you weary giants of flesh and steel, I come from Cyberspace, the new home of Mind. On behalf of the future, I ask you of the past to leave us alone.</p>
<ul>
<li>You are not welcome among us.</li>
<li>You have no sovereignty where we gather.</li>
</ul>
<p>We have no elected government, nor are we likely to have one, so I address you with no greater authority than that with which liberty itself always speaks.</p>
<ol>
<li>I declare the global social space we are building to be naturally independent</li>
<li>of the tyrannies you seek to impose on us.</li>
</ol>
<p>Source: <a target="_blank" rel="noopener noreferrer" href="https://www.eff.org/de/cyberspace-independence">https://www.eff.org/de/cyberspace-independence</a></p>
<h3>A https link</h3>
<p><a target="_blank" rel="noopener noreferrer" href="https://codeberg.org/buhtz/hyperorg">The &quot;hyperorg&quot; repository</a></p>
<h2>About backlinks</h2>
<p>See the autogenerated backlinks in the next section. The node &quot;bar&quot; does link to this node &quot;foo&quot;.</p>
        </section>
        <section>
            <hr />
            <h2>Backlinks</h2>
<ul>
<li><a href="20240319084651-bar.html">bar</a></li>
</ul>
        </section>
    </main>
    <footer>
        Generated with <a href="https://codeberg.org/buhtz/hyperorg">hyperorg</a> 0.1.0 on Di 19 Mär 2024 09:03:51
    </footer>
</body>
</html>
```

</td>
</tr>
</table>

# Technologies & Standards

 - [Python 3](https://python.org)
 - [`orgparse`](https://orgparse.readthedocs.io/en/latest/)
 - [W3C](https://www.w3.org/) conform
   [HTML5](https://wikipedia.org/wiki/HTML5)
   & [CSS](https://wikipedia.org/wiki/CSS)
 - [Semantic Versioning](https://semver.org),
   [Common Changelog](https://common-changelog.org) and
   [Conventional Commits](https://www.conventionalcommits.org)
 - [REUSE Software](https://reuse.software) and
   [SPDX](https://spdx.github.io/spdx-spec) ([ISO/IEC 5962:2021](https://www.iso.org/obp/ui/en/#iso:std:iso-iec:5962)) specifications
