Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions .github/workflows/documentation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: Documentation

on:
push:
branches: [master]
pull_request:
branches: [master]
workflow_dispatch:

permissions:
contents: read

concurrency:
group: documentation-${{ github.ref }}
cancel-in-progress: true

jobs:
build:
name: Build user guide and API reference
runs-on: ubuntu-24.04
steps:
- name: Check out sources
uses: actions/checkout@v7

- name: Build existing Jekyll user guide
uses: actions/jekyll-build-pages@v1
with:
source: ./
destination: ./_site
baseurl: /${{ github.event.repository.name }}

- name: Install documentation tools
run: |
sudo apt-get update
sudo apt-get install --yes doxygen graphviz

- name: Build API reference
run: |
bash doc/build-api.sh "$RUNNER_TEMP/intarna-api"
# The Jekyll container creates its output as root.
sudo chown -R "$(id -u):$(id -g)" _site
cp -R "$RUNNER_TEMP/intarna-api/html" _site/api

- name: Check generated documentation
run: |
python3 doc/check-api.py _site/api
test -s _site/index.html
test -s _site/doc/figures/icon-up.28.png

- name: Upload documentation for review and deployment
uses: actions/upload-pages-artifact@v4
with:
path: _site
retention-days: 7

deploy:
name: Publish documentation
if: github.repository == 'BackofenLab/IntaRNA' && github.ref == 'refs/heads/master' && github.event_name != 'pull_request'
needs: build
runs-on: ubuntu-24.04
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
19 changes: 19 additions & 0 deletions ChangeLog
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@

## Technical changes and Optimizations

