Export method code snippets#258
Draft
adamziel wants to merge 18 commits into
Draft
Conversation
Instead of stripping every PHP fence and emitting code_snippets that the theme appends after the description, leave an inline HTML-comment placeholder (<!-- wp-parser-code-snippet:N -->) where each PHP fence was. The index aligns with the code_snippets array so the theme can render each runnable snippet in place, keeping it between the surrounding prose. Snippet-metadata fences (expected-output, Blueprints) are still removed. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
With snippets rendered inline, a description that previously stripped to '' (or to just its prose) now keeps an inline <!-- wp-parser-code-snippet:N --> marker. Update the two affected long_description assertions to match. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ripping export_docblock() parses the long-description fences a single time and passes the array to both export_docblock_code_snippets() and strip_docblock_code_snippet_fences() (each still tokenizes on its own when called directly). get_docblock_code_fences() now classifies each fence once (is_php / is_expected_output / is_blueprint / setup_name / referenced_setup / is_code_snippet) and numbers the PHP fences, so the stripper reads each snippet's index from the fence instead of recounting — removing the implicit index-alignment coupling. No behavior change (output byte-identical); still O(n). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
get_docblock_code_fences() now captures each fenced block with a single regex: the \2 backreference makes the closing fence repeat the opener's backtick run (so longer/shorter fences stay in the body), the non-greedy (?:.*\n)*? stops at the first matching closer, and \G anchors each attempt at the next opener so an unterminated opener still halts parsing — same semantics as the old scanner. Indentation is stripped per block; line numbers are counted incrementally (gap-only) to keep the scan O(n). Output is byte-identical, verified against golden captures of the tokenizer (16 cases incl. empty/blank/nested/unterminated/CRLF), the snippet exporter + stripper (11 cases), and a full WP_HTML_Tag_Processor parse. Fence benchmark stays linear. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The classification is precomputed once in get_docblock_code_fences() as $fence['is_code_snippet'] and the stripper reads that flag, so this helper has no callers left — its body only duplicated the inline computation. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The inner metadata scan always breaks on the first expected-output fence, so a snippet can take at most one and the guard was always true. Inline the assignment. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What it does
Exports runnable PHP examples from DocBlocks as
doc.code_snippets, replaces each PHP fence indoc.long_descriptionwith an inline placeholder (<!-- wp-parser-code-snippet:N -->), and stores the snippet metadata during import. The theme renders each placeholder as a runnable snippet in place, so a snippet stays between the surrounding prose instead of collapsing to the end of the description.A DocBlock can pair a
phpfence withexpected-outputand optional setup Blueprint data:For reusable setup, define a named setup Blueprint once and reference it from multiple PHP fences:
File-level setup Blueprints are inherited by functions, classes, and methods in that file, so one setup definition can be reused by several examples.
How the export JSON changes
Only PHP fences move; a plain fence (no language) is left untouched. Here is the same DocBlock — one plain fence and one
phpexample — parsed bymasterversus this branch (the function'sdoc, HTML abbreviated):"doc": { "description": "Greets a person.", - "long_description": "…<pre><code>$greeting = docs_greet( $name );</code></pre>… <pre><code>echo docs_greet( $name );</code></pre> <pre><code>Hello, World!</code></pre>", + "long_description": "…<pre><code>$greeting = docs_greet( $name );</code></pre>… <!-- wp-parser-code-snippet:0 -->", + "code_snippets": [ + { "type": "php-code-snippet", "code": "<?php\necho docs_greet( $name );", "expected_output": "Hello, World!" } + ], "tags": [ /* @param, @return — unchanged */ ] }The plain
$greetingfence stays inlong_description; thephpfence becomes a positioned placeholder plus acode_snippetsentry.Screenshot
Actual
wporg-developerrender from an imported fixture using this parser branch plus WordPress/wporg-developer#567. The second and third examples share a named setup Blueprint.Try it in WordPress Playground
WP_HTML_Tag_Processor's usage docs — prose interleaved with both plain code fences and runnable PHP fences — imported into the builtwporg-developer-2023stack. (These are minimal Playgrounds, so the global theme styling is absent; the snippet rendering is what they demonstrate.)<php-snippet>, all in place: code block → snippet → "Finding tags" → code block → snippet.Rationale
WordPress.org docs need structured data for
php-code-snippet, with JSON as the intermediate format. Exportingcode,expected_output, and setup Blueprint data avoids reverse-parsing rendered HTML later.Replacing each PHP fence with an inline placeholder — rather than dropping it — keeps the theme from rendering duplicate examples while preserving the snippet's position: the plain code fence disappears, and the runnable snippet renders exactly where it appeared in the prose.
Backward compatibility
Safe to land before WordPress/wporg-developer#567. A theme that doesn't read the new post meta ignores it, and the placeholders are invisible HTML comments, so pages render cleanly with no PHP errors (see the stock-theme Playground above). Nothing visible is removed today either: only
php-tagged fences are converted, and a scan ofwordpress-develop/src(1,858 files) finds zerophp-tagged fences in WordPress's own docs — the few that exist live only in bundled libraries such asPHPMailer/andphp-ai-client/. Plain code fences, which core does use, are left untouched. #567 is needed only to render the new convention (e.g. WordPress/wordpress-develop#29).Testing instructions