joaju 0.1.0

A scientific academic compiler and typographical orchestrator in Rust for Typst, clinical pedigrees, and tables
Documentation

Joaju (djo-a-DJÚ)

crates.io docs.rs License: Apache-2.0 GOST

Joaju (Guarani): Link, reciprocal bond, connection, edge.
Declarative local orchestrator and native scientific academic compiler in Rust for Typst typographical output, charts, academic tables, and clinical pedigrees.

⚠️ Active Development Notice (pre-1.0 / dev)
Joaju is currently in early active development (0.2.x). The API and HTTP endpoints are evolving prior to stabilizing version 1.0.0. Feedback and contributions are welcome!

📌 Overview

Joaju is an academic layout and compilation pipeline focused on privacy, deterministic execution, data protection compliance (strict LGPD alignment), and ergonomic integration with Obsidian. It acts as a bridge between Markdown notes and academic/technical publications compliant with standards such as ABNT or Vancouver.

Rather than overloading text editors with heavy renderers or relying on third-party cloud services that compromise data confidentiality, Joaju encapsulates a Docker-backed microservice stack that provides:

  1. Multi-Engine Diagrams & Scientific Graphics: Rendering flowcharts, system architectures, and graphs (Mermaid, Graphviz, PlantUML) via seamless integration with Kroki, featuring layout scale control without injecting HTML into the editor.

  2. Hybrid Typographical Compilation: Leveraging Pandoc (--citeproc) for robust bibliographic resolution integrated with Zotero, compiling structured output at high speed with Typst and academic templates (e.g., ABNT NBR 14724).

  3. Specialized Pedigree Module: Deterministic processing of clinical pedigrees via native R engines (kinship2 / pedtools), converting tabular records into standards-compliant SVGs aligned with the guidelines of the National Society of Genetic Counselors (NSGC) and the American College of Medical Genetics (ACMG).

🏗️ Pipeline Architecture

flowchart TD
    subgraph Obsidian [Obsidian Vault / Desktop & Tablet]
        MD["Markdown Note with YAML & Declarative Blocks"]
        TP["Templater Automation Script"]
        MD -->|"Hotkey"| TP
    end

    subgraph Docker [Local Docker Stack - Joaju]
        direction TB
        SRV["server.js - Node.js Orchestrator :3000"]
        TP -->|"POST /compile"| SRV

        subgraph Preprocess [Dynamic Preprocessing]
            direction LR
            H_BLK["kinship2 / pedtools Block"] -->|"CSV + %% Directives"| R_ENG["Rscript pedtools / kinship2"]
            M_BLK["Mermaid Block"] -->|"Code + %% Directives"| KRK["Kroki Gateway + Chromium Headless"]
            R_ENG -->|"SVG Vector"| TYP_INJ1["Typst Raw Block Injection"]
            KRK -->|"High-Res PNG"| TYP_INJ2["Typst Raw Block Injection"]
        end

        SRV --> Preprocess

        subgraph Compilers [Two-Stage Compilation]
            PANDOC["Pandoc Citeproc"] -->|"Resolves .bib + .csl"| TYP_AST["Intermediate Typst AST"]
            TYP_AST --> TYPST["Typst Compiler 0.11.x"]
            TEMPLATE["data/template.typ - NBR 14724"] --> TYPST
        end

        Preprocess --> PANDOC
        TYPST -->|"PDF Binary Buffer"| SRV
    end

    SRV -->|"HTTP 200 Response"| TP
    TP -->|"Local write to vault"| PDF["Final Article .pdf"]

🗂️ File Structure

The project repository structure is organized as follows:

joaju/
├── Dockerfile              # Container image: Node.js + Pandoc + R (kinship2/pedtools) + Typst
├── docker-compose.yml      # Service orchestration for compiler and Kroki gateway
├── server.js               # HTTP orchestrator, regex preprocessors, and dynamic dispatch
├── plot_pedigree.R         # R engine for clinical pedigree rendering
├── README.md               # Ecosystem documentation
└── data/                   # Persistent volume mounted in container
    ├── template.typ        # Typst typographical rules (NBR 14724)
    ├── abnt.csl            # ABNT citation style (NBR 10520)
    ├── vancouver.csl       # Vancouver citation style (Medical / ICMJE)
    └── referencias.bib     # References exported by Better BibTeX (Zotero)