- add an API overview, IntaRNA Doxygen styling, and automated documentation
builds and GitHub Pages publishing alongside the user guide (issue #22)

- install personality links in out-of-tree builds, including IntaRNAsnap

- BUGFIX : normalize single-pair suboptimal boundaries before traceback and
Expand Down Expand Up @@ -126,6 +129,22 @@ energies, restricted partition sums, and trackers.
################################################################################
################################################################################

261007 Alexander Mitrofanov
* doc/doxygen.cfg, doc/doxygen/* :
+ introduce the API main page with component links, prediction flow,
coordinate/energy conventions, and library integration guidance
+ add IntaRNA header/footer navigation and responsive project styling
* doc/build-api.sh, doc/check-api.py, doc/api-documentation.md, README.md :
+ build HTML without C++ dependencies and check entry-page links/assets
+ document local generation and the one-time Pages activation after merge
* .github/workflows/documentation.yml :
+ build the existing Jekyll guide and API on PRs and master commits;
publish both together from master only, with API content under /api/
* Makefile.am, doc/Makefile.am :
* rebuild documentation when headers or documentation assets change and
include all documentation sources and build helpers in distributions
* addresses https://github.com/BackofenLab/IntaRNA/issues/22

261005 Alexander Mitrofanov
* bin/CommandLineParsing, tests/runKineticSeedExtension.sh :
+ add IntaRNAsnap personality with model=X, mode=K and outNoLP=true defaults;
Expand Down
5 changes: 5 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ install-exec-hook:
if enable_doxygen
## doxygen documentation make target
@DX_RULES@

# Refresh the API after changes to public headers, the overview, or branding.
$(DX_DOCDIR)/$(PACKAGE).tag: $(wildcard $(srcdir)/src/IntaRNA/*.h) \
$(srcdir)/doc/doxygen/mainpage.md $(srcdir)/doc/doxygen/header.html \
$(srcdir)/doc/doxygen/footer.html $(srcdir)/doc/doxygen/intarna.css
else
## generate mandatory targets otherwise generated by doxygen.m4
DX_PHONY =
Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2378,6 +2378,14 @@ and functionalities used within the IntaRNA tool. The whole library comes with
an `IntaRNA` namespace and exhaustive class and member API documentation that is
processed using doxygen to generate html/pdf versions.

Browse the [C++ API reference](https://backofenlab.github.io/IntaRNA/api/)
for an overview of the library components and links to the class documentation.
The online reference follows `master`. To generate it for your checkout, install
Doxygen and Graphviz and run `bash doc/build-api.sh`, then open
`doxygen-doc/html/index.html`. See the
[API documentation build guide](doc/api-documentation.md) for validation,
Autotools, and publishing instructions.

When IntaRNA is build while `pkg-config` is present, according pkg-config
information is generated and installed too.

Expand Down
7 changes: 7 additions & 0 deletions doc/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,14 @@

EXTRA_DIST = \
conda.txt \
api-documentation.md \
build-api.sh \
check-api.py \
doxygen.cfg \
doxygen/mainpage.md \
doxygen/header.html \
doxygen/footer.html \
doxygen/intarna.css \
latex-deps/adjcalc.sty \
latex-deps/adjustbox.sty \
latex-deps/collectbox.sty \
Expand Down
65 changes: 65 additions & 0 deletions doc/api-documentation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Building and publishing the API reference

The API reference is generated from `src/IntaRNA/*.h` and
`doc/doxygen/mainpage.md`. Its HTML header, footer, and extra stylesheet live in
`doc/doxygen/`; the common configuration is `doc/doxygen.cfg`.

## Local HTML build

Install Doxygen and Graphviz (on Ubuntu: `sudo apt-get install doxygen graphviz`).
The HTML templates are based on Doxygen 1.9.8, the version provided by the
Ubuntu 24.04 CI runner. When updating Doxygen, compare them with freshly generated
templates (`doxygen -w html header.html footer.html default.css`) and verify
navigation and search before publishing.

From the repository root:

```bash
bash doc/build-api.sh
python3 doc/check-api.py doxygen-doc/html
```

Open `doxygen-doc/html/index.html`, or serve the directory with
`python3 -m http.server --directory doxygen-doc/html` and browse
`http://localhost:8000/`. An optional output directory can be passed to the build
script; relative paths are resolved from the calling directory. The script only
builds HTML and does not require a compiler, Boost, ViennaRNA, or an IntaRNA build.
It uses the package version from `configure.ac`.

In a configured Autotools checkout, the existing `make doxygen-doc` target uses
the same content and styling. Configure with `--disable-doxygen-pdf` for an
HTML-only build; PDF generation additionally requires the configured LaTeX tools.

The link check verifies the entry page's local links (including class/member
anchors), its styles and scripts, and the class/namespace/search entry points.
Review Doxygen's warnings as well: existing header documentation can emit
warnings, so the workflow does not treat every legacy documentation warning as
fatal. New unresolved references should be fixed before merging.

## GitHub Pages

`.github/workflows/documentation.yml` builds documentation on pull requests to
`master`, on pushes to `master`, and on manual dispatch. Every successful build
uploads a `github-pages` artifact for review. Only a push or manual dispatch on
`BackofenLab/IntaRNA`'s `master` can deploy; pull requests and forks cannot publish.
The deployment job alone receives Pages and OIDC write permissions.

The workflow first builds the existing README-based Jekyll site with its Slate
theme, then adds Doxygen output under `api/`. It publishes both together:

- User guide: <https://backofenlab.github.io/IntaRNA/>
- Development API: <https://backofenlab.github.io/IntaRNA/api/>

### One-time activation after merge

The repository currently publishes from the root of the `master` branch. After
merging the documentation workflow, a repository administrator must select
**Settings → Pages → Build and deployment → Source → GitHub Actions**, then run
the **Documentation** workflow on `master` (or push a subsequent commit).
Retain any required approval rules on the `github-pages` environment. The PR
does not change the live publishing settings. See GitHub's
[custom Pages workflow documentation](https://docs.github.com/en/pages/getting-started-with-github-pages/using-custom-workflows-with-github-pages).

No generated HTML, access token, or separate documentation branch is needed.
Both the existing guide and the API are included in the deployment artifact;
deploying only the API would replace the guide at the site's root.
35 changes: 35 additions & 0 deletions doc/build-api.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/usr/bin/env bash
# Build the HTML API without configuring or compiling the C++ library.
set -euo pipefail

if (( $# > 1 )); then
echo "Usage: $0 [output-directory]" >&2
exit 2
fi

source_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)"
output_dir="${1:-$source_dir/doxygen-doc}"
mkdir -p -- "$output_dir"
output_dir="$(cd -- "$output_dir" && pwd)"
cd -- "$source_dir"

version="$(sed -n 's/^AC_INIT(\[IntaRNA\], \[\([^]]*\)\].*/\1/p' configure.ac)"
test -n "$version"
for tool in doxygen dot; do
if ! command -v "$tool" >/dev/null; then
echo "Missing documentation tool: $tool (install Doxygen and Graphviz)" >&2
exit 1
fi
done
dot_path="$(dirname -- "$(command -v dot)")"

# These are the same substitutions provided by m4/doxygen.m4 for make doxygen-doc.
env SRCDIR=. PROJECT=IntaRNA VERSION="$version" DOCDIR="$output_dir" \
GENERATE_HTML=YES GENERATE_LATEX=NO GENERATE_PDF=NO \
GENERATE_HTMLHELP=NO GENERATE_CHI=NO GENERATE_RTF=NO \
GENERATE_MAN=NO GENERATE_XML=NO PAPER_SIZE=a4 \
HAVE_DOT=YES DOT_PATH="$dot_path" \
doxygen doc/doxygen.cfg

test -s "$output_dir/html/index.html"
echo "API documentation: $output_dir/html/index.html"
59 changes: 59 additions & 0 deletions doc/check-api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/usr/bin/env python3
"""Check the generated API entry page, its links, and navigation assets."""

import sys
from html.parser import HTMLParser
from pathlib import Path
from urllib.parse import unquote, urlsplit


class Page(HTMLParser):
def __init__(self, path):
super().__init__()
self.links = []
self.anchors = set()
self.feed(path.read_text(encoding="utf-8"))

def handle_starttag(self, tag, attrs):
attrs = dict(attrs)
for key in ("href", "src"):
if attrs.get(key):
self.links.append(attrs[key])
for key in ("id", "name"):
if attrs.get(key):
self.anchors.add(attrs[key])


def check(directory):
for name in ("index.html", "annotated.html", "hierarchy.html",
"namespaceIntaRNA.html", "search/searchdata.js", "intarna.css"):
path = directory / name
if not path.is_file() or path.stat().st_size == 0:
raise ValueError(f"Missing or empty API output: {path}")

index = directory / "index.html"
page = Page(index)
pages = {index: page}
for link in page.links:
url = urlsplit(link)
if url.scheme or url.netloc:
continue
target = directory / unquote(url.path) if url.path else index
if not target.is_file():
raise ValueError(f"Broken API entry-page link: {link}")
if url.fragment and target.suffix == ".html":
if target not in pages:
pages[target] = Page(target)
if unquote(url.fragment) not in pages[target].anchors:
raise ValueError(f"Broken API entry-page anchor: {link}")

print(f"API entry page: {len(page.links)} links and assets checked")


if __name__ == "__main__":
if len(sys.argv) != 2:
sys.exit("Usage: python3 doc/check-api.py <generated-html-directory>")
try:
check(Path(sys.argv[1]))
except (OSError, ValueError) as error:
sys.exit(str(error))
Loading
Loading