Skip to content
Open
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
1 change: 1 addition & 0 deletions .github/workflows/accessibility-regression.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ jobs:
- name: Install Python dependencies
run: |
python -m pip install --upgrade pip
python -m pip install --upgrade --force-reinstall "git+https://github.com/Community-Access/quill-glow-core.git@main"
python -m pip install -e ./desktop
python -m pip install -e ./web

Expand Down
1 change: 1 addition & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ jobs:
done
}

install_with_retry 4 python -m pip install --upgrade --force-reinstall "git+https://github.com/Community-Access/quill-glow-core.git@main"
install_with_retry 4 python -m pip install -e ./desktop
install_with_retry 4 python -m pip install -e ./web
install_with_retry 4 python -m pip install -r ./mcp_server/requirements.txt
Expand Down
7 changes: 5 additions & 2 deletions .github/workflows/feature-flags-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,17 @@ jobs:
- name: Install dependencies (desktop and web dev)
run: |
python -m pip install --upgrade pip setuptools wheel
python -m pip install --upgrade --force-reinstall "git+https://github.com/Community-Access/quill-glow-core.git@main"
python -m pip install -e desktop/
python -m pip install -e web[dev]

- name: Run feature flags migration
run: python web/tools/run_migrate.py

- name: Run web tests
run: python -m pytest web/ -q
- name: Run focused feature-flag regression tests
run: |
python -m pytest web/tests/test_admin_flags.py -q
python -m pytest web/tests/test_ai_feature_gates.py -q
env:
# ensure sqlite backend for audit tests
FEATURE_FLAGS_BACKEND: sqlite
25 changes: 24 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# GLOW

GLOW stands for **Guided Layout & Output Workflow**.
Expand Down Expand Up @@ -124,6 +124,27 @@
- Produces PowerShell scripts for configuring Word document styles
- Detects and uses external tools (markdownlint, Pandoc) when available

## Shared core architecture (retrofit baseline)

GLOW now includes a shared service package at:

- `desktop/src/acb_large_print_core/`

This package is the canonical dispatch layer for **audit**, **fix**, and **MarkItDown conversion** across CLI, desktop, and web surfaces.

Current shared entry points:

- `acb_large_print_core.services.audit_by_extension(...)`
- `acb_large_print_core.services.fix_by_extension(...)`
- `acb_large_print_core.services.convert_to_markdown(...)`
- `acb_large_print_core.versions.get_component_versions()`

Design intent:

- Keep UX-specific behavior in each interface (web routes, GUI dialogs, CLI output formatting).
- Keep business logic dispatch and component-version provenance in shared core APIs.
- Enable future extraction to an external reusable package without changing app-layer behavior.

## Recent Fix Workflow Updates (April 2026)