🚀 Installation and Setup

1. Prerequisites

  • Docker and Docker Compose installed.
  • Obsidian with community plugins Templater and active Mermaid support.

2. Download CSL Styles

In the project root directory, ensure the data/ directory exists and download the standardized styles:

mkdir -p data

# Download official ABNT citation style
curl -fsSL "https://raw.githubusercontent.com/citation-style-language/styles/master/associacao-brasileira-de-normas-tecnicas.csl" -o data/abnt.csl

# Download official Vancouver citation style
curl -fsSL "https://raw.githubusercontent.com/citation-style-language/styles/master/vancouver.csl" -o data/vancouver.csl

3. Launching Containers

Build and run the services in the background:

docker compose up -d --build

The orchestrator service will be available at http://localhost:3000.

✍️ Obsidian Usage Guide

1. Frontmatter (YAML) and Supported Typographical Profiles

Joaju supports three official typographical profiles configured in the note's YAML frontmatter:

---
titulo: Family Pedigree Analysis and Clinical Genetics Study
subtitulo: Outpatient Case Report and Autosomal Recessive Inheritance
autor: Medical Genetics Team
instituicao: Federal University of Santa Catarina
local: Florianopolis
ano: 2026
perfil: trabalho-ufsc # Options: 'trabalho-ufsc', 'abnt', or 'vancouver'
---

📚 Compilation Profiles Comparison

Profile (perfil:) Purpose & Description Typographical Rules / Template Citation / CSL Supported YAML Variables
trabalho-ufsc UFSC academic theses, reports, and monographs Automated institutional cover, title page, 3cm/2cm margins, pagination from page 2 trabalho-ufsc.csl (ABNT/UFSC) titulo, subtitulo, autor, instituicao, local, ano, fonte, tamanho
abnt General academic papers conforming to ABNT NBR 14724 ABNT margins (top/left: 3cm, bottom/right: 2cm), 1.5 line spacing, NBR 6024 numbering abnt.csl (Brazilian National Standards) titulo, autor, subtitulo, fonte, tamanho
vancouver Biomedical and health science articles and reports International biomedical numeric style, references sorted by appearance order in text vancouver.csl (ICMJE / NLM) titulo, autor, subtitulo, fonte, tamanho

⚙️ YAML Frontmatter Variables

  • perfil: Profile identifier (trabalho-ufsc, abnt, or vancouver). Default: abnt.
  • titulo: Main title of the publication or academic document.
  • subtitulo: Optional subtitle (rendered after a colon or beneath the title depending on profile).
  • autor: Author or author list.
  • instituicao: (Specific to trabalho-ufsc) University, faculty, or department name for standard cover.
  • local: (Specific to trabalho-ufsc) City of the institution (e.g. Florianopolis).
  • ano: (Specific to trabalho-ufsc) Year of academic delivery (e.g. 2026).
  • fonte: Typographical font family in Typst (default: Liberation Sans).
  • tamanho: Main body font size (default: 12pt).

2. Supported Engines & Module Catalog

Joaju includes specialized engines for scientific diagrams, clinical pedigrees, 2D chemical structures, and academic tables. Complete documentation with interactive examples is available at joaju.2lp.in and in the Obsidian vault documentation (00_meta/joaju/).

Engine Purpose Joaju Directives (%%) Native Engine / R Parameters Full Documentation
pedtools Primary: Modern clinical pedigrees (R pedsuite) layout.width, layout.max_width, src/file cex, symbolsize, foldLabs, margins, addSpace, col, lwd, lty, fill, plot_width, plot_height, legend, legend.type pedtools.html
kinship2 Legacy: Clinical pedigrees in phase-out layout.width, layout.max_width, src/file cex, symbolsize, branch, density, angle, col, lwd, lty, plot_width, plot_height, legend, legend.type kinship2.html
table Academic tables (ABNT NBR 14724 & APA) caption/title, note/fonte, align, columns, layout.width, src/file - table.html
openchemlib 2D chemical structure via SMILES title, layout.width, layout.max_width, width, height, file/src - quimica.html
openbabel 2D chemical structure via MOL/SDF title, layout.width, layout.max_width, file/src - quimica.html
mermaid Flowcharts, sequences, Gantt via Kroki layout.width, layout.max_width, src/file - mermaid.html
d2 Modern declarative system architecture diagrams layout.width, layout.max_width, src/file - d2.html
plantuml UML and software engineering diagrams layout.width, layout.max_width, src/file - plantuml.html
graphviz Graphs and networks in DOT language layout.width, layout.max_width, src/file - graphviz.html
gist Embedding external analytical scripts url, file, title - gist.html

