How khiproteam/khipro-library works
1. Overall shape
- This is a cross-platform C++ core library for the Khipro Bangla input method, with thin platform bindings for Android and WebAssembly/JavaScript.
- The architecture is centered on one reusable engine that is built into native libraries for multiple targets.
2. Core domain boundary
- core/ is the main subsystem and owns the actual input-method logic.
- It exposes a public C API (core/include/khipro/khipro.h) so non-C++ consumers can integrate without depending on internal C++ types.
3. Engine pipeline
- Inside core/src/, the implementation is split into:
- engine.* for runtime state and composition behavior,
- spec.* and sexpr.* for parsing/interpreting the bundled m17n layout specifications,
- convert.* for converting between internal representations and output text.
- The main data flow is: key input → engine state update → spec-driven composition → produced Bangla output.
4. Bundled layout data
- The input-method behavior is not hardcoded; it comes from embedded .mim files in resources/.
- There are two shipped variants:
- bn-khipro.mim for desktop keyboards,
- bn-khipro-touchscreen.mim for touch devices.
- resources/.lock and the scripts/resources/* tooling track provenance and syncing of those upstream layout files.
5. Build-time resource embedding
- The repository treats the m17n specs as build inputs that are embedded into the library at compile time.
- This means the runtime library has no external dependency on the .mim files; they are packaged into the native artifacts.
6. Android binding layer
- bindings/android/ contains an Android Gradle project that wraps the native core through JNI.
- jni_bridge.cpp is the native bridge, while the Kotlin library under bindings/android/library/ provides the public Android API.
- The Kotlin classes (KhiproEngine, KhiproIme, KhiproNative, etc.) separate engine control, IME integration, and result/variant modeling.
7. Android usage model
- The Android binding is designed for both app integration and IME-style usage, with sample entry points in bindings/android/samples/.
- The data flow is: Kotlin API → JNI bridge → native C API/core engine → result back to Kotlin.
8. WebAssembly binding layer
- bindings/web/ packages the same core engine for browser or JS runtimes via Wasm.
- wasm_shim.cpp adapts the native core into a form that can be exported to TypeScript (src/index.ts).
- This is another thin boundary around the same shared engine, not a separate implementation.
9. Portability and packaging
- The repository is designed for multiple native targets: Linux, Windows, macOS, Android, and Wasm.
- cmake/ and container/ hold the platform toolchains and Docker-based build environments used to produce the different artifacts.
- The build is orchestrated through Makefile, CMakeLists.txt, and target scripts in scripts/targets/.
10. Tests and conformance
- tests/ contains conformance tests driven by CSV testcases in resources/.
- These tests validate the engine’s composition behavior against expected Khipro outputs, so they sit at the boundary between core logic and the bundled layout specs.
11. Versioning and release flow
- khipro.meta is the single source of truth for package metadata and versioning.
- The GitHub Actions release workflow and scripts/ automation use it to sync upstream layout versions, rebuild all targets, run tests, and publish tagged releases.
12. Architecture summary for diagramming
- The cleanest diagram is: upstream m17n layout specs → embedded resources → C++ core engine/API → platform bindings (Android JNI, WebAssembly) → target-specific packaged artifacts.
- Around that sit the build/release systems, which do not change runtime behavior but control resource ingestion, compilation, testing, and distribution.
Main entry points: embed.py Embed tool · engine.cpp Engine · khipro.h C API · KhiproEngine.kt Kotlin API
Components 21
Core library
Reusable C++ input-method engine and public API.
- C API · Stable C-facing entrypoint for non-C++ consumers.
core/include/khipro/khipro.h - Engine · Maintains composition state and processes key input.
core/src/engine.cpp - Spec parser · Parses and interprets embedded m17n specification data.
core/src/spec.cpp - S-expr · Supports reading spec expressions used by the layout files.
core/src/sexpr.cpp - Converter · Converts internal composition results to output text.
core/src/convert.cpp - API impl · Implements the public C API on top of the C++ engine.
core/src/api.cpp
Embedded layouts
Bundled m17n specs and test fixtures consumed by the core and tests.
- MIM layouts · Bundled Bangla keyboard and touchscreen layout specs.
resources/bn-khipro.mim - Touch layout · Touch-oriented variant of the bundled layout.
resources/bn-khipro-touchscreen.mim - Resource lock · Tracks upstream layout sync state and embedding provenance.
resources/.lock - CSV cases · Expected input/output cases for conformance testing.
resources/khipro-testcases.csv
Platform bindings
Thin adapters that expose the same engine to Android and WebAssembly.
- Kotlin API · Public Android-facing API for engine control and IME integration.
bindings/android/library/src/main/kotlin/com/khiproteam/khipro/KhiproEngine.kt - IME layer · IME-style integration and higher-level input workflow on Android.
bindings/android/library/src/main/kotlin/com/khiproteam/khipro/KhiproIme.kt - JNI bridge · Bridges Kotlin calls to the native C API.
bindings/android/jni_bridge.cpp - Result model · Represents results and variants returned to Android callers.
bindings/android/library/src/main/kotlin/com/khiproteam/khipro/KhiproResult.kt - TS API · TypeScript-facing API over the WebAssembly build.
bindings/web/src/index.ts - Wasm shim · Adapts the core engine for export to JavaScript/Wasm runtimes.
bindings/web/wasm_shim.cpp
Build & release
Tooling for embedding resources, cross-compiling, packaging, and publishing.
- CMake · Primary native build configuration for core and bindings.
CMakeLists.txt - Target scripts · Platform build and target orchestration scripts.
scripts/targets/common.sh - Embed tool · Build-time tooling that packs layout specs into native artifacts.
scripts/resources/embed.py - Release workflow · GitHub Actions workflow for sync, build, test, and release.
.github/workflows/release.yml
Tests
Conformance checks for engine behavior against bundled cases.
- Conformance · Runs engine behavior checks against bundled testcases.
tests/main.cpp
Connections 22
- MIM layouts → Embed tool: embed · Bundles desktop layout data into build artifacts.
- Touch layout → Embed tool: embed · Bundles touchscreen layout data into build artifacts.
- Resource lock → Target scripts: sync · Tracks upstream provenance used by resource automation.
- Embed tool → Spec parser: feeds · Provides embedded spec data to the core parser.
- S-expr → Spec parser: parses · Supports interpreting spec expressions.
- Spec parser → Engine: drives · Defines the composition rules used by runtime state.
- Engine → Converter: outputs · Hands composition results to text conversion.
- Engine → API impl: used by · Core runtime is exposed through the C API implementation.
- API impl → C API: exports · Publishes the stable public interface.
- C API → JNI bridge: calls · Android JNI invokes the native C API.
- JNI bridge → Kotlin API: bridges · Provides native backing for the Kotlin wrapper.
- Kotlin API → IME layer: extends · IME integration builds on the engine-facing API.
- Kotlin API → Result model: returns · Result and variant types model Kotlin-facing outputs.
- C API → Wasm shim: exports · Wasm build exposes the same C API through a shim.
- Wasm shim → TS API: binds · TypeScript API wraps the Wasm exports.
- Embed tool → CMake: integrates · Embedding happens during native build configuration.
- CMake → Target scripts: orchestrates · Target scripts drive per-platform builds.
- Target scripts → Release workflow: triggers · Release automation reuses the build scripts.
- CSV cases → Conformance: drives · CSV fixtures define expected engine behavior.
- Engine → Conformance: validated by · Conformance tests exercise the runtime engine.
- Release workflow → Embed tool: packages · Release workflow rebuilds artifacts with embedded resources.
- Release workflow → Conformance: runs · Release workflow validates behavior before publishing.