- Fix Results now suppresses `ACB-FAUX-HEADING` from post-fix scoring when heading detection is explicitly disabled, and shows a "Suppressed by your settings" note for transparency.
Expand Down Expand Up @@ -169,6 +190,7 @@
announcement.md Press release / announcement
prd.md Canonical web app product requirements document
deployment.md Step-by-step server deployment guide
shared-core-retrofit.md Shared service-core architecture and migration status
samples/
*.md Example Markdown source files
*.html Converted HTML output files
Expand All @@ -181,7 +203,8 @@
Dockerfile Production container image
docker-compose.yml Compose file for deployment
desktop/ Desktop CLI + GUI (Python)
src/acb_large_print/ Core library (canonical source of truth)
src/acb_large_print_core/ Shared service core (canonical dispatch layer)
src/acb_large_print/ App-layer CLI/GUI + format engines
office-addin/ Office.js Word Add-in (TypeScript)
src/ TypeScript port of audit/fix/template
vendor/ Vendored third-party source
Expand Down
1 change: 1 addition & 0 deletions desktop/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ classifiers = [
"Topic :: Adaptive Technologies",
]
dependencies = [
"quill-glow-core>=0.1.0",
"python-docx>=1.2.0",
"mammoth>=1.11.0,<1.12.0",
"markitdown[all]>=0.1.5",
Expand Down
1 change: 1 addition & 0 deletions desktop/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Core dependencies
quill-glow-core>=0.1.0
python-docx>=1.1.0
mammoth>=1.11.0,<1.12.0
markitdown[all]>=0.1.5
Expand Down
12 changes: 10 additions & 2 deletions desktop/src/acb_large_print/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
"""ACB Large Print Tool -- audit, fix, and template Word documents for ACB compliance."""
"""ACB Large Print Tool -- audit, fix, and convert accessible documents."""

from __future__ import annotations

__version__ = "5.0.0"
__app_name__ = "ACB Large Print Tool"
__author__ = "BITS (Blind Information Technology Solutions)"

try:
from .version import get_version as _get_version

__version__ = _get_version()
except Exception:
__version__ = "unknown"
95 changes: 20 additions & 75 deletions desktop/src/acb_large_print/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -713,28 +713,14 @@ def _build_parser() -> argparse.ArgumentParser:


# ── Supported file extensions ─────────────────────────────────────────
SUPPORTED_EXTENSIONS = {".docx", ".xlsx", ".pptx", ".epub"}
SUPPORTED_EXTENSIONS = {".docx", ".xlsx", ".pptx", ".md", ".pdf", ".epub"}


def _audit_by_extension(file_path: Path):
"""Dispatch to the correct auditor based on file extension."""
ext = file_path.suffix.lower()
if ext == ".xlsx":
from .xlsx_auditor import audit_workbook
from quill_glow_core import audit_by_extension

return audit_workbook(file_path)
elif ext == ".pptx":
from .pptx_auditor import audit_presentation

return audit_presentation(file_path)
elif ext == ".epub":
from .epub_auditor import audit_epub

return audit_epub(file_path)
else:
from .auditor import audit_document

return audit_document(file_path)
return audit_by_extension(file_path)


def _resolve_list_indent(args: argparse.Namespace) -> tuple[float, float]:
Expand Down Expand Up @@ -819,61 +805,17 @@ def _fix_by_extension(

Returns (output_path, total_fixes, fix_records, post_audit, warnings).
"""
ext = file_path.suffix.lower()
if ext == ".xlsx":
from .xlsx_auditor import audit_workbook

post_audit = audit_workbook(file_path)
return (
file_path,
0,
[],
post_audit,
[
"Excel workbooks cannot be auto-fixed yet. "
"Review the audit findings and fix them manually in Excel."
],
)
elif ext == ".pptx":
from .pptx_auditor import audit_presentation

post_audit = audit_presentation(file_path)
return (
file_path,
0,
[],
post_audit,
[
"PowerPoint presentations cannot be auto-fixed yet. "
"Review the audit findings and fix them manually in PowerPoint."
],
)
elif ext == ".epub":
from .epub_auditor import audit_epub
from quill_glow_core import fix_by_extension

post_audit = audit_epub(file_path)
return (
file_path,
0,
[],
post_audit,
[
"ePub files cannot be auto-fixed yet. "
"Review the audit findings and fix them in your ePub editor."
],
)
else:
from .fixer import fix_document

return fix_document(
file_path,
output_path=output_path,
bound=bound,
list_indent_in=list_indent_in,
list_hanging_in=list_hanging_in,
para_indent_in=para_indent_in,
first_line_indent_in=first_line_indent_in,
)
return fix_by_extension(
file_path,
output_path=output_path,
bound=bound,
list_indent_in=list_indent_in,
list_hanging_in=list_hanging_in,
para_indent_in=para_indent_in,
first_line_indent_in=first_line_indent_in,
)


def _cmd_audit(args: argparse.Namespace) -> int:
Expand All @@ -885,9 +827,10 @@ def _cmd_audit(args: argparse.Namespace) -> int:
return 1

ext = args.file.suffix.lower()
if ext not in (".docx", ".xlsx", ".pptx", ".epub"):
if ext not in SUPPORTED_EXTENSIONS:
print(
f"Error: Unsupported file type '{ext}'. Use .docx, .xlsx, .pptx, or .epub.",
"Error: Unsupported file type "
f"'{ext}'. Use .docx, .xlsx, .pptx, .md, .pdf, or .epub.",
file=sys.stderr,
)
return 1
Expand Down Expand Up @@ -927,7 +870,8 @@ def _cmd_fix(args: argparse.Namespace) -> int:
ext = args.file.suffix.lower()
if ext not in SUPPORTED_EXTENSIONS:
print(
f"Error: Unsupported file type '{ext}'. Use .docx, .xlsx, .pptx, or .epub.",
"Error: Unsupported file type "
f"'{ext}'. Use .docx, .xlsx, .pptx, .md, .pdf, or .epub.",
file=sys.stderr,
)
return 1
Expand Down Expand Up @@ -1291,7 +1235,8 @@ def _print_wcag_language_report(report) -> None:

def _cmd_convert(args: argparse.Namespace) -> int:
"""Execute the convert command."""
from .converter import CONVERTIBLE_EXTENSIONS, convert_to_markdown
from .converter import CONVERTIBLE_EXTENSIONS
from quill_glow_core import convert_to_markdown
from .wcag_language import analyze_text_for_wcag_language

if not args.file.exists():
Expand Down
7 changes: 7 additions & 0 deletions desktop/src/acb_large_print/cli_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@


def main() -> None:
try:
from quill_glow_core import configure_default_services as _configure_shared_core_default

_configure_shared_core_default()
except Exception:
pass

from acb_large_print.cli import main as cli_main

sys.exit(cli_main(force_cli=True))
Expand Down
23 changes: 23 additions & 0 deletions desktop/src/acb_large_print_core/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"""Shared core services for GLOW audit/fix/convert workflows."""

from .services import (
CONVERTIBLE_EXTENSIONS,
MARKITDOWN_AUDIO_EXTENSIONS,
SUPPORTED_AUDIT_EXTENSIONS,
SUPPORTED_FIX_EXTENSIONS,
audit_by_extension,
convert_to_markdown,
fix_by_extension,
)
from .versions import get_component_versions

__all__ = [
"CONVERTIBLE_EXTENSIONS",
"MARKITDOWN_AUDIO_EXTENSIONS",
"SUPPORTED_AUDIT_EXTENSIONS",
"SUPPORTED_FIX_EXTENSIONS",
"audit_by_extension",
"convert_to_markdown",
"fix_by_extension",
"get_component_versions",
]
Loading
Loading