Repository navigation
Releases
MD.Scribe 3.5.0 — Loom
Mermaid 12 comes to the docs, and a repair that finally reaches the page.
Highlights
Mermaid 11.17.2 → 12.3.0. Authors get the 12 features in a plain fenced block:
- edge IDs with animation —
A e1@--> B, thene1@{ animate: true }ore1@{ animation: fast }; - step-by-step flow animation (12.3+) —
e1@{ step: 1 }, plusflowchart.stepDurationandflowchart.stepNumbers; - the circle and cross edge markers —
A ---o B,A ---x B; - the
@{ shape: … }family — manual-file, cylinder, document, paper-tape and the rest.
The 12 defaults are deliberately not adopted: Mermaid 12 draws flowcharts with the redux-color
theme, the neo look and an ELK layout, which would restyle every existing diagram without anyone
asking. look: 'classic' and layout: 'dagre' are pinned instead. Measured against 11.17.2 on the
same document: a sequence diagram keeps its geometry exactly (-50 -10 514 451 on both), a flowchart
is laid out with 12's wider spacing (0 0 624.66 140 → 0 0 837.88 140, same height, still scaled
by useMaxWidth). Dropping those two keys adopts the new defaults.
The vendored bundle grows from 3.5 MB to 5.5 MB raw (0.98 → 1.58 MB gzip) and is still injected only
on pages that contain a diagram.
Fixed
- A repaired diagram was parsed unrepaired. The server writes the repaired source into the
<pre>body and the author's text intodata-mermaid-sourcefor the copy control, but the loader
read the attribute — so every auto-repair was discarded: the badge announced a repair and Mermaid
rejected the original. Reproduced on 11.17.2 as well, so the defect predates this release. A node
label with unquoted parentheses now renders with its repair applied, and a test pins the DOM
contract the client relies on. - The vendor rebuild dropped the icon fallback.
node build.mjs --vendorand
node generate-icons.mjsboth writesrc/View/Icons.php, but only the second added the
circle-alertentryIcons::svg()falls back to. The class raisedUndefined array keyand drew
an empty<svg>for any name outsideicons.json. Both generators now apply the same rule;
tests/Unit/IconsTest.phpfails if the fallback goes missing.
Changed
league/commonmark2.10.3 → 2.10.7, KaTeX 0.16.47 → 0.19.1, lucide 0.469 → 0.577, tailwind 4.3.5,
esbuild 0.28.2,actions/checkout@v7,actions/setup-node@v7.- Dependabot runs monthly with a two-pull-request cap per ecosystem, and the two majors that still
need a deliberate decision (lucide 1.x, phpunit 13.x) are ignored by version — not by update type,
becauseignorealso silences security updates. docs/development.mdstates what is vendored: which packages are installed at release time, which
files travel inside the archive, and that the updater's release check is the only outbound request.
Verification of this release
vendor/bin/phpunit --no-coverage→ OK (218 tests, 688 assertions, 1 skipped)phpstan analyselevel 6 → no errors;Invoke-ProjectDoctrine.ps1→ 12 checks, 0 errors, 0 warnings- the archive was verified against its own manifest: 979 entries, 979 matching sha256, nothing missing
- the extracted archive was served and exercised:
/,?page=browser,?page=themes,
?api=search&q=markdown,?file=nope.md→ 404,?api=manifest→application/manifest+json,
and the page reports version 3.5.0
Install
unzip MD.Scribe-3.5.0.zip -d /var/www/docs
cd /var/www/docs && cp .md.ini.example .md.ini # or let the first request create itPoint the docroot at public/. The archive ships vendor/, so no Composer on the host; PHP 8.5 is
the floor and CI runs 8.5 only.
MD.Scribe 3.4.4 — Keystone
3.4.4 “Keystone” — patch
Two defects found by looking at the rendered page rather than at HTTP status codes.
Fixed
- Wide tables were clipped at the column edge. Document tables were drawn at their unwrapped content width (
width: max-content) withwhite-space: nowrapin the header row, so a table wider than the reading column ran past it and the text was cut off mid-word — with no visible hint that it scrolls. Measured on a real document at 1512px: a 736px column held an 896px table. Tables now take the column width and wrap their cells; the scroll container stays as a fallback for genuinely wide tables. After the fix the same table measures 734px in a 736px column with zero clipped cells. - The documented MIME fix could break a whole vhost.
docs/installation.mdadvisedtypes { application/manifest+json webmanifest; }, but atypesblock replaces the inherited MIME table (and Debian'smime.typesis itself wrapped in one). Applied on nginx 1.24, that served every.css,.jsand.svgasapplication/octet-stream: the site rendered unstyled and the client’s whole virtual host was affected. Both guides now say plainly not to use atypesblock, map only the extension, and check the whole table afterwards.
Changed
- The web app manifest is served by the application (
?api=manifest) withContent-Type: application/manifest+json, and the layout links to that instead of the staticpublic/manifest.webmanifest. The media type no longer depends on the host, and sub-directory installs get a correctscope/start_url(e.g./docs/). The static file still ships as a fallback.
Tests
214 tests, 664 → 679 assertions. New guards: TypographyAssetsTest keeps the built typography.css byte-identical to its source and forbids the clipping rules; ManifestEndpointTest pins the media type, the document shape, the sub-directory scope and the route/layout wiring.
Install
unzip MD.Scribe-3.4.4.zip -d /var/www/docs
chown -R www-data:www-data /var/www/docs/storageFull changelog: CHANGELOG.md
MD.Scribe v3.1.0 - Aurora (PHP 8.3 Markdown docs: viewer, editor, admin panel)
MD.Scribe v3.1.0 — "Aurora"
Self-hosted documentation for a folder of Markdown files — with an editor, an admin panel,
full-text search and zero CDN dependencies. PHP 8.3, no database, no build step.
First release under the name MD.Scribe. Until 3.0.1 this project was published as
MD.Viewer; that repository still exists and is untouched. Same code, same contracts, new name
and new home — 3.1.0 is a rename release, not a rewrite: application behaviour is unchanged.
Install
Download MD.Scribe-3.1.0.zip below — it bundles vendor/, so Composer is not needed:
unzip MD.Scribe-3.1.0.zip -d /var/www/docs
chmod -R u+w /var/www/docs/storage
# docroot: /var/www/docs/public (recommended) or the project rootFrom a clone instead:
git clone https://github.com/paulmann/MD.Scribe.git /var/www/docs
cd /var/www/docs && composer install --no-dev --optimize-autoloaderOpen admin.php for first-run setup; the viewer works before that. Requirements: PHP >= 8.3
with mbstring, dom, libxml, json (curl + phar + zip recommended for the updater and
backup archives).
Why the name changed
The old name described only the reading half of what v3 became. This is a viewer, an editor, an
admin panel, a publisher and a search index — "Scribe" covers the whole where "Viewer" covered one
part. The practical numbers, measured on GitHub (in:name): 750 repositories match md-viewer and
686 match mdview, against 24 for md-scribe — which was also free on npm, free as a .dev
domain and unused in this account.
What is in 3.1.0
| Area | Change |
|---|---|
| Naming | Version::REPO / RAW_BASE / API_BASE and userAgent() point at paulmann/MD.Scribe |
| User-visible text | Window titles, admin header and login page, <meta name="generator">, footer, X-Powered-By, default SITE_NAME, console banner, bootstrap error messages |
| Packages | composer.json is now mdscribe/md-scribe; composer.lock content-hash recomputed and verified with composer validate --check-lock |
| Docs | README, docs/, content/ pages, LICENSE, and the deployment samples (Docker, nginx, Caddy, php.ini) |
| Manifest | config/manifest.json rebuilt: 921 files, app MD.Scribe, version 3.1.0 |
Fixed in the same release
The self-updater pinned a product name when unpacking a release archive — it looked for
glob('.../MD.Viewer-*'). An archive named after the repository (MD.Scribe-main/) would have
been rejected with "does not look like a release". It now accepts any <name>-<ref> directory
containing config/manifest.json, with a fallback for a flat archive.
.gitignore did not ignore vendor/ at all, so git add -A would have committed 723 dependency
files. Added as /vendor/; reproducibility is kept through the committed composer.lock.
Deliberately unchanged
- The PHP namespace
MdViewer\. It is an internal identifier shared by every class insrc/;
renaming it would touch every file for no user-visible gain and would break code that type-hints
these classes. - Every v2 compatibility contract:
md.php?file=…,&download=1,updater.php?update=?restore=,
the machine-API envelope{ok, action, version, steps, files, conflicts, errors}, per-directory
.md.inilayering,mdv_feat_*cookies, and the 14-layer path validator. - Historical references to v2 still read
MD.Viewer v2 …where they describe the previous
product (upgrade guide, changelog, compatibility notes). v2 was MD.Viewer. - Upgrading in place from 3.0.x works: the tracked file list and the API envelope are unchanged,
and.md.inikeys are the same —SITE_NAMEkeeps whatever value the installation already has.
Verified
php -lacross 110 PHP files outsidevendor/: 0 errors;node --checkon both committed
bundles: clean.- Served with PHP 8.5.0: home, themes catalogue and search API answer 200 and report
MD.Scribe 3.1.0 in<meta generator>;/admin.phpanswers Setup · MD.Scribe Admin;
a missing document answers 404;updater.php?action=status&format=jsonanswers
{"ok":false,…,"error":"unauthorized"}without a key — the v2 contract intact. - The release archive was unpacked and served before publishing;
Version::REPOinside it points
at the new repository. - PHPUnit and PHPStan were not run on the build machine: its
vendor/is a--no-devinstall,
so neither tool is present..github/workflows/ci.ymlruns lint, PHPStan level 6 and PHPUnit on
PHP 8.3 and 8.4 for every push.
Documentation
The wiki is being published at https://github.com/paulmann/MD.Scribe/wiki (22 pages: install
and deployment, the complete .md.ini reference, the Markdown extensions matrix, the self-updater
and machine-API guides, and the security hardening guide).
Full changelog: CHANGELOG.md