diff --git a/README.md b/README.md index 4b2c858..a29f2ec 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ $label = Markdown::github()->toInlineHtml('Install **Alto**'); ``` See [Installation](docs/installation.md), [HTML](docs/conversion/html.md), -[Profiles](docs/documents/profiles.md), and [Security](docs/engine/security.md) to choose the +[Profiles](docs/documents/profiles.md), and [Security](docs/security.md) to choose the right language and HTML policy. ## Open a document when you need more @@ -118,7 +118,7 @@ if ($file->hasChanges()) { ``` Source ranges use original byte offsets. `toMarkdown()` preserves unchanged -bytes, line endings, and a UTF-8 BOM. Alto rejects an edit when it cannot apply +bytes, line endings, and a UTF-8 BOM. ALTO rejects an edit when it cannot apply it safely under the documented V1 contract. The documentation covers this in more depth: [Queries](docs/documents/queries.md) @@ -133,15 +133,26 @@ to enforce content and style policies. Trusted extensions add custom blocks, leaf inlines, native and link-aware HTML decoration, document render projections, lint, formatting, metrics, heading-level projection, permalinks, and generated tables of contents through -compiled contracts. Read [Extensions](docs/extensions/index.md) and +compiled contracts. Read [Extensions](docs/extensions.md) and [Compatibility](docs/extensions/compatibility.md) for the extension contracts -and migration notes from historical Alto CommonMark extensions. +and migration notes from historical ALTO CommonMark extensions. ## Documentation -- [Documentation index](docs/index.md): browse the complete guide set. -- [API reference](docs/api/index.md) and [Exceptions](docs/api/exceptions.md): the - public surface and recovery contracts. +- [Installation](docs/installation.md): install the package and verify the runtime. +- [Getting started](docs/getting-started.md): render and inspect a document. +- [Conversion](docs/conversion.md): produce HTML or Markdown output. +- [Documents](docs/documents.md): query, measure, and edit source-backed content. +- [Quality](docs/quality.md): lint, fix, and format Markdown. +- [Extensions](docs/extensions.md): choose bundled capabilities or create one. +- [Syntax](docs/syntax.md): add authoring syntax. +- [Rendering](docs/rendering.md): control document and HTML output. +- [Resources](docs/resources.md): resolve imported, included, and embedded content. +- [Security](docs/security.md): define HTML, input, and resource boundaries. +- [Errors](docs/errors.md): recover from parse, edit, resource, and file failures. +- [Performance](docs/performance.md): select and measure the processing path. +- [Compliance](docs/compliance.md): review supported Markdown specifications. +- [Documentation index](docs/index.md): browse every guide. ## Contributing diff --git a/docs/api/documents.md b/docs/api/documents.md deleted file mode 100644 index edeb978..0000000 --- a/docs/api/documents.md +++ /dev/null @@ -1,39 +0,0 @@ -# Documents API - -Factories create one of two document contracts: an in-memory -`MarkdownDocument` or a path-backed `MarkdownFile`. - -## MarkdownFactory - -| Method | Return | Purpose | -| --- | --- | --- | -| `profile()` | `Profile` | Return the compiled language profile. | -| `with(ExtensionInterface ...$extensions)` | `self` | Return a factory with trusted extensions. | -| `fromString(string $source, ?ParseOptions $options = null)` | `MarkdownDocument` | Parse an in-memory document. | -| `open(string $path, ?ParseOptions $options = null)` | `MarkdownFile` | Read and parse a file. | -| `toHtml(...)` | `string` | Render block Markdown directly. | -| `toInlineHtml(...)` | `string` | Render an inline fragment directly. | -| `builder()` | `MarkdownBuilder` | Start a document builder. | -| `fragment()` | `MarkdownFragmentBuilder` | Start a fragment builder. | - -## MarkdownDocument - -The document exposes its `profile()` and `model()`, typed accessors, `query()`, -`ensure()`, `lint()`, `fix()`, `format()`, and `stats()`. Output methods are -`toMarkdown()` and `toHtml()`. `hasChanges()` and `diff()` inspect pending -source edits. - -```php -$document = $factory->fromString($source); - -if ($document->hasChanges()) { - echo $document->diff()->toUnifiedString(); -} -``` - -## MarkdownFile - -`MarkdownFile` adds `path()`, `save()`, and `saveAs()`. Saving may reject a -changed, missing, symbolic-link, or unauthorized target. See -[Editing](editing.md) for persistence contracts and [Exceptions](exceptions.md) -for recoverable failures. diff --git a/docs/api/editing.md b/docs/api/editing.md deleted file mode 100644 index 5753b75..0000000 --- a/docs/api/editing.md +++ /dev/null @@ -1,38 +0,0 @@ -# Editing API - -Editing APIs either build new Markdown or record validated patches against an -existing source. - -## Builders - -`MarkdownBuilder` provides `heading()`, `h1()`, `h2()`, `paragraph()`, -`codeBlock()`, `unorderedList()`, `orderedList()`, `blockquote()`, and -`thematicBreak()`. Finish with `document()` or `toMarkdown()`. - -```php -$markdown = $factory->builder() - ->h1('Guide') - ->paragraph('Start here.') - ->toMarkdown(); -``` - -`MarkdownFragmentBuilder` creates content intended for insertion rather than a -standalone document. - -## Pending patches - -Typed handle mutations update the in-memory model immediately and add source -operations to the document journal. `toMarkdown()` lowers pending operations; -`diff()` returns a `Diff` whose `toUnifiedString()` method is suitable for a -preview. - -## SaveOptions - -`MarkdownFile::save()` replaces the opened file. `saveAs()` targets another -path. `SaveOptions` controls compare-before-write and related persistence -policies. Atomic replacement, permission preservation, line-ending retention, -and conflict checks remain available through the file contract. - -Catch the file exceptions described in [Exceptions](exceptions.md) at the -application boundary. See [Editing](../documents/editing.md) for complete -source-preserving workflows. diff --git a/docs/api/extensions.md b/docs/api/extensions.md deleted file mode 100644 index ec4373b..0000000 --- a/docs/api/extensions.md +++ /dev/null @@ -1,31 +0,0 @@ -# Extensions API - -An extension has a stable name and implements only the public capability -interfaces required by its behavior. - -| Capability | Public contract | -| --- | --- | -| Syntax | `BlockExtensionInterface`, `InlineExtensionInterface` | -| HTML | `HtmlDecoratorExtensionInterface` | -| Projection | `DocumentTransformExtensionInterface` | -| Lint | `LintExtensionInterface` | -| Format | `FormatterExtensionInterface` | -| Statistics | `StatsExtensionInterface` | -| Resources | `ResourceResolver` | - -Definitions, contexts, and value objects under `Alto\Markdown\Extension` are -public unless marked `@internal`. Parser tapes, compact node IDs, compiler -caches, and internal dispatch objects are not extension contracts. - -```php -$extended = $factory->with($firstExtension, $secondExtension); -``` - -The returned factory is immutable. Extension compilation rejects invalid -names, duplicate or incompatible definitions, and unavailable parser triggers -before processing a document. - -Read [Extension points](../extensions/extension-points.md) to choose a contract, -[Custom extension](../extensions/custom.md) for an implementation, and -[Compatibility](../extensions/compatibility.md) before declaring a package -version range. diff --git a/docs/api/index.md b/docs/api/index.md deleted file mode 100644 index 95eec51..0000000 --- a/docs/api/index.md +++ /dev/null @@ -1,32 +0,0 @@ -# API reference - -The public API is organized by application task. Types marked `@internal` in -source are not part of the package contract. - -## Entry points - -`Markdown::commonmark()`, `Markdown::gfm()`, and `Markdown::github()` return a -`MarkdownFactory` for the selected syntax profile. A factory can render a -string directly, create a document, open a file, start a builder, or install -trusted extensions. - -```php -use Alto\Markdown\Markdown; - -$factory = Markdown::github(); -$document = $factory->fromString("# Guide\n"); -``` - -## Reference domains - -- [Documents](documents.md): `MarkdownFactory`, `MarkdownDocument`, and - `MarkdownFile`. -- [Nodes](nodes.md): headings, sections, links, images, code, and front matter. -- [Queries](queries.md): collections, generic selectors, and statistics. -- [Editing](editing.md): builders, source patches, diffs, and persistence. -- [Extensions](extensions.md): profiles and public extension capabilities. -- [Exceptions](exceptions.md): argument, parse, render, resource, and file - failures. - -Use the guide pages for decisions and workflows. These reference pages define -callable contracts and observable boundaries. diff --git a/docs/api/queries.md b/docs/api/queries.md deleted file mode 100644 index 6703b65..0000000 --- a/docs/api/queries.md +++ /dev/null @@ -1,37 +0,0 @@ -# Queries API - -Documents provide typed accessors for common questions and `MarkdownQuery` for -core or extension node kinds. - -## Typed accessors - -`title()`, `headings()`, `section()`, `sections()`, `links()`, `images()`, -`codeBlocks()`, and `frontMatter()` return typed handles or lazy collections. - -## Collection - -`Collection` implements `Countable`, `IteratorAggregate`, and lazy operations: - -| Method | Result | -| --- | --- | -| `first()` | First item or `null`. | -| `count()` | Number of matching items. | -| `all()` | Materialized result array. | -| `filter()` | Derived lazy collection. | - -## MarkdownQuery - -`kind()` adds an OR node-kind selector. `where()` adds an AND predicate. -`get()` returns matching handles in source order. - -```php -$tablesAndParagraphs = $document->query() - ->kind('paragraph') - ->kind('gfm:table') - ->get(); -``` - -`stats()` returns `DocumentStats`, including headings, sections, links, images, -code, words, reading time, tables, and extension metrics. See -[Queries](../documents/queries.md) and [Statistics](../documents/statistics.md) -for selection and counting semantics. diff --git a/docs/engine/compliance.md b/docs/compliance.md similarity index 99% rename from docs/engine/compliance.md rename to docs/compliance.md index ddfb7be..cc0f144 100644 --- a/docs/engine/compliance.md +++ b/docs/compliance.md @@ -25,7 +25,7 @@ The published package carries the conformance fixtures and runs them with the rest of the suite: ```bash -composer tests +composer test ``` The full quality gate also runs static analysis and style checks on top of the diff --git a/docs/conversion.md b/docs/conversion.md new file mode 100644 index 0000000..3d61bd0 --- /dev/null +++ b/docs/conversion.md @@ -0,0 +1,21 @@ +# Conversion + +Convert Markdown directly when the application only needs one output. Open a +document first when the same parsed structure will also be queried, edited, +linted, or rendered more than once. + +```php +use Alto\Markdown\Markdown; + +$html = Markdown::github()->toHtml("# Guide\n\nRead **carefully**.\n"); +``` + +## Output + +- [HTML](conversion/html.md): render blocks or inline fragments with an explicit + HTML policy. +- [Markdown](conversion/markdown.md): preserve original source or produce + normalized Markdown. + +Direct conversion avoids retaining a document object. Document output preserves +unchanged source bytes until an operation explicitly normalizes them. diff --git a/docs/conversion/html.md b/docs/conversion/html.md index d500ccf..f7bfb35 100644 --- a/docs/conversion/html.md +++ b/docs/conversion/html.md @@ -46,5 +46,5 @@ The default policy escapes raw HTML and filters unsafe URL schemes. Pass a `RenderOptions` value only when the application has an explicit reason to use another policy. -Read [Security](../engine/security.md) before enabling authored HTML. Continue +Read [Security](../security.md) before enabling authored HTML. Continue with [Markdown](markdown.md) when output must remain Markdown. diff --git a/docs/documents.md b/docs/documents.md new file mode 100644 index 0000000..0c0c51b --- /dev/null +++ b/docs/documents.md @@ -0,0 +1,40 @@ +# Documents + +A document retains the parsed model and original source. Use it when an +application needs to inspect, reuse, measure, or change Markdown without +rewriting unrelated content. + +```php +use Alto\Markdown\Markdown; + +$document = Markdown::github()->fromString("# Guide\n\nRead the docs.\n"); +$title = $document->title()?->text(); +``` + +`$title` is `Guide`. + +## Guides + +- [Profiles](documents/profiles.md): choose CommonMark, GFM, or GitHub syntax. +- [Queries](documents/queries.md): find headings, sections, links, and code. +- [Statistics](documents/statistics.md): compute an immutable document summary. +- [Editing](documents/editing.md): make source-preserving changes and save files. +- [Nodes](documents/nodes.md): inspect and mutate typed handles. + +## Entry points + +| Method | Return | Purpose | +| --- | --- | --- | +| `profile()` | `Profile` | Return the compiled language profile. | +| `with(ExtensionInterface ...$extensions)` | `self` | Return a factory with trusted extensions. | +| `fromString(string $source, ?ParseOptions $options = null)` | `MarkdownDocument` | Parse an in-memory document. | +| `open(string $path, ?ParseOptions $options = null)` | `MarkdownFile` | Read and parse a file. | +| `toHtml(...)` | `string` | Render block Markdown directly. | +| `toInlineHtml(...)` | `string` | Render an inline fragment directly. | +| `builder()` | `MarkdownBuilder` | Start a document builder. | +| `fragment()` | `MarkdownFragmentBuilder` | Start a fragment builder. | + +`MarkdownDocument` exposes typed accessors, `query()`, `ensure()`, `lint()`, +`fix()`, `format()`, `stats()`, `toMarkdown()`, and `toHtml()`. +`MarkdownFile` adds `path()`, `save()`, and `saveAs()`. See +[Errors](errors.md) for recoverable parse, edit, resource, and file failures. diff --git a/docs/documents/editing.md b/docs/documents/editing.md index 1c7f837..447251e 100644 --- a/docs/documents/editing.md +++ b/docs/documents/editing.md @@ -27,6 +27,7 @@ The result changes only the section body: ## Install Run Composer. + ``` Available typed edits: @@ -218,6 +219,10 @@ Compare-before-write protects against silently replacing bytes changed by another editor or process. It is optimistic conflict detection, not a filesystem lock. +After a conflict, keep the pending diff for review, reopen the current file, +and reapply the intended change against its updated content. Do not disable +comparison merely to force a stale write over another editor's changes. + Protected `saveAs()` can create a new target but refuses to replace an existing file that this document did not open. The default comparison option remains `false`, so enable it explicitly when concurrent changes are possible. @@ -252,5 +257,5 @@ mode handling is platform-limited. Use `atomic: false` only when retaining the existing inode and its metadata is more important than all-or-nothing replacement. A non-atomic write can leave partial content after an I/O failure. -See [Exceptions](../api/exceptions.md) for conflicts, stale handles, missing sections, and +See [Errors](../errors.md) for conflicts, stale handles, missing sections, and unsupported edits. diff --git a/docs/api/nodes.md b/docs/documents/nodes.md similarity index 94% rename from docs/api/nodes.md rename to docs/documents/nodes.md index 7676c66..337c3d5 100644 --- a/docs/api/nodes.md +++ b/docs/documents/nodes.md @@ -1,4 +1,4 @@ -# Nodes API +# Nodes Typed handles expose semantic values and the mutations Alto can lower safely to source patches. @@ -27,4 +27,4 @@ query the current document again. Generic block movement and insertion accept only direct children of the document root. Typed mutations retain their own documented boundaries. See -[Editing](../documents/editing.md) for worked operations. +[Editing](editing.md) for worked operations. diff --git a/docs/api/exceptions.md b/docs/errors.md similarity index 97% rename from docs/api/exceptions.md rename to docs/errors.md index 0bf15d1..6bf9527 100644 --- a/docs/api/exceptions.md +++ b/docs/errors.md @@ -63,7 +63,7 @@ Use the precise subtype when its recovery is different: Parser limit subclasses expose the configured and attempted values. File exceptions expose the original application path through `path`. Resource limits and their exact counting rules are documented in -[Security](../engine/security.md#bound-parsing-and-file-access). +[Security](security.md#bound-parsing-and-file-access). Unknown generic node kinds also raise an Alto domain exception. Construct factories with custom extensions during application startup rather than after @@ -122,5 +122,5 @@ own symlink policy. Existing non-regular targets are rejected. A relative path is anchored to its canonical parent when opened or adopted by `saveAs()`, but that does not replace application authorization. Permission inspection or restoration failures abort atomic replacement and preserve the pending diff. -See [Editing](../documents/editing.md#preview-and-save) for the complete +See [Editing](documents/editing.md#preview-and-save) for the complete persistence contract. diff --git a/docs/extensions.md b/docs/extensions.md new file mode 100644 index 0000000..8e171c6 --- /dev/null +++ b/docs/extensions.md @@ -0,0 +1,51 @@ +# Extensions + +Extensions add trusted syntax, rendering, transformations, analysis, or +resource-backed behavior to an immutable factory profile. Install only the +capabilities required by the document format. + +```php +use Alto\Markdown\Extension\Footnote\FootnoteExtension; +use Alto\Markdown\Extension\Highlight\HighlightExtension; +use Alto\Markdown\Markdown; + +$factory = Markdown::github()->with( + new FootnoteExtension(), + new HighlightExtension(), +); +``` + +Choose bundled extensions by outcome: + +- [Syntax](syntax.md) adds author-facing Markdown constructs. +- [Rendering](rendering.md) projects or decorates document output. +- [Resources](resources.md) resolves bounded external content. + +## Development + +- [Compatibility](extensions/compatibility.md): understand extension versioning. +- [Extension points](extensions/extension-points.md): select the correct contract. +- [Custom extension](extensions/custom.md): register trusted application behavior. + +## Capabilities + +An extension has a stable name and implements only the public capabilities its +behavior requires. + +| Capability | Public contract | +| --- | --- | +| Syntax | `BlockExtensionInterface`, `InlineExtensionInterface` | +| HTML | `HtmlDecoratorExtensionInterface` | +| Projection | `DocumentTransformExtensionInterface` | +| Lint | `LintExtensionInterface` | +| Format | `FormatterExtensionInterface` | +| Statistics | `StatsExtensionInterface` | +| Resources | `ResourceResolver` | + +Definitions, contexts, and value objects under `Alto\Markdown\Extension` are +public unless marked `@internal`. Parser tapes, compact node IDs, compiler +caches, and internal dispatch objects are not extension contracts. + +The returned factory is immutable. Extension compilation rejects invalid +names, duplicate or incompatible definitions, and unavailable parser triggers +before processing a document. Extensions execute as trusted application code. diff --git a/docs/extensions/compatibility.md b/docs/extensions/compatibility.md index 2d87ea7..70ae6b3 100644 --- a/docs/extensions/compatibility.md +++ b/docs/extensions/compatibility.md @@ -1,6 +1,6 @@ # Compatibility -Alto extensions depend only on Alto's public contracts. Extensions written for +ALTO extensions depend only on ALTO's public contracts. Extensions written for League CommonMark, Parsedown, or the historical `alto/commonmark` packages use different parser and renderer APIs. They cannot be passed directly to `MarkdownFactory::with()`. @@ -62,7 +62,7 @@ Alto does not emit deprecation warnings from parser or renderer hot paths. Security fixes may narrow unsafe behavior in a patch release when preserving it would keep users exposed. Such changes require an explicit security notice. -Package authors should test the lowest and newest Alto versions allowed by +Package authors should test the lowest and newest ALTO versions allowed by their Composer constraint. Invalid definitions and callback results raise `InvalidExtensionException`; arbitrary exceptions thrown by application callbacks remain unchanged. @@ -90,19 +90,19 @@ Map new block syntax to `BlockExtensionInterface`, leaf inline syntax to `HtmlDecoratorExtensionInterface`, and document-wide output decisions to `DocumentTransformExtensionInterface`. Do not adapt or expose the foreign AST. -Every historical Alto CommonMark feature has a native replacement: +Every historical ALTO CommonMark feature has a native replacement: | Historical package | Native Alto replacement | Migration note | | --- | --- | --- | -| `alto/commonmark-code-block-title` | [`CodeBlockTitleExtension`](index.md) | Use the typed title policy | -| `alto/commonmark-content-slicer` | [`ContentSlicerExtension`](index.md) | `minLevel` is the first heading level that opens a section | -| `alto/commonmark-heading-level` | [`HeadingLevelExtension`](index.md) | Use `HeadingLevelPolicy::map()`, `shift()`, or `using()` | -| `alto/commonmark-import` | [`ImportExtension`](index.md) | Inject a bounded `ResourceResolver` | -| `alto/commonmark-include` | [`IncludeExtension`](index.md) | Inject a resolver and explicit recursion policy | -| `alto/commonmark-link-rewriter` | [`LinkRewriterExtension`](index.md) | Build rules with `LinkRewriter` | -| `alto/commonmark-source` | [`SourceExtension`](index.md) | Inject a bounded resolver | -| `alto/commonmark-table-of-contents` | [`TableOfContentsExtension`](index.md) | Use the typed TOC policy | -| `alto/commonmark-tabs` | [`TabsExtension`](index.md) | Review generated HTML and progressive behavior | +| `alto/commonmark-code-block-title` | [`CodeBlockTitleExtension`](../rendering/code-block-titles.md) | Use the typed title policy | +| `alto/commonmark-content-slicer` | [`ContentSlicerExtension`](../rendering/content-slicer.md) | `minLevel` is the first heading level that opens a section | +| `alto/commonmark-heading-level` | [`HeadingLevelExtension`](../rendering/heading-levels.md) | Use `HeadingLevelPolicy::map()`, `shift()`, or `using()` | +| `alto/commonmark-import` | [`ImportExtension`](../resources/import.md) | Inject a bounded `ResourceResolver` | +| `alto/commonmark-include` | [`IncludeExtension`](../resources/include.md) | Inject a resolver and explicit recursion policy | +| `alto/commonmark-link-rewriter` | [`LinkRewriterExtension`](../rendering/link-rewriting.md) | Build rules with `LinkRewriter` | +| `alto/commonmark-source` | [`SourceExtension`](../resources/source.md) | Inject a bounded resolver | +| `alto/commonmark-table-of-contents` | [`TableOfContentsExtension`](../rendering/table-of-contents.md) | Use the typed TOC policy | +| `alto/commonmark-tabs` | [`TabsExtension`](../syntax/tabs.md) | Review generated HTML and progressive behavior | These are feature migrations, not drop-in class aliases. Re-run output, security, and source-preservation tests when moving an application. diff --git a/docs/extensions/index.md b/docs/extensions/index.md deleted file mode 100644 index e75d7c7..0000000 --- a/docs/extensions/index.md +++ /dev/null @@ -1,53 +0,0 @@ -# Extensions - -Extensions add trusted syntax, rendering, transformations, analysis, or -resource-backed behavior to an immutable factory profile. Install only the -capabilities required by the document format. - -```php -use Alto\Markdown\Extension\Footnote\FootnoteExtension; -use Alto\Markdown\Extension\Highlight\HighlightExtension; -use Alto\Markdown\Markdown; - -$factory = Markdown::github()->with( - new FootnoteExtension(), - new HighlightExtension(), -); -``` - -## Authoring syntax - -- [Paired delimiters](paired-delimiters.md): configurable leaf delimiter pairs. -- [Smart punctuation](smart-punctuation.md): quotes, dashes, and ellipses. -- [Highlight](highlight.md): highlighted inline text. -- [Description lists](description-lists.md): terms and definitions. -- [Footnotes](footnotes.md): definitions and references. -- [Tabs](tabs.md): nested tab groups. -- [Mentions](mentions.md): application-resolved references. -- [Attributes](attributes.md): constrained source attributes. - -## Documents and HTML - -- [Heading levels](heading-levels.md): project heading levels at render time. -- [Content slicer](content-slicer.md): group heading sections. -- [Heading permalinks](heading-permalinks.md): add stable heading links. -- [Table of contents](table-of-contents.md): generate a document outline. -- [Default attributes](default-attributes.md): add controlled HTML attributes. -- [Code block titles](code-block-titles.md): render code-block titles. -- [External links](external-links.md): mark external links. -- [Link rewriting](link-rewriting.md): rewrite link destinations. - -## External resources - -- [Import](import.md): insert escaped source code. -- [Include](include.md): expand bounded Markdown resources. -- [Source](source.md): display source excerpts. -- [Embeds](embeds.md): resolve allowlisted rich content. - -Resource-backed extensions require an injected `ResourceResolver`; installing -an extension never grants filesystem or network authority by itself. Read -[Security](../engine/security.md) before enabling them on untrusted input. - -Use [Extension points](extension-points.md) to choose a public contract, -[Custom extension](custom.md) for a minimal implementation, and -[Compatibility](compatibility.md) before publishing an extension package. diff --git a/docs/getting-started.md b/docs/getting-started.md index c0a135d..69b3fda 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -5,7 +5,8 @@ without parsing the source twice. ## Create a document -Start from a Composer application with `alto/markdown` installed: +Start from a Composer application with `alto/markdown` installed. Save this +as `render.php` beside `vendor/` and run `php render.php`: ```php links()->count()."\n"; echo $document->toHtml(); ``` -The first two lines are `Project` and `1`. The remaining output is the rendered -heading and paragraph. +The complete output is: + +```text +Project +1 +
Read the guide.
+``` `github()` enables CommonMark, GitHub Flavored Markdown, GitHub alerts, and front matter. The returned document retains the parsed structure and original diff --git a/docs/index.md b/docs/index.md index 471eef6..fc03fac 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,6 +1,6 @@ -# Alto Markdown +# ALTO Markdown -Alto Markdown converts Markdown to safe HTML and keeps a source-backed +ALTO Markdown converts Markdown to safe HTML and keeps a source-backed document model when an application needs to inspect, lint, or edit content. Use direct conversion for one result; open a document when later work depends on its structure. @@ -11,80 +11,25 @@ use Alto\Markdown\Markdown; $html = Markdown::github()->toHtml("# Hello\n\nWelcome.\n"); ``` -## Start +The conversion returns `