unillett/variance-inputThis project automates and provides an admin UI to produce the legacy
Variance publish files. Editors can upload textual versions, generate
Medite comparisons, manage facsimiles, and assemble the published asset
bundle with pagination markers derived from _lignes files. In practice
this means:
_lignes, facsimiles, and comparison manifests.The project is split into:
http://localhost:8080 to reach Laravel (/admin), legacy Variance (/),
and Medite endpoints from a single port.Detailed documentation:
descr/architecture.md,descr/workflow.md,descr/facsimiles.md,descr/queues_jobs.md,descr/api_endpoints.md,descr/deployment_notes.md.
Clone & Boot
bashgit clone [***] cd variance-input docker compose up -d --build
This brings up:
laravel (admin web app at http://localhost:8080/admin via the proxy)medite (Flask API on http://localhost:5000)laravel-queue (queue worker for pagination & facsimile jobs)Environment
laravel/.env is committed for development; tweak DB or queue
settings if needed.php artisan queue:work --queue=facsimiles,page-markers, so
pagination and facsimile jobs are processed automatically.Initial setup (first run)
bashdocker compose exec laravel php artisan migrate docker compose exec laravel php artisan db:seed # optional fixtures
Upload version – “Téléverser une version” in the Versions card
generates the TEI container under storage/app/public/uploads/versions/.
Attach pagination (_lignes) – Drop the _lignes text file; the queue
produces storage/app/private/pagination/{version}.json sidecars that
describe every pagination marker.
Import & curate facsimiles – Upload batches of images (optional) and use the Fac-similés manifest manager to choose which files belong to each comparison (JSON manifests stay in sync with the comparisons table pills).
Run Medite – Launch a comparison from the Comparaisons card. Medite
writes its XHTML/TEI components to
storage/app/public/uploads/{author}/{work}/comparisons/{id}.
Inject pagination – Use “Injecter la pagination” per role (source/target)
to merge the _lignes markers into the Medite XHTML files.
Export legacy bundle – Click “Exporter” to download a zip containing the published comparison folder plus only the facsimiles referenced in the JSON manifests (source/target).
Publish – Optional. Keep the comparison synced to the legacy public tree via the “Publier” toggle.
| Purpose | Command |
|---|---|
| Tail Laravel queue logs | docker compose logs -f laravel-queue |
| Run queue worker manually | docker compose exec laravel php artisan queue:work --queue=page-markers --stop-when-empty |
| Artisan shell | docker compose exec laravel php artisan tinker |
| Composer install (Laravel) | docker compose exec laravel composer install |
| NPM build (if needed) | docker compose exec laravel npm run build |
├── docker-compose.yml ├── descr/ # Developer documentation (not committed) ├── laravel/ # Admin application (PHP/Laravel) │ ├── app/ │ ├── routes/ │ └── ... ├── medite/ # Flask + Celery Medite runner │ └── app/variance/... ├── variance/ # Legacy PHP frontend (read-only in dev) └── variance_data/ # Runtime uploads & generated outputs
Upload a version (Versions card)
.txt files (≤ 8 MB, text/plain).VersionController::store normalises text (UTF‑8, whitespace collapse),
inserts <lb/>, wraps it in a TEI skeleton, and writes both the raw text
and TEI XML to storage/app/public/uploads/versions/{base}.{txt,xml} (with
public mirrors under public/uploads/...).versions row is created with the generated folder slug.Upload _lignes
storage/app/private/lignes/{version_id}.txt.ApplyLignesJob parses the _lignes entries, matches them against the TEI
text, and stores a pagination sidecar JSON at
storage/app/private/pagination/{version_id}.json containing
{ char_index, page, image_code, phrase, context }.storage/app/tmp/pager/{version_id}.json
so the UI shows when the sidecar is ready.Curate facsimiles & manifests
img_*) and generate thumbnails.storage/app/public/uploads/{author}/{work}/{version}/images_{role}_{author--work--comparison}.json
and reflected immediately in the comparisons table (“JSON” pill).Run Medite
MediteController::runMedite calls the
Flask service which executes the Celery task./app/uploads/{author}/{work}/comparisons/{comparison_id} which Laravel
mirrors into storage/app/public/uploads/{author}/{work}/comparisons/{id}.Inject pagination markers
ComparisonController::applyPageMarkers
ensures both versions have sidecars, marks the comparison queued, and
dispatches InjectComparisonPaginationJob.storage/app/private/pagination/{version}.json, injects
<span class="page-marker"> tags into source.xhtml / target.xhtml at
the recorded offsets, and saves the updated files.storage/app/tmp/pager/comparisons/{comparison_id}.json; the UI polls this
endpoint to show queued → running → done per role (source/target).Export the legacy bundle
Optional publication
public/uploads/{author}/{work}/{comparison_folder} for the legacy site.ApplyLignesJob, InjectComparisonPaginationJob) run on
the page-markers queue; facsimile processing uses the facsimiles queue.laravel-queue container runsphp artisan queue:work --queue=facsimiles,page-markers.docker compose exec laravel php artisan queue:work --queue=page-markers --stop-when-empty.| Artefact | Location |
|---|---|
| Uploaded TXT | storage/app/public/uploads/versions/{folder}.txt |
| TEI version | storage/app/public/uploads/versions/{folder}.xml |
_lignes raw file | storage/app/private/lignes/{version_id}.txt |
| Pagination sidecar | storage/app/private/pagination/{version_id}.json |
| Facsimile manifest JSON | storage/app/public/uploads/{author}/{work}/{version}/images_{role}_{author--work--comparison}.json |
| Version progress | storage/app/tmp/pager/{version_id}.json |
| Comparison progress | storage/app/tmp/pager/comparisons/{comparison_id}.json |
| Medite outputs (XHTML/TEI) | storage/app/public/uploads/{author}/{work}/comparisons/{id} |
| Published comparison (optional) | public/uploads/{author}/{work}/{comparison_folder} |
| Facsimile images (draft) | storage/app/public/uploads/{author}/{work}/{version}/ |
| Exported legacy zip | Downloaded on demand via /comparisons/{id}/export |
For deeper dives check:
laravel/app/Services/PageMarkerService.phplaravel/app/Jobs/ApplyLignesJob.phplaravel/app/Jobs/InjectComparisonPaginationJob.phpmedite/app/flask_app.pyVariance & Medite Integration is developed by SIER (Service Infrastructure Enseignement et Recherche), part of the Faculty of Arts at the University of Lausanne (<[***]>). Licensing is currently under internal review; this repository is private and no redistribution rights are granted at this stage.
Happy comparing! :)
探索更多轩辕镜像的使用方法,找到最适合您系统的配置方式
通过 Docker 登录认证访问私有仓库
在 Linux 系统配置镜像服务
在 Docker Desktop 配置镜像
Docker Compose 项目配置
Kubernetes 集群配置 Containerd
K3s 轻量级 Kubernetes 镜像加速
VS Code Dev Containers 配置
MacOS OrbStack 容器配置
在宝塔面板一键配置镜像
Synology 群晖 NAS 配置
飞牛 fnOS 系统配置镜像
极空间 NAS 系统配置服务
爱快 iKuai 路由系统配置
绿联 NAS 系统配置镜像
QNAP 威联通 NAS 配置
Podman 容器引擎配置
HPC 科学计算容器配置
ghcr、Quay、nvcr 等镜像仓库
无需登录使用专属域名
需要其他帮助?请查看我们的 常见问题Docker 镜像访问常见问题解答 或 提交工单
免费版仅支持 Docker Hub 访问,不承诺可用性和速度;专业版支持更多镜像源,保证可用性和稳定速度,提供优先客服响应。
专业版支持 docker.io、gcr.io、ghcr.io、registry.k8s.io、nvcr.io、quay.io、mcr.microsoft.com、docker.elastic.co 等;免费版仅支持 docker.io。
当返回 402 Payment Required 错误时,表示流量已耗尽,需要充值流量包以恢复服务。
通常由 Docker 版本过低导致,需要升级到 20.x 或更高版本以支持 V2 协议。
先检查 Docker 版本,版本过低则升级;版本正常则验证镜像信息是否正确。
使用 docker tag 命令为镜像打上新标签,去掉域名前缀,使镜像名称更简洁。
来自真实用户的反馈,见证轩辕镜像的优质服务