3. Detailed Engines & Practical Examples

3.1. Clinical Pedigrees (pedtools - Recommended)

The pedtools engine standardizes family pedigrees with automatic vertical generation scaling, exact split half-fills for heterozygotes, proband indicators with padding, and integrated legends.

%% layout.width=95% layout.max_width=720pt cex=0.85 symbolsize=1.25 legend=c("Normal (M)","Normal (F)","Affected (M)","Affected (F)","Proband") legend.type=c("sq_empty","circ_empty","sq_solid","circ_solid","proband")
id,pai,mae,sex,fenotipo,proband,label
1,0,0,M,wt,0,I-1 [Normal]
2,0,0,F,afetado,0,I-2 [Affected]
3,1,2,M,het,0,II-1 [Carrier]
4,1,2,F,afetado,1,II-2 [Affected]
5,1,2,M,wt,0,II-3 [Normal]

Pre-rendered Output: pedtools output

  • CSV Columns: id, pai (or fid), mae (or mid), sex (M/F/1/2), fenotipo (wt, het, afetado, ?), proband (1/0), label (supports \n via brackets), status (1/deceased).
  • Legend Types: sq_empty, circ_empty, sq_half, circ_half, sq_solid, circ_solid, suspect, proband.

3.2. Legacy Pedigrees (kinship2 - Phase-out)

Retained in Joaju for backward compatibility with legacy clinical notes:

%% layout.width=90% layout.max_width=600pt cex=0.88 symbolsize=2.85 legend=c("Normal (M)","Carrier (F)","Affected (M)","Proband") legend.type=c("sq_empty","circ_half","sq_solid","proband")
id,pai,mae,sex,fenotipo,proband,label
1,0,0,M,wt,0,I.1
2,0,0,F,het,0,I.2
3,1,2,M,afetado,1,II.1 [Affected]
4,1,2,F,wt,0,II.2 [Normal]

Pre-rendered Output: kinship2 output

3.3. Academic Tables (table) & Single Source of Truth (SSOT)

Transforms tabular CSV data into clean three-line academic tables conforming to ABNT NBR 14724 and APA styling, with support for shared Single Source of Truth (SSOT) datasets via the joaju-csv crate:

%% src=data/family.csv
%% title=Table 1 – ABO Blood Group Phenotypes in Family Cohort
%% select=id, pai, mae, sexo, fenotipo_abo
%% where=geracao <= 2
%% note=Source: Prepared by authors from SSOT dataset (2026).

Direct inline tables are also supported with comma-delimited or markdown pipe (|) formatting:

%% caption="Phenotypic and Genotypic Segregation in F2 Pea Cohort (Pisum sativum)"
%% align=l, c, c, r
%% note="Source: Gregor Mendel, Versuche uber Pflanzen-Hybriden (1866)."
Observed Phenotype, Probable Genotype, Count (N), Observed Ratio
Smooth Seeds (Dominant), $R R$ / $R r$, 5474, 74.74% (approx. 3/4)
Wrinkled Seeds (Recessive), $r r$, 1850, 25.26% (approx. 1/4)
Consolidated Total, -, 7324, 100.00% (3 : 1)

Pre-rendered Output: table output

3.4. 2D Chemical Structures (openchemlib and openbabel)

Vector SVG rendering of molecular structures from SMILES notation or MOL files:

%% layout.width=45% layout.max_width=300pt
%% title="Structure of 17β-Estradiol (Estrogen Hormone)"
%% layout.width=50% layout.max_width=350pt
C[C@]12CC[C@@H]3c4ccc(O)cc4CC[C@H]3[C@@H]1CC[C@@H]2O

Pre-rendered Output: openchemlib output

3.5. Technical Diagrams (d2, mermaid, plantuml, graphviz)

D2 Diagram
%% width=75% max-width=500pt
blood_sample: Blood Collection -> ngs_sequencing: NGS Sequencing
ngs_sequencing -> bioinformatics: Bioinformatic Analysis
bioinformatics -> report: Medical Report

Pre-rendered Output: d2 output

Mermaid Diagram
%% width=80% max-width=550pt
graph TD
    A[Sample Collection] --> B[NGS Sequencing]
    B --> C{Pathogenic Variant?}
    C -->|Yes| D[Genetic Counseling]
    C -->|No| E[Clinical Follow-up]

Pre-rendered Output: mermaid output

PlantUML Diagram
@startuml
skinparam monochrome true
skinparam defaultFontName "Liberation Sans"
autonumber
Physician -> Joaju: Submits Markdown note
Joaju -> Kroki: Renders technical diagrams
Joaju -> Pandoc: Resolves bibliographic references (.bib)
Joaju -> Typst: Compiles final PDF
Joaju --> Physician: Returns compiled PDF
@enduml

Pre-rendered Output: plantuml output

Graphviz DOT Graph
digraph GeneNetwork {
    rankdir=LR;
    node [shape=box, style=rounded, fontname="Liberation Sans"];
    TP53 -> MDM2 [label="regulates"];
    MDM2 -> TP53 [label="inhibits", style=dashed];
    TP53 -> CDKN1A [label="induces"];
    CDKN1A -> "Cell Cycle Arrest";
}

Pre-rendered Output: graphviz output

3.6. Analytical Script Embedding (gist)

Resilient embedding of external computational scripts (R, Python, Julia, SQL):

%% url=https://gist.github.com/example/hardy_weinberg_calc
%% file=hardy_weinberg.R
%% title="R Script: Hardy-Weinberg Equilibrium Allele Frequencies"

Pre-rendered Output: gist output

7. Obsidian Templater Integration

To trigger compilation using a hotkey in Obsidian:

  1. Create a note named Compile Article.md inside your Obsidian templates folder with the following script:
<%*
const activeFile = app.workspace.getActiveFile();
if (!activeFile) {
    new Notice("❌ No active note to compile!");
    return;
}

new Notice("⏳ Compiling via Joaju...");

try {
    const content = await app.vault.read(activeFile);

    const response = await fetch("http://localhost:3000/compile", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ markdown: content })
    });

    if (!response.ok) {
        throw new Error(await response.text());
    }

    const buffer = await response.arrayBuffer();
    const folderPath = activeFile.parent ? activeFile.parent.path : "";
    const pdfPath = (folderPath && folderPath !== "/" ? folderPath + "/" : "") + activeFile.basename + ".pdf";

    const existingFile = app.vault.getAbstractFileByPath(pdfPath);
    if (existingFile) {
        await app.vault.modifyBinary(existingFile, buffer);
    } else {
        await app.vault.createBinary(pdfPath, buffer);
    }

    new Notice(`✅ PDF generated: ${activeFile.basename}.pdf`);
} catch (err) {
    new Notice(`❌ Joaju error: ${err.message}`, 10000);
}
_%>
  1. Open Settings > Templater > Template Hotkeys;
  2. Assign Compile Article.md to your preferred keyboard shortcut (e.g., Ctrl + Alt + B).

🛠️ Backend API

GET /

Interactive web playground for instant editing, preview, and validation of diagrams and clinical pedigrees.

POST /render

Renders an isolated pedigree or Mermaid diagram block, returning the chart in vector SVG format.

  • Payload:

    {
      "code": "```kinship2\n%% layout.width=90%\nid,pai,mae,sex,fenotipo\n1,0,0,M,wt\n...\n```"
    }
    
  • Responses:

    • 200 OK: JSON containing the generated SVG:

      {
        "format": "kinship2",
        "type": "svg",
        "svg": "<svg ...>...</svg>"
      }
      
    • 400 Bad Request: Invalid parameters or empty code.

    • 500 Internal Server Error: Rendering engine failure (Rscript or Kroki).

POST /compile

Accepts Markdown content and compiles it into an academic PDF (Pandoc + Citeproc + Typst). Supports two submission modes:

  1. Plaintext Markdown (JSON):

    • Content-Type: application/json
    • Payload:
      {
        "markdown": "# Article content..."
      }
      
  2. Workspace Package with Attachments (ZIP):

    • Content-Type: application/zip (or application/octet-stream)
    • Payload: Binary .zip archive containing:
      • main.md: Primary Markdown document;
      • attachments/: Folder containing referenced images (![[photo.png]], ![[image_with_underscore.png|500]], ![[photo.png|Caption]]), CSV files (%% src=...), and chemical structure files (%% file=...). Joaju automatically normalizes Obsidian wikilinks and filenames containing underscores (_) into native Typst syntax with academic styling.
    • Joaju unpacks the archive into an ephemeral workspace /tmp/job_<id>/, enabling Pandoc and Typst to reference relative paths directly without requiring Base64 conversion. The Typst compiler automatically sanitizes isolated < characters in text and tables to prevent unclosed label syntax errors. The temporary directory is wiped immediately after compilation.
  • Responses:

    • 200 OK: Compiled application/pdf binary.

    • 500 Internal Server Error: Detailed error description from Pandoc, R, or Typst.

GET /health

Operational health check endpoint for Docker, Kubernetes, and CCCP orchestration scripts.

  • Responses:
    • 200 OK:
      {
        "status": "ok",
        "name": "joaju",
        "version": "0.2.0-dev.1",
        "uptime": 12.34
      }
      

POST /unfurl

Extracts rich metadata from a URL (title, description, cover image, domain, author, publish date, estimated reading time) using Readability + linkedom without requiring a headless browser. Optionally captures an archival PDF snapshot of the page via Readability → Pandoc → Typst.

  • Payload:

    {
      "url": "https://example.com/article",
      "archive": false
    }
    
    Field Type Description
    url string Target URL to unfurl. Supported schemes: http, https.
    archive boolean If true, includes an archival PDF snapshot encoded as pdfBase64.
  • Responses:

    • 200 OK:

      {
        "ok": true,
        "url": "https://example.com/article",
        "title": "Page Title",
        "description": "Extracted summary from OpenGraph or meta description tag.",
        "imageUrl": "https://example.com/og-image.jpg",
        "faviconUrl": "https://example.com/favicon.ico",
        "domain": "example.com",
        "siteName": "Example",
        "author": "Jane Doe",
        "date": "2025-01-15",
        "readingTimeMin": 4,
        "hasArticle": true,
        "pdfBase64": "JVBERi0x..." 
      }
      

      pdfBase64 is only present when archive: true.

    • 400 Bad Request: Missing or invalid url.

    • 422 Unprocessable Entity: Unsupported protocol or upstream HTTP error.

🛠️ CCCP Development Commands (Serve, Dev & Demo)

Joaju maintains full alignment with the CCCP CLI workflow:

1. Development Server with Live Reload

# Via CCCP (delegates automatically to scripts/dev.sh):
cccp serve --dev

# With custom port and browser options:
./scripts/dev.sh --port 3100 --localhost --open

# Or via npm:
npm run dev

2. Demonstration Mode (VDNKh Exhibition)

# Executes validation routine and opens Web Playground with fixtures seeded in data/demo/:
cccp serve --demo

# Or directly:
npm run demo

3. Static Preview Server

# Serves static Web Playground (./public) via Mayak or Python:
cccp serve

⚖️ GOST Compliance

This repository adheres to the GOST v1.1.0 specification (lumen profile). Specification integrity and automation rules are audited and managed via the cccp CLI across .gost/.

📄 License

This project is open-source software distributed under the Apache-2.0 license:

Component License File
Source Code & Core Engine Apache-2.0 LICENSE
Logos & Brand Identity CC-BY-ND-4.0 LICENSE-LOGO
Media & Illustrations CC-BY-SA-4.0 LICENSE-MEDIA