libmorpheus modernizes the Morpheus
morphological analyzer for Ancient Greek and Latin. It turns the historical C
programs into an installable C17 shared library with a stable, opaque ABI and a
typed Deno 2 binding.
- Project status
- Bindings
- Build the native library
- Install and consume from C
- Runtime data
- Alpine container images
cruncher- Releases and platform support
- Architecture and provenance
- License
| Operation | Ancient Greek | Latin | Status |
|---|---|---|---|
| Analyze an inflected form | Yes | Yes | Supported |
| Generate forms from a lemma | Yes | No | Experimental |
The public runtime includes:
- structured, caller-owned analysis and generation results;
- per-request analysis options and generation filters;
- isolated contexts that can be used concurrently;
- a Deno 2 FFI binding published on JSR as
@libmorpheus/deno; cruncher, retained as a compatibility client of the public library;- CMake and
pkg-configinstallation metadata.
Note
Native archives and the JSR package contain no linguistic data. Applications must acquire a compatible stem library separately; see Runtime data.
Bindings expose the native C API to other language ecosystems. The Deno binding is published; the Node.js binding is under active development:
| Binding | Description | Documentation |
|---|---|---|
| Deno 2 | Typed TypeScript API for analysis and experimental Greek generation, published on JSR | Deno binding guide |
| Node.js 20+ | ESM facade over an asynchronous Node-API addon; not yet published | Node.js binding guide |
| Python 3.11+ | Pure-Python ctypes facade over the stable C ABI; under active development |
Python binding guide |
The historical @humanities/libmorpheus package remains available through
version 0.3.2; new Deno releases use @libmorpheus/deno.
Native consumers should instead use the public C API.
- CMake 3.25 or newer;
- Ninja;
- a C17 compiler;
- Deno 2 only for the binding tests.
The alpheios-project reference stemlib is a pinned Git submodule, so clone recursively:
git clone --recurse-submodules \
https://github.com/defense-humanites/libmorpheus.git
cd libmorpheusFor an existing clone:
git submodule update --init --recursiveConfigure, build, and test the development preset:
cmake --preset dev
cmake --build --preset dev
ctest --preset devThis produces build/dev/libmorpheus.so (or the platform equivalent) and, by
default, build/dev/cruncher. The runtime build consumes compiled stemlibs and
does not require Flex.
To use another compiled stemlib for the Alpheios fixture suite:
cmake --preset dev -DMORPHEUS_STEMLIB_DIR=/absolute/path/to/stemlibSanitizer and optimized test configurations are available as separate presets:
cmake --preset sanitizers
cmake --build --preset sanitizers
ctest --preset sanitizerscmake --preset thread-sanitizer
cmake --build --preset thread-sanitizer
ctest --preset thread-sanitizercmake --preset release -DBUILD_TESTING=ON
cmake --build --preset release
ctest --preset releaseThe Release tests also install into a clean prefix and verify the public package boundary.
Install the development build into the prefix of your choice:
cmake --install build/dev --prefix /chosen/prefixThe installation contains the shared library, morpheus/morpheus.h, the
Morpheus::morpheus CMake target, libmorpheus.pc, and cruncher. Runtime data
is not installed with the library.
With CMake:
find_package(Morpheus 0.1 CONFIG REQUIRED)
target_link_libraries(my_analyzer PRIVATE Morpheus::morpheus)With pkg-config:
cc analyzer.c $(pkg-config --cflags --libs libmorpheus)Minimal API use:
#include <stdint.h>
#include <morpheus/morpheus.h>
int main(void) {
morpheus_config config = {
MORPHEUS_ABI_VERSION,
sizeof config,
"/path/to/stemlib",
MORPHEUS_LANGUAGE_GREEK
};
morpheus_context *context = NULL;
morpheus_result *result = NULL;
if (morpheus_open(&config, &context) == MORPHEUS_OK &&
morpheus_analyze(
context,
(const uint8_t *)"a)/nqrwpos",
sizeof "a)/nqrwpos" - 1,
MORPHEUS_OPTION_STRICT_CASE,
&result
) == MORPHEUS_OK) {
for (size_t i = 0; i < morpheus_result_count(result); i++) {
morpheus_analysis analysis;
if (morpheus_result_get(result, i, &analysis) == MORPHEUS_OK) {
/* analysis.lemma, analysis.stem, morphology fields, ... */
}
}
}
morpheus_result_free(result);
morpheus_close(context);
return 0;
}Results preserve Morpheus ordering and duplicates. The caller owns every
successful result until morpheus_result_free(). Distinct contexts may run
concurrently; calls on one context must be serialized. The
public API reference documents the complete ABI, error
statuses, ownership rules, and buffer contracts.
Morpheus reads compiled binary databases called stemlibs. Code and data are versioned and distributed separately.
| Dataset | Analysis | Generation | Repository location |
|---|---|---|---|
perseids-tools |
Greek and Latin | No | stemlib/ |
alpheios-project (pinned) |
Greek | Requires a prepared gener.index |
vendor/alpheios-morpheus/dist/stemlib/ |
From a recursive source checkout, prepare a standalone Alpheios directory with the validated experimental generation index using:
sh tools/prepare-runtime-data.sh "$PWD/morpheus-greek-data"The runtime-data guide records exact pinned revisions, digests, acquisition permissions, and redistribution caveats. The stem-library inventory explains the origin and role of each dataset; the production audit records why the checked-in build drivers are not yet a supported reproducible compiler.
We provide two Alpine container images to facilitate the use of the library.
The Dockerfile supports linux/amd64 and linux/arm64 with BuildKit/QEMU.
These images are local qualification and application-build targets.
The default Alpine multi-stage image builds and tests the C17 runtime on musl,
then ships the installed library, cruncher, runtime dependencies, and the
prepared alpheios-project stemlib:
docker build --target runtime -t morpheus .
printf 'a)/nqrwpos\n' | docker run --rm -i morpheus -SThe deno-runtime target adds Deno while preinstalling only the native runtime
and prepared data:
docker build --target deno-runtime -t morpheus-deno .Applications consume the binding as a normal JSR dependency. See the Deno binding guide for the preconfigured paths and a consumer example.
The historical command-line interface remains available as a compatibility
client of the library. It reads MORPHLIB as before:
printf 'a)/nqrwpos\n' | \
MORPHLIB="$PWD/vendor/alpheios-morpheus/dist/stemlib" \
build/dev/cruncher -SRetained options include -L for Latin, -S for non-strict case, -n to
ignore accents, -d for database format, -e for numeric feature indices,
-k to retain Beta Code, -l for lemma-only output, and -V for verbs only.
Native v<version> release tags provide data-free archives and SHA-256 files
for:
- Linux x86-64 glibc;
- Linux aarch64 glibc;
- macOS arm64.
The Deno binding has an independent version and uses deno-v<version> tags for
its standalone source archive and JSR publication. Each binding version declares
the native runtime release and ABI it supports.
The Node.js binding is versioned independently with node-v<version> tags. npm
publishes the ESM facade as @libmorpheus/node and a matching optional Node-API
addon for each supported native platform; the runtime and stem data remain
separate, verified acquisitions.
The Python binding is versioned independently with python-v<version> tags and
publishes the pure-Python libmorpheus distribution to PyPI. It uses ctypes,
so one universal wheel supports Python 3.11 and newer while applications provide
the compatible native runtime and stem data separately.
The checksum detects corruption; it is not a release signature. See platform support for the complete qualification matrix and release qualification for the checks required before a tag. Release changes are recorded in the changelog.
Two separate fixture suites prevent stemlib differences from being mistaken for runtime regressions:
legacy_fixtureschecks inherited Greek and Latin expectations against theperseids-toolsdataset;alpheios_greek_fixtureschecks Greek reference cases against the pinned Alpheios dataset.
Public ABI, installed-package, parallel-context, Deno, ASan/UBSan, and TSan tests complement those fixtures.
The current implementation derives from the perseids-tools fork, the only
baseline known to compile before this modernization. The repository bundles its
Greek and Latin stemlib and pins a newer Alpheios Greek stemlib for additional
testing and validation.
Further documentation:
The inherited Makefiles remain as a compatibility check for libs and
cruncher, but new consumers should use CMake and the public ABI. Other
historical programs below src/ are quarantined and excluded from supported
builds.
This is a mixed-license repository:
- inherited engine, bridge, compatibility, and derived internal code remain under MPL-2.0;
- the normalized public API, Deno binding, and marked independently written support files use AGPL-3.0-or-later.
A file's SPDX identifier controls when present; otherwise the root MPL-2.0 license applies. See the licensing guide for the precise file-level boundary and the license inventory for its rationale and provenance.