Glyph Forge
A Python framework for turning LLM plaintext into styled DOCX documents. Inspired by HTML/CSS and Tailwind design patterns — schemas define the baseline formatting, inline markup handles the overrides, and AI agents handle the rest.
Installation
pip install glyph-forge
Quick Start
from glyph_forge import ForgeClient, create_workspace
ws = create_workspace()
client = ForgeClient()
# Build schema from a reference DOCX
schema = client.build_schema_from_docx(ws, docx_path="template.docx", save_as="my_schema")
# Generate a new DOCX from plaintext
docx_path = client.run_schema(
ws,
schema=schema,
plaintext="Your content here...",
dest_name="output.docx"
)
Tools & Their Purpose
Glyph Forge has several tools. Each one does a specific job. Understanding what each tool is (and isn't) for is key to building reliable workflows.
Schemas — Your Baseline Formatter
What it does: A schema maps heuristic types (headings, paragraphs, lists, tables) to styling rules. When you run a schema against plaintext, Glyph classifies each line by its structural role and applies the matching style.
What it is NOT: A schema is not AI. It does not understand meaning, context, or semantics. It matches structural patterns — a short title-cased line is a heading, a line starting with • is a bullet, and so on.
When to use it: Always. The schema is the foundation of every Glyph workflow. Start here.
Performance: Schemas compile in milliseconds. No API key, no network calls, no latency.
# Schema selectors target structural patterns
{
"type": "H-SHORT", # Short headings (title case, ALL CAPS, <=6 words)
"style": {"font": {"bold": true, "size": 18}}
}
Inline Markup — Context-Aware Overrides
What it does: Inline markup lets you (or an LLM) embed styling instructions directly in the plaintext. Block markup ($glyph-{utilities}) wraps entire paragraphs. Inline markup ([utilities]text[/]) styles specific words or phrases.
What it is NOT: A replacement for schemas. Markup handles exceptions and overrides — it is not meant to style every line of a document from scratch.
When to use it: When you need to style something a schema can't identify on its own. A schema knows what a heading looks like structurally, but it doesn't know that "Professional Summary" is a section you want bolded in blue. An LLM does.
Cascade rule: Inline markup always overrides schema styles. [bold,color-FF0000] on a word wins over whatever the schema says for that line.
$glyph-font-size-11
This is normal body text, but [bold,color-FF0000]this phrase[/] stands out.
$glyph
Plaintext Agent (Markup Agent) — LLM-Powered Styling
What it does: You describe what you want in natural language, and the agent rewrites the plaintext with the appropriate $glyph blocks and [utilities]text[/] inline tags inserted.
What it is NOT: A content generator. It does not write or rewrite your text. It wraps existing text in markup.
When to use it: When you already have an established schema and want to apply styling that requires understanding the meaning of the text — things like "bold the professional summary" or "make the warning section red."
Requires: API key. This is an AI agent, so it adds processing time.
# The agent reads the plaintext, understands the request, and inserts markup
marked_up = client.ask(message="Make the professional summary bold", current_plaintext=plaintext)
Schema Agent — Developer Scaffolding
What it does: Helps you quickly draft or edit schemas through natural language prompts. You describe the document structure you want, and it generates selector JSON.
What it is NOT: A source of truth. Schemas generated by this agent should be reviewed, tested, and stored in your backend. Do not use agent-generated schemas in production without human review.
When to use it: During development, to bootstrap a schema quickly. Think of it like a code generator — useful to get started, but you own the output.
Requires: API key.
XML Agent — Experimental Final Polish
What it does: Operates directly on the unzipped DOCX XML structure. An LLM identifies a target element in the XML and writes modifications to it.
What it is NOT: A content generator or primary formatter. Do not use it to style an entire document. Its job is surgical, targeted edits — a final polish step when the schema and markup aren't enough.
When to use it: Rarely. When you need something that can't be expressed through schemas or markup — for example, modifying a specific XML attribute that Glyph's styling utilities don't cover. In theory an LLM can write anything to a DOCX with this method, but it requires precision.
Status: Beta. The accuracy and reliability of direct XML writing is still being researched.
Requires: API key.
Form Detection — Heuristic Line Classification
What it does: Classifies each line of plaintext by its structural form (H-SHORT, L-BULLET, P-BODY, T-ROW, etc.) using the same heuristic engine that powers schemas. Returns a list of classifications with confidence scores.
What it is NOT: AI. This is the same deterministic heuristic engine used by schemas, exposed as a standalone tool.
When to use it: When you want to understand what Glyph "sees" in your plaintext before building a schema. Also useful for filtering — extract only headings, or only list items, from a large document.
Performance: Local, milliseconds, no API key.
result = client.detect_forms(ws, text=text, forms=["H-SHORT", "L-BULLET"])
Document Chunking — Heading-Bounded Splitting
What it does: Splits plaintext or DOCX files at heading boundaries, producing independent chunks that can be processed one at a time.
What it is NOT: Semantic chunking. It splits at structural heading boundaries detected by heuristics, not by topic or meaning.
When to use it: To reduce LLM context window usage. Instead of sending a 50-page document to an LLM, chunk it and process one section at a time. Works with both plaintext files and DOCX files.
Performance: Local, milliseconds, no API key.
result = client.chunk_plaintext_text(ws, text=text)
for chunk in result["chunks"]:
llm_response = call_llm(chunk["plaintext"]) # Each chunk fits in context
Tool Summary
| Tool | AI? | API Key? | Speed | Purpose |
|---|---|---|---|---|
| Schema | No | No | Milliseconds | Baseline structural styling |
| Inline Markup | No | No | Milliseconds | Embedded style overrides in plaintext |
| Plaintext Agent | Yes | Yes | Seconds | LLM applies markup based on meaning |
| Schema Agent | Yes | Yes | Seconds | LLM drafts/edits schemas |
| XML Agent | Yes | Yes | Seconds | Direct DOCX XML modifications (beta) |
| Form Detection | No | No | Milliseconds | Classify lines by heuristic form |
| Chunking | No | No | Milliseconds | Split documents at heading boundaries |
| Indexing | No | No | Milliseconds | Structured document index with sections and form-annotated segments |
Workflow Patterns
Pattern 1: Schema Only (Fastest)
The simplest path. Good when your document structure is consistent and predictable.
LLM writes plaintext --> Schema styles heuristics --> DOCX
(milliseconds, no AI)
schema = client.build_schema_from_docx(ws, docx_path="template.docx")
docx_path = client.run_schema(ws, schema=schema, plaintext=plaintext)
Pattern 2: Schema + Markup Agent (Most Common)
Schema handles the structural baseline, then the markup agent adds context-aware overrides.
LLM writes plaintext --> Markup agent inserts styling --> Schema compiles --> DOCX
(seconds, requires API key) (milliseconds)
schema = client.build_schema_from_docx(ws, docx_path="template.docx")
# Agent understands "professional summary" semantically and inserts markup
response = client.ask(
message="Bold the professional summary and make section headers dark blue",
current_plaintext=plaintext,
)
marked_up_plaintext = response["plaintext"]
docx_path = client.run_schema(ws, schema=schema, plaintext=marked_up_plaintext)
Pattern 3: Chunk + Process (Large Documents)
For documents that exceed LLM context windows, chunk first, process per-section, reassemble.
Document --> Chunk at headings --> Process each chunk --> Reassemble --> Schema --> DOCX
(milliseconds) (per-chunk LLM calls)
chunks = client.chunk_plaintext_text(ws, text=full_document)
processed_sections = []
for chunk in chunks["chunks"]:
result = call_llm(chunk["plaintext"]) # Your LLM call
processed_sections.append(result)
final_plaintext = "\n".join(processed_sections)
docx_path = client.run_schema(ws, schema=schema, plaintext=final_plaintext)
Pattern 4: Detect + Filter (Pre-Processing)
Use form detection to extract or filter specific content types before processing.
Document --> Detect forms --> Filter by type --> Process subset
(milliseconds)
result = client.detect_forms(ws, text=text, forms=["H-SHORT", "H-SECTION-N"])
headings = [c["text"] for c in result["classifications"]]
# Use headings as a table of contents, outline, or navigation structure
Pattern 5: Index + Annotate (Structured Pre-Processing)
Build a structured index of your document with heading-bounded sections and form-annotated segments. Extract exactly what you need before calling an LLM.
Document --> Index at headings --> Annotate segments --> Extract specific forms --> LLM
(milliseconds) (milliseconds) (filter by type)
result = client.index_document(
ws,
text=full_document,
annotate_forms=["L-BULLET", "T-ROW"],
)
for sec in result["sections"]:
bullets = [s for s in sec["segments"] if s["form"] == "L-BULLET"]
if bullets:
# Only send bullet content to LLM — reduces tokens and noise
for b in bullets:
llm_response = call_llm(b["content"])
Building a Workflow: Resume Builder Example
Here's how the tools layer together for a real use case.
Step 1 — Build your schema. Look at your reference resume DOCX. Note the font sizes, colors, and spacing for headings, body text, bullet lists. Create selectors for each:
schema = client.build_schema_from_docx(ws, docx_path="resume_template.docx", save_as="resume")
At this point, LLM plaintext -> schema -> DOCX already produces a solid result with correct heading sizes, bullet formatting, and paragraph spacing. This runs in milliseconds with no API key.
Step 2 — Add markup for semantic styling. A schema knows what a heading looks like structurally, but it doesn't know that "Professional Summary" should be styled differently from "Education." Use the markup agent:
response = client.ask(
message="Bold the professional summary section header and make it dark blue",
current_plaintext=resume_plaintext,
)
The agent returns the same plaintext, but now the professional summary line is wrapped in $glyph-bold-color-1F4E78 markup. When the schema runs, inline markup overrides the default heading style for just that section.
Step 3 — Compile. Feed the marked-up plaintext through the schema:
docx_path = client.run_schema(
ws,
schema=schema,
plaintext=response["plaintext"],
dest_name="resume_output.docx"
)
The key insight: Schemas are fast and deterministic. Agents are smart but slow. Layer them — schema for the 90% that's structural, agents for the 10% that requires understanding.
CLI Usage
# Build schema from template
glyph-forge build template.docx -o ./output
# Build and run in one command
glyph-forge build-and-run template.docx input.txt -o ./output
# Run existing schema
glyph-forge run schema.json input.txt -o ./output
# Detect forms in plaintext
glyph-forge detect-forms document.txt --forms H-SHORT,L-BULLET
# Chunk a document
glyph-forge chunk report.txt
glyph-forge chunk report.docx
# Index a document with annotations
glyph-forge index document.txt --annotate-forms L-BULLET,T-ROW
glyph-forge index report.docx
Documentation
Full documentation: glyphapi.ai
License
Apache License 2.0 - see LICENSE for details.
Copyright 2025 Devpro LLC
Metadata
Release files for glyph-forge 4.0.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| glyph_forge-4.0.0.tar.gz | 197.3 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| glyph_forge-4.0.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 451.5 kB
Release files / glyph_forge-4.0.0.tar.gz
| Download URL | glyph_forge-4.0.0.tar.gz |
|---|---|
| Size | 197.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
de7d1a7ae3de3bad3a9a531b93baa9269ee52ef9b47470f98a5be6ca40136ef4
|
|
BLAKE2b-256 checksum How to use checksums |
f7cad4c6a0fed961ac28e4b2fe419be04ee15526d43bacde5da5c11ff39d246c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.0.1 CPython/3.12.8
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Feb 10, 2026.
Transparency logRelease files / glyph_forge-4.0.0-py3-none-any.whl
| Download URL | glyph_forge-4.0.0-py3-none-any.whl |
|---|---|
| Size | 254.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1414a5deba66fb3db74b39faf96741e708befc9569179af7ff47660b6e28a1ec
|
|
BLAKE2b-256 checksum How to use checksums |
3a83ecd38747976e825abd1465ee45aa5b5c94977f1ea1248d797572d6d28de4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.0.1 CPython/3.12.8
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Feb 10, 2026.
Transparency logSecurity for glyph-forge 4.0.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for glyph_forge-4.0.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Feb 10, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.