diff --git a/.github/scripts/verify-metrics.sh b/.github/scripts/verify-metrics.sh index a6f4fa1..1904db5 100755 --- a/.github/scripts/verify-metrics.sh +++ b/.github/scripts/verify-metrics.sh @@ -71,6 +71,7 @@ actual_php="$(find . -name '*.php' \ -not -path './tests/*' \ -not -path './packages/*' \ -not -path './scripts/*' \ + -not -path './playground/*' \ -not -path './output/*' \ -not -path './build/*' \ -print0 | xargs -0 wc -l | tail -1 | awk '{print $1}')" diff --git a/.wordpress-org/blueprints/blueprint.json b/.wordpress-org/blueprints/blueprint.json index 80d45b2..ff03e34 100644 --- a/.wordpress-org/blueprints/blueprint.json +++ b/.wordpress-org/blueprints/blueprint.json @@ -26,7 +26,7 @@ }, { "step": "runPHP", - "code": "\n
Welcome to Borges Bibliography Builder. Use the Bibliography block below, then paste one or more sample entries into the Paste / Import field (separate entries with a blank line).
\n\n\n\n10.1145/3368089.3409742\n\n10.1038/s41586-020-2649-2\n\nPMID:26673779\n\nPMC3531190\n\narXiv:1706.03762\n\nISBN 978-0-14-032872-1\n\n@article{knuth1984literate,\n author = {Knuth, Donald E.},\n title = {Literate Programming},\n journal = {The Computer Journal},\n year = {1984},\n volume = {27},\n number = {2},\n pages = {97--111},\n doi = {10.1093/comjnl/27.2.97}\n}\n\n\n\nTip: In the block sidebar, try changing citation style and export actions (CSL-JSON, BibTeX, RIS).
\n\n\n\nEOT;\n\nwp_update_post(\n\tarray(\n\t\t'ID' => 1,\n\t\t'post_title' => 'Borges Bibliography Playground Starter',\n\t\t'post_content' => $post_content,\n\t)\n);\n" + "code": "Welcome to Borges Bibliography Builder. This Playground runs the latest release. It is a sandbox: nothing here is kept after you close the tab.';\n$borges_demo_json = <<<'JSON'\n{\"title\":\"Borges Bibliography Builder demo\",\"sampleGroups\":[{\"title\":\"DOIs\",\"description\":\"A bare DOI, adoi: prefix, or a doi.org link. Metadata comes from Crossref.\",\"samples\":[{\"format\":\"doi\",\"input\":\"10.1038/s41586-020-2649-2\"},{\"format\":\"doi\",\"input\":\"doi:10.1038/nature14539\"},{\"format\":\"doi\",\"input\":\"https://doi.org/10.1145/3368089.3409742\"}]},{\"title\":\"PubMed and PubMed Central\",\"description\":\"A PMID needs its PMID: label. A PMCID starts with PMC, with or without a PMCID: label.\",\"samples\":[{\"format\":\"pmid\",\"input\":\"PMID:26673779\"},{\"format\":\"pmcid\",\"input\":\"PMC3531190\"}]},{\"title\":\"arXiv\",\"description\":\"An arXiv: ID (modern or legacy), an arxiv.org link, or an arXiv DOI.\",\"samples\":[{\"format\":\"arxiv\",\"input\":\"arXiv:1706.03762\"},{\"format\":\"arxiv\",\"input\":\"https://arxiv.org/abs/1810.04805\"},{\"format\":\"arxiv\",\"input\":\"arXiv:hep-th/9711200\"},{\"format\":\"arxiv\",\"input\":\"10.48550/arXiv.2005.14165\"}]},{\"title\":\"ISBNs\",\"description\":\"A labeled ISBN-13 or ISBN-10, or a bare ISBN-13 starting with 978 or 979. Books come from Open Library, with Google Books as a fallback.\",\"samples\":[{\"format\":\"isbn\",\"input\":\"ISBN 978-0-14-032872-1\"},{\"format\":\"isbn\",\"input\":\"9780262033848\"},{\"format\":\"isbn\",\"input\":\"ISBN-10: 0-8112-0012-4\"}]},{\"title\":\"BibTeX and BibLaTeX\",\"description\":\"Whole entries, one or many. BibLaTeX fields such as date and location are understood.\",\"samples\":[{\"format\":\"bibtex\",\"input\":\"@article{knuth1984literate,\\n author = {Knuth, Donald E.},\\n title = {Literate Programming},\\n journal = {The Computer Journal},\\n year = {1984},\\n volume = {27},\\n number = {2},\\n pages = {97--111},\\n doi = {10.1093/comjnl/27.2.97}\\n}\"},{\"format\":\"bibtex\",\"input\":\"@book{borges1962labyrinths,\\n author = {Borges, Jorge Luis},\\n title = {Labyrinths: Selected Stories and Other Writings},\\n editor = {Yates, Donald A. and Irby, James E.},\\n date = {1962},\\n publisher = {New Directions},\\n location = {New York}\\n}\"}]},{\"title\":\"Formatted citations\",\"description\":\"Plain-text citations for books, journal articles, chapters, and webpages, in Chicago or APA shape. A citation that contains a DOI, PMID, PMCID, or arXiv ID is looked up by that identifier instead.\",\"samples\":[{\"format\":\"freetext\",\"input\":\"Binder, Amy J., and Jeffrey L. Kidder. The Channels of Student Activism: How the Left and Right Are Winning (and Losing) in Campus Politics Today. University of Chicago Press, 2022.\"},{\"format\":\"freetext\",\"input\":\"Dittmar, Emily L., and Douglas W. Schemske. “Temporal Variation in Selection Influences Microgeographic Local Adaptation.” American Naturalist 202, no. 4 (2023): 471–85.\"},{\"format\":\"freetext\",\"input\":\"Doyle, Kathleen. “The Queen Mary Psalter.” In The Book by Design: The Remarkable Story of the World’s Greatest Invention, edited by P. J. M. Marks and Stephen Parkin. University of Chicago Press, 2023.\"},{\"format\":\"freetext\",\"input\":\"Yale University. “About Yale: Yale Facts.” Accessed March 8, 2022. https://www.yale.edu/about-yale/yale-facts.\"},{\"format\":\"doi\",\"embedded\":true,\"input\":\"Dittmar, Emily L., and Douglas W. Schemske. “Temporal Variation in Selection Influences Microgeographic Local Adaptation.” American Naturalist 202, no. 4 (2023): 471–85. https://doi.org/10.1086/725865.\"}]}],\"features\":[\"Citation Style (block sidebar): switch among Chicago, APA, MLA, Harvard, IEEE, Vancouver, OSCOLA, ABNT, and more. Generated text reformats; your manual edits are kept.\",\"Edit an entry: select a citation and use its edit button to correct fields. Reset edits restores the generated text.\",\"Manual Entry: next to Paste / Import, add a citation field by field when there is nothing to paste.\",\"Duplicates: paste a DOI that is already in the list; it is skipped, not added twice.\",\"Order: notes and author-date styles sort alphabetically. Numeric styles (IEEE, Vancouver) keep your order; use Move citation up/down.\",\"Exports (block toolbar): copy the bibliography as text, or download BibTeX, BibLaTeX, RIS, or CSL-JSON.\",\"Per-entry Cite / Export (sidebar): gives readers copy and download links under each entry on the published page.\",\"Machine-readable output (sidebar): JSON-LD for search engines (on by default), COinS for Zotero, and embedded CSL-JSON.\",\"Front end: use View Post to see the published bibliography, then open its read-only REST data.\"],\"examples\":[{\"title\":\"Chicago notes-bibliography, with Cite / Export\",\"description\":\"A book, a chapter, a journal article, and a webpage, sorted alphabetically. Per-entry Cite / Export and COinS are on; view the post to try the copy and download links.\",\"attributes\":{\"bibliographyId\":\"demo-chicago-notes\",\"citationStyle\":\"chicago-notes-bibliography\",\"headingText\":\"Works Cited\",\"outputJsonLd\":true,\"outputCoins\":true,\"outputCslJson\":false,\"outputCiteExport\":true},\"citations\":[{\"type\":\"book\",\"title\":\"Labyrinths: Selected Stories and Other Writings\",\"author\":[{\"family\":\"Borges\",\"given\":\"Jorge Luis\"}],\"editor\":[{\"family\":\"Yates\",\"given\":\"Donald A.\"},{\"family\":\"Irby\",\"given\":\"James E.\"}],\"publisher\":\"New Directions\",\"publisher-place\":\"New York\",\"issued\":{\"date-parts\":[[1962]]}},{\"type\":\"chapter\",\"title\":\"The Library of Babel\",\"author\":[{\"family\":\"Borges\",\"given\":\"Jorge Luis\"}],\"translator\":[{\"family\":\"Irby\",\"given\":\"James E.\"}],\"container-title\":\"Labyrinths: Selected Stories and Other Writings\",\"editor\":[{\"family\":\"Yates\",\"given\":\"Donald A.\"},{\"family\":\"Irby\",\"given\":\"James E.\"}],\"publisher\":\"New Directions\",\"publisher-place\":\"New York\",\"issued\":{\"date-parts\":[[1962]]}},{\"type\":\"article-journal\",\"title\":\"Literate Programming\",\"author\":[{\"family\":\"Knuth\",\"given\":\"Donald E.\"}],\"container-title\":\"The Computer Journal\",\"volume\":\"27\",\"issue\":\"2\",\"page\":\"97-111\",\"DOI\":\"10.1093/comjnl/27.2.97\",\"issued\":{\"date-parts\":[[1984]]}},{\"type\":\"webpage\",\"title\":\"Block Editor Handbook\",\"author\":[{\"literal\":\"WordPress.org\"}],\"container-title\":\"WordPress Developer Resources\",\"URL\":\"https://developer.wordpress.org/block-editor/\"}],\"exports\":[{\"exportBibtex\":\"@book{Borges1962Labyrinths,\\n\\taddress = {New York},\\n\\tauthor = {Borges, Jorge Luis},\\n\\teditor = {Yates, Donald A. and Irby, James E.},\\n\\tyear = {1962},\\n\\tpublisher = {New Directions},\\n\\ttitle = {Labyrinths: Selected {Stories} and {Other} {Writings}},\\n}\\n\\n\\n\",\"exportBiblatex\":\"@book{Borges1962Labyrinths,\\n\\tauthor = {Borges, Jorge Luis},\\n\\teditor = {Yates, Donald A. and Irby, James E.},\\n\\tdate = {1962},\\n\\tlocation = {New York},\\n\\tpublisher = {New Directions},\\n\\ttitle = {Labyrinths: Selected {Stories} and {Other} {Writings}},\\n}\\n\\n\\n\"},{\"exportBibtex\":\"@inbook{Borges1962Library,\\n\\taddress = {New York},\\n\\tauthor = {Borges, Jorge Luis},\\n\\tbooktitle = {Labyrinths: Selected {Stories} and {Other} {Writings}},\\n\\teditor = {Yates, Donald A. and Irby, James E.},\\n\\tyear = {1962},\\n\\tpublisher = {New Directions},\\n\\ttitle = {The {Library} of {Babel}},\\n}\\n\\n\\n\",\"exportBiblatex\":\"@inbook{Borges1962Library,\\n\\tauthor = {Borges, Jorge Luis},\\n\\tbooktitle = {Labyrinths: Selected {Stories} and {Other} {Writings}},\\n\\teditor = {Yates, Donald A. and Irby, James E.},\\n\\tdate = {1962},\\n\\tlocation = {New York},\\n\\tpublisher = {New Directions},\\n\\ttitle = {The {Library} of {Babel}},\\n\\ttranslator = {Irby, James E.},\\n}\\n\\n\\n\"},{\"exportBibtex\":\"@article{Knuth1984Literate,\\n\\tauthor = {Knuth, Donald E.},\\n\\tjournal = {The Computer Journal},\\n\\tdoi = {10.1093/comjnl/27.2.97},\\n\\tnumber = {2},\\n\\tyear = {1984},\\n\\tpages = {97--111},\\n\\ttitle = {Literate {Programming}},\\n\\tvolume = {27},\\n}\\n\\n\\n\",\"exportBiblatex\":\"@article{Knuth1984Literate,\\n\\tauthor = {Knuth, Donald E.},\\n\\tjournaltitle = {The Computer Journal},\\n\\tdoi = {10.1093/comjnl/27.2.97},\\n\\tnumber = {2},\\n\\tdate = {1984},\\n\\tpages = {97--111},\\n\\ttitle = {Literate {Programming}},\\n\\tvolume = {27},\\n}\\n\\n\\n\"},{\"exportBibtex\":\"@misc{WordPressBlock,\\n\\tauthor = {{WordPress.org}},\\n\\ttitle = {Block {Editor} {Handbook}},\\n\\turl = {https://developer.wordpress.org/block-editor/},\\n\\thowpublished = {https://developer.wordpress.org/block-editor/},\\n}\\n\\n\\n\",\"exportBiblatex\":\"@online{WordPressBlock,\\n\\tauthor = {{WordPress.org}},\\n\\tbooktitle = {WordPress {Developer} {Resources}},\\n\\ttitle = {Block {Editor} {Handbook}},\\n\\turl = {https://developer.wordpress.org/block-editor/},\\n}\\n\\n\\n\"}]},{\"title\":\"APA 7 author-date\",\"description\":\"Journal articles and an arXiv preprint in APA style, with DOIs as links.\",\"attributes\":{\"bibliographyId\":\"demo-apa-7\",\"citationStyle\":\"apa-7\",\"headingText\":\"References\",\"outputJsonLd\":true,\"outputCoins\":false,\"outputCslJson\":false,\"outputCiteExport\":false},\"citations\":[{\"type\":\"article-journal\",\"title\":\"Deep learning\",\"author\":[{\"family\":\"LeCun\",\"given\":\"Yann\"},{\"family\":\"Bengio\",\"given\":\"Yoshua\"},{\"family\":\"Hinton\",\"given\":\"Geoffrey\"}],\"container-title\":\"Nature\",\"volume\":\"521\",\"issue\":\"7553\",\"page\":\"436-444\",\"DOI\":\"10.1038/nature14539\",\"issued\":{\"date-parts\":[[2015]]}},{\"type\":\"article\",\"title\":\"Attention is all you need\",\"author\":[{\"family\":\"Vaswani\",\"given\":\"Ashish\"},{\"family\":\"Shazeer\",\"given\":\"Noam\"},{\"family\":\"Parmar\",\"given\":\"Niki\"},{\"family\":\"Uszkoreit\",\"given\":\"Jakob\"},{\"family\":\"Jones\",\"given\":\"Llion\"},{\"family\":\"Gomez\",\"given\":\"Aidan N.\"},{\"family\":\"Kaiser\",\"given\":\"Łukasz\"},{\"family\":\"Polosukhin\",\"given\":\"Illia\"}],\"publisher\":\"arXiv\",\"number\":\"1706.03762\",\"DOI\":\"10.48550/arXiv.1706.03762\",\"issued\":{\"date-parts\":[[2017]]}},{\"type\":\"article-journal\",\"title\":\"Computing machinery and intelligence\",\"author\":[{\"family\":\"Turing\",\"given\":\"A. M.\"}],\"container-title\":\"Mind\",\"volume\":\"59\",\"issue\":\"236\",\"page\":\"433-460\",\"DOI\":\"10.1093/mind/LIX.236.433\",\"issued\":{\"date-parts\":[[1950]]}}]},{\"title\":\"IEEE numeric\",\"description\":\"Numbered entries keep the order you give them. Select the block and use Move citation up/down to renumber.\",\"attributes\":{\"bibliographyId\":\"demo-ieee\",\"citationStyle\":\"ieee\",\"headingText\":\"References\",\"outputJsonLd\":true,\"outputCoins\":false,\"outputCslJson\":false,\"outputCiteExport\":false},\"citations\":[{\"type\":\"article-journal\",\"title\":\"A Mathematical Theory of Communication\",\"author\":[{\"family\":\"Shannon\",\"given\":\"Claude E.\"}],\"container-title\":\"Bell System Technical Journal\",\"volume\":\"27\",\"issue\":\"3\",\"page\":\"379-423\",\"DOI\":\"10.1002/j.1538-7305.1948.tb01338.x\",\"issued\":{\"date-parts\":[[1948]]}},{\"type\":\"article-journal\",\"title\":\"Computing Machinery and Intelligence\",\"author\":[{\"family\":\"Turing\",\"given\":\"A. M.\"}],\"container-title\":\"Mind\",\"volume\":\"59\",\"issue\":\"236\",\"page\":\"433-460\",\"DOI\":\"10.1093/mind/LIX.236.433\",\"issued\":{\"date-parts\":[[1950]]}},{\"type\":\"article-journal\",\"title\":\"Literate Programming\",\"author\":[{\"family\":\"Knuth\",\"given\":\"Donald E.\"}],\"container-title\":\"The Computer Journal\",\"volume\":\"27\",\"issue\":\"2\",\"page\":\"97-111\",\"DOI\":\"10.1093/comjnl/27.2.97\",\"issued\":{\"date-parts\":[[1984]]}}]}]}\nJSON;\n/**\n * Playground demo page builder.\n *\n * `npm run playground:build` inlines this file into each demo blueprint's\n * runPHP step, after defining:\n *\n * - $borges_demo_json The contents of playground/demo-content.json.\n * - $borges_demo_intro An HTML lead paragraph for that blueprint.\n *\n * It rewrites post 1 as the demo page the blueprint lands on, and turns off\n * the editor's Welcome Guide so the page is visible straight away. Example\n * bibliographies are formatted with the plugin's own citeproc formatter and\n * rendered with its PHP port of save(), so they validate against whatever\n * version is installed. A release without that port (before 1.7.0) gets a\n * note instead.\n *\n * Not part of the plugin package (playground/ is in .distignore).\n *\n * @package BibliographyBuilder\n */\n\nrequire_once '/wordpress/wp-load.php';\n\n// Write as the admin, and keep kses from stripping the blocks' JSON-LD\n// scripts and data attributes: kses_init() ran before any user was set.\nwp_set_current_user( 1 );\nkses_remove_filters();\n\n$borges_demo = json_decode( $borges_demo_json, true );\n\n$borges_demo_block = static function ( $name, $attrs, $html ) {\n\treturn serialize_block(\n\t\tarray(\n\t\t\t'blockName' => $name,\n\t\t\t'attrs' => $attrs,\n\t\t\t'innerBlocks' => array(),\n\t\t\t'innerHTML' => $html,\n\t\t\t'innerContent' => array( $html ),\n\t\t)\n\t) . \"\\n\\n\";\n};\n\n$borges_demo_paragraph = static function ( $html ) use ( $borges_demo_block ) {\n\treturn $borges_demo_block( 'core/paragraph', array(), '' . $html . '
' );\n};\n\n$borges_demo_heading = static function ( $text, $level ) use ( $borges_demo_block ) {\n\t$attrs = 2 === $level ? array() : array( 'level' => $level );\n\t$tag = 'h' . $level;\n\n\treturn $borges_demo_block( 'core/heading', $attrs, '<' . $tag . ' class=\"wp-block-heading\">' . esc_html( $text ) . '' . $tag . '>' );\n};\n\n$borges_demo_code = static function ( $text ) use ( $borges_demo_block ) {\n\treturn $borges_demo_block(\n\t\t'core/code',\n\t\tarray(),\n\t\t'' . htmlspecialchars( $text, ENT_NOQUOTES, 'UTF-8' ) . ''\n\t);\n};\n\n$borges_demo_list = static function ( $items ) {\n\t$html = \"\\nWelcome to the Borges Bibliography Builder development build. This Playground runs the current main branch, not a stable release. Use the Bibliography block below, then paste one or more sample entries into the Paste / Import field (separate entries with a blank line).
10.1145/3368089.3409742\n\n10.1038/s41586-020-2649-2\n\nPMID:26673779\n\nPMC3531190\n\narXiv:1706.03762\n\nISBN 978-0-14-032872-1\n\n@article{knuth1984literate,\n author = {Knuth, Donald E.},\n title = {Literate Programming},\n journal = {The Computer Journal},\n year = {1984},\n volume = {27},\n number = {2},\n pages = {97--111},\n doi = {10.1093/comjnl/27.2.97}\n}\n\n\n\nTip: In the block sidebar, try changing citation style and export actions (CSL-JSON, BibTeX, RIS).
\n\n\n\nEOT;\n\nwp_update_post(\n\tarray(\n\t\t'ID' => 1,\n\t\t'post_title' => 'Borges Bibliography Playground Starter (main build)',\n\t\t'post_content' => $post_content,\n\t)\n);\n" + "code": "Welcome to the Borges Bibliography Builder development build. This Playground runs the currentmain branch, not a stable release. It is a sandbox: nothing here is kept after you close the tab.';\n$borges_demo_json = <<<'JSON'\n{\"title\":\"Borges Bibliography Builder demo\",\"sampleGroups\":[{\"title\":\"DOIs\",\"description\":\"A bare DOI, a doi: prefix, or a doi.org link. Metadata comes from Crossref.\",\"samples\":[{\"format\":\"doi\",\"input\":\"10.1038/s41586-020-2649-2\"},{\"format\":\"doi\",\"input\":\"doi:10.1038/nature14539\"},{\"format\":\"doi\",\"input\":\"https://doi.org/10.1145/3368089.3409742\"}]},{\"title\":\"PubMed and PubMed Central\",\"description\":\"A PMID needs its PMID: label. A PMCID starts with PMC, with or without a PMCID: label.\",\"samples\":[{\"format\":\"pmid\",\"input\":\"PMID:26673779\"},{\"format\":\"pmcid\",\"input\":\"PMC3531190\"}]},{\"title\":\"arXiv\",\"description\":\"An arXiv: ID (modern or legacy), an arxiv.org link, or an arXiv DOI.\",\"samples\":[{\"format\":\"arxiv\",\"input\":\"arXiv:1706.03762\"},{\"format\":\"arxiv\",\"input\":\"https://arxiv.org/abs/1810.04805\"},{\"format\":\"arxiv\",\"input\":\"arXiv:hep-th/9711200\"},{\"format\":\"arxiv\",\"input\":\"10.48550/arXiv.2005.14165\"}]},{\"title\":\"ISBNs\",\"description\":\"A labeled ISBN-13 or ISBN-10, or a bare ISBN-13 starting with 978 or 979. Books come from Open Library, with Google Books as a fallback.\",\"samples\":[{\"format\":\"isbn\",\"input\":\"ISBN 978-0-14-032872-1\"},{\"format\":\"isbn\",\"input\":\"9780262033848\"},{\"format\":\"isbn\",\"input\":\"ISBN-10: 0-8112-0012-4\"}]},{\"title\":\"BibTeX and BibLaTeX\",\"description\":\"Whole entries, one or many. BibLaTeX fields such as date and location are understood.\",\"samples\":[{\"format\":\"bibtex\",\"input\":\"@article{knuth1984literate,\\n author = {Knuth, Donald E.},\\n title = {Literate Programming},\\n journal = {The Computer Journal},\\n year = {1984},\\n volume = {27},\\n number = {2},\\n pages = {97--111},\\n doi = {10.1093/comjnl/27.2.97}\\n}\"},{\"format\":\"bibtex\",\"input\":\"@book{borges1962labyrinths,\\n author = {Borges, Jorge Luis},\\n title = {Labyrinths: Selected Stories and Other Writings},\\n editor = {Yates, Donald A. and Irby, James E.},\\n date = {1962},\\n publisher = {New Directions},\\n location = {New York}\\n}\"}]},{\"title\":\"Formatted citations\",\"description\":\"Plain-text citations for books, journal articles, chapters, and webpages, in Chicago or APA shape. A citation that contains a DOI, PMID, PMCID, or arXiv ID is looked up by that identifier instead.\",\"samples\":[{\"format\":\"freetext\",\"input\":\"Binder, Amy J., and Jeffrey L. Kidder. The Channels of Student Activism: How the Left and Right Are Winning (and Losing) in Campus Politics Today. University of Chicago Press, 2022.\"},{\"format\":\"freetext\",\"input\":\"Dittmar, Emily L., and Douglas W. Schemske. “Temporal Variation in Selection Influences Microgeographic Local Adaptation.” American Naturalist 202, no. 4 (2023): 471–85.\"},{\"format\":\"freetext\",\"input\":\"Doyle, Kathleen. “The Queen Mary Psalter.” In The Book by Design: The Remarkable Story of the World’s Greatest Invention, edited by P. J. M. Marks and Stephen Parkin. University of Chicago Press, 2023.\"},{\"format\":\"freetext\",\"input\":\"Yale University. “About Yale: Yale Facts.” Accessed March 8, 2022. https://www.yale.edu/about-yale/yale-facts.\"},{\"format\":\"doi\",\"embedded\":true,\"input\":\"Dittmar, Emily L., and Douglas W. Schemske. “Temporal Variation in Selection Influences Microgeographic Local Adaptation.” American Naturalist 202, no. 4 (2023): 471–85. https://doi.org/10.1086/725865.\"}]}],\"features\":[\"Citation Style (block sidebar): switch among Chicago, APA, MLA, Harvard, IEEE, Vancouver, OSCOLA, ABNT, and more. Generated text reformats; your manual edits are kept.\",\"Edit an entry: select a citation and use its edit button to correct fields. Reset edits restores the generated text.\",\"Manual Entry: next to Paste / Import, add a citation field by field when there is nothing to paste.\",\"Duplicates: paste a DOI that is already in the list; it is skipped, not added twice.\",\"Order: notes and author-date styles sort alphabetically. Numeric styles (IEEE, Vancouver) keep your order; use Move citation up/down.\",\"Exports (block toolbar): copy the bibliography as text, or download BibTeX, BibLaTeX, RIS, or CSL-JSON.\",\"Per-entry Cite / Export (sidebar): gives readers copy and download links under each entry on the published page.\",\"Machine-readable output (sidebar): JSON-LD for search engines (on by default), COinS for Zotero, and embedded CSL-JSON.\",\"Front end: use View Post to see the published bibliography, then open its read-only REST data.\"],\"examples\":[{\"title\":\"Chicago notes-bibliography, with Cite / Export\",\"description\":\"A book, a chapter, a journal article, and a webpage, sorted alphabetically. Per-entry Cite / Export and COinS are on; view the post to try the copy and download links.\",\"attributes\":{\"bibliographyId\":\"demo-chicago-notes\",\"citationStyle\":\"chicago-notes-bibliography\",\"headingText\":\"Works Cited\",\"outputJsonLd\":true,\"outputCoins\":true,\"outputCslJson\":false,\"outputCiteExport\":true},\"citations\":[{\"type\":\"book\",\"title\":\"Labyrinths: Selected Stories and Other Writings\",\"author\":[{\"family\":\"Borges\",\"given\":\"Jorge Luis\"}],\"editor\":[{\"family\":\"Yates\",\"given\":\"Donald A.\"},{\"family\":\"Irby\",\"given\":\"James E.\"}],\"publisher\":\"New Directions\",\"publisher-place\":\"New York\",\"issued\":{\"date-parts\":[[1962]]}},{\"type\":\"chapter\",\"title\":\"The Library of Babel\",\"author\":[{\"family\":\"Borges\",\"given\":\"Jorge Luis\"}],\"translator\":[{\"family\":\"Irby\",\"given\":\"James E.\"}],\"container-title\":\"Labyrinths: Selected Stories and Other Writings\",\"editor\":[{\"family\":\"Yates\",\"given\":\"Donald A.\"},{\"family\":\"Irby\",\"given\":\"James E.\"}],\"publisher\":\"New Directions\",\"publisher-place\":\"New York\",\"issued\":{\"date-parts\":[[1962]]}},{\"type\":\"article-journal\",\"title\":\"Literate Programming\",\"author\":[{\"family\":\"Knuth\",\"given\":\"Donald E.\"}],\"container-title\":\"The Computer Journal\",\"volume\":\"27\",\"issue\":\"2\",\"page\":\"97-111\",\"DOI\":\"10.1093/comjnl/27.2.97\",\"issued\":{\"date-parts\":[[1984]]}},{\"type\":\"webpage\",\"title\":\"Block Editor Handbook\",\"author\":[{\"literal\":\"WordPress.org\"}],\"container-title\":\"WordPress Developer Resources\",\"URL\":\"https://developer.wordpress.org/block-editor/\"}],\"exports\":[{\"exportBibtex\":\"@book{Borges1962Labyrinths,\\n\\taddress = {New York},\\n\\tauthor = {Borges, Jorge Luis},\\n\\teditor = {Yates, Donald A. and Irby, James E.},\\n\\tyear = {1962},\\n\\tpublisher = {New Directions},\\n\\ttitle = {Labyrinths: Selected {Stories} and {Other} {Writings}},\\n}\\n\\n\\n\",\"exportBiblatex\":\"@book{Borges1962Labyrinths,\\n\\tauthor = {Borges, Jorge Luis},\\n\\teditor = {Yates, Donald A. and Irby, James E.},\\n\\tdate = {1962},\\n\\tlocation = {New York},\\n\\tpublisher = {New Directions},\\n\\ttitle = {Labyrinths: Selected {Stories} and {Other} {Writings}},\\n}\\n\\n\\n\"},{\"exportBibtex\":\"@inbook{Borges1962Library,\\n\\taddress = {New York},\\n\\tauthor = {Borges, Jorge Luis},\\n\\tbooktitle = {Labyrinths: Selected {Stories} and {Other} {Writings}},\\n\\teditor = {Yates, Donald A. and Irby, James E.},\\n\\tyear = {1962},\\n\\tpublisher = {New Directions},\\n\\ttitle = {The {Library} of {Babel}},\\n}\\n\\n\\n\",\"exportBiblatex\":\"@inbook{Borges1962Library,\\n\\tauthor = {Borges, Jorge Luis},\\n\\tbooktitle = {Labyrinths: Selected {Stories} and {Other} {Writings}},\\n\\teditor = {Yates, Donald A. and Irby, James E.},\\n\\tdate = {1962},\\n\\tlocation = {New York},\\n\\tpublisher = {New Directions},\\n\\ttitle = {The {Library} of {Babel}},\\n\\ttranslator = {Irby, James E.},\\n}\\n\\n\\n\"},{\"exportBibtex\":\"@article{Knuth1984Literate,\\n\\tauthor = {Knuth, Donald E.},\\n\\tjournal = {The Computer Journal},\\n\\tdoi = {10.1093/comjnl/27.2.97},\\n\\tnumber = {2},\\n\\tyear = {1984},\\n\\tpages = {97--111},\\n\\ttitle = {Literate {Programming}},\\n\\tvolume = {27},\\n}\\n\\n\\n\",\"exportBiblatex\":\"@article{Knuth1984Literate,\\n\\tauthor = {Knuth, Donald E.},\\n\\tjournaltitle = {The Computer Journal},\\n\\tdoi = {10.1093/comjnl/27.2.97},\\n\\tnumber = {2},\\n\\tdate = {1984},\\n\\tpages = {97--111},\\n\\ttitle = {Literate {Programming}},\\n\\tvolume = {27},\\n}\\n\\n\\n\"},{\"exportBibtex\":\"@misc{WordPressBlock,\\n\\tauthor = {{WordPress.org}},\\n\\ttitle = {Block {Editor} {Handbook}},\\n\\turl = {https://developer.wordpress.org/block-editor/},\\n\\thowpublished = {https://developer.wordpress.org/block-editor/},\\n}\\n\\n\\n\",\"exportBiblatex\":\"@online{WordPressBlock,\\n\\tauthor = {{WordPress.org}},\\n\\tbooktitle = {WordPress {Developer} {Resources}},\\n\\ttitle = {Block {Editor} {Handbook}},\\n\\turl = {https://developer.wordpress.org/block-editor/},\\n}\\n\\n\\n\"}]},{\"title\":\"APA 7 author-date\",\"description\":\"Journal articles and an arXiv preprint in APA style, with DOIs as links.\",\"attributes\":{\"bibliographyId\":\"demo-apa-7\",\"citationStyle\":\"apa-7\",\"headingText\":\"References\",\"outputJsonLd\":true,\"outputCoins\":false,\"outputCslJson\":false,\"outputCiteExport\":false},\"citations\":[{\"type\":\"article-journal\",\"title\":\"Deep learning\",\"author\":[{\"family\":\"LeCun\",\"given\":\"Yann\"},{\"family\":\"Bengio\",\"given\":\"Yoshua\"},{\"family\":\"Hinton\",\"given\":\"Geoffrey\"}],\"container-title\":\"Nature\",\"volume\":\"521\",\"issue\":\"7553\",\"page\":\"436-444\",\"DOI\":\"10.1038/nature14539\",\"issued\":{\"date-parts\":[[2015]]}},{\"type\":\"article\",\"title\":\"Attention is all you need\",\"author\":[{\"family\":\"Vaswani\",\"given\":\"Ashish\"},{\"family\":\"Shazeer\",\"given\":\"Noam\"},{\"family\":\"Parmar\",\"given\":\"Niki\"},{\"family\":\"Uszkoreit\",\"given\":\"Jakob\"},{\"family\":\"Jones\",\"given\":\"Llion\"},{\"family\":\"Gomez\",\"given\":\"Aidan N.\"},{\"family\":\"Kaiser\",\"given\":\"Łukasz\"},{\"family\":\"Polosukhin\",\"given\":\"Illia\"}],\"publisher\":\"arXiv\",\"number\":\"1706.03762\",\"DOI\":\"10.48550/arXiv.1706.03762\",\"issued\":{\"date-parts\":[[2017]]}},{\"type\":\"article-journal\",\"title\":\"Computing machinery and intelligence\",\"author\":[{\"family\":\"Turing\",\"given\":\"A. M.\"}],\"container-title\":\"Mind\",\"volume\":\"59\",\"issue\":\"236\",\"page\":\"433-460\",\"DOI\":\"10.1093/mind/LIX.236.433\",\"issued\":{\"date-parts\":[[1950]]}}]},{\"title\":\"IEEE numeric\",\"description\":\"Numbered entries keep the order you give them. Select the block and use Move citation up/down to renumber.\",\"attributes\":{\"bibliographyId\":\"demo-ieee\",\"citationStyle\":\"ieee\",\"headingText\":\"References\",\"outputJsonLd\":true,\"outputCoins\":false,\"outputCslJson\":false,\"outputCiteExport\":false},\"citations\":[{\"type\":\"article-journal\",\"title\":\"A Mathematical Theory of Communication\",\"author\":[{\"family\":\"Shannon\",\"given\":\"Claude E.\"}],\"container-title\":\"Bell System Technical Journal\",\"volume\":\"27\",\"issue\":\"3\",\"page\":\"379-423\",\"DOI\":\"10.1002/j.1538-7305.1948.tb01338.x\",\"issued\":{\"date-parts\":[[1948]]}},{\"type\":\"article-journal\",\"title\":\"Computing Machinery and Intelligence\",\"author\":[{\"family\":\"Turing\",\"given\":\"A. M.\"}],\"container-title\":\"Mind\",\"volume\":\"59\",\"issue\":\"236\",\"page\":\"433-460\",\"DOI\":\"10.1093/mind/LIX.236.433\",\"issued\":{\"date-parts\":[[1950]]}},{\"type\":\"article-journal\",\"title\":\"Literate Programming\",\"author\":[{\"family\":\"Knuth\",\"given\":\"Donald E.\"}],\"container-title\":\"The Computer Journal\",\"volume\":\"27\",\"issue\":\"2\",\"page\":\"97-111\",\"DOI\":\"10.1093/comjnl/27.2.97\",\"issued\":{\"date-parts\":[[1984]]}}]}]}\nJSON;\n/**\n * Playground demo page builder.\n *\n * `npm run playground:build` inlines this file into each demo blueprint's\n * runPHP step, after defining:\n *\n * - $borges_demo_json The contents of playground/demo-content.json.\n * - $borges_demo_intro An HTML lead paragraph for that blueprint.\n *\n * It rewrites post 1 as the demo page the blueprint lands on, and turns off\n * the editor's Welcome Guide so the page is visible straight away. Example\n * bibliographies are formatted with the plugin's own citeproc formatter and\n * rendered with its PHP port of save(), so they validate against whatever\n * version is installed. A release without that port (before 1.7.0) gets a\n * note instead.\n *\n * Not part of the plugin package (playground/ is in .distignore).\n *\n * @package BibliographyBuilder\n */\n\nrequire_once '/wordpress/wp-load.php';\n\n// Write as the admin, and keep kses from stripping the blocks' JSON-LD\n// scripts and data attributes: kses_init() ran before any user was set.\nwp_set_current_user( 1 );\nkses_remove_filters();\n\n$borges_demo = json_decode( $borges_demo_json, true );\n\n$borges_demo_block = static function ( $name, $attrs, $html ) {\n\treturn serialize_block(\n\t\tarray(\n\t\t\t'blockName' => $name,\n\t\t\t'attrs' => $attrs,\n\t\t\t'innerBlocks' => array(),\n\t\t\t'innerHTML' => $html,\n\t\t\t'innerContent' => array( $html ),\n\t\t)\n\t) . \"\\n\\n\";\n};\n\n$borges_demo_paragraph = static function ( $html ) use ( $borges_demo_block ) {\n\treturn $borges_demo_block( 'core/paragraph', array(), '' . $html . '
' );\n};\n\n$borges_demo_heading = static function ( $text, $level ) use ( $borges_demo_block ) {\n\t$attrs = 2 === $level ? array() : array( 'level' => $level );\n\t$tag = 'h' . $level;\n\n\treturn $borges_demo_block( 'core/heading', $attrs, '<' . $tag . ' class=\"wp-block-heading\">' . esc_html( $text ) . '' . $tag . '>' );\n};\n\n$borges_demo_code = static function ( $text ) use ( $borges_demo_block ) {\n\treturn $borges_demo_block(\n\t\t'core/code',\n\t\tarray(),\n\t\t'' . htmlspecialchars( $text, ENT_NOQUOTES, 'UTF-8' ) . ''\n\t);\n};\n\n$borges_demo_list = static function ( $items ) {\n\t$html = \"\\nWelcome to Borges Bibliography Builder. Use the Bibliography block below, then paste one or more sample entries into the Paste / Import field (separate entries with a blank line).
\n\n\n\n10.1145/3368089.3409742\n\n10.1038/s41586-020-2649-2\n\nPMID:26673779\n\nPMC3531190\n\narXiv:1706.03762\n\nISBN 978-0-14-032872-1\n\n@article{knuth1984literate,\n author = {Knuth, Donald E.},\n title = {Literate Programming},\n journal = {The Computer Journal},\n year = {1984},\n volume = {27},\n number = {2},\n pages = {97--111},\n doi = {10.1093/comjnl/27.2.97}\n}\n\n\n\nTip: In the block sidebar, try changing citation style and export actions (CSL-JSON, BibTeX, RIS).
\n\n\n\nEOT;\n\nwp_update_post(\n\tarray(\n\t\t'ID' => 1,\n\t\t'post_title' => 'Borges Bibliography Playground Starter',\n\t\t'post_content' => $post_content,\n\t)\n);\n" + "code": "Welcome to Borges Bibliography Builder. This Playground runs the latest release. It is a sandbox: nothing here is kept after you close the tab.';\n$borges_demo_json = <<<'JSON'\n{\"title\":\"Borges Bibliography Builder demo\",\"sampleGroups\":[{\"title\":\"DOIs\",\"description\":\"A bare DOI, adoi: prefix, or a doi.org link. Metadata comes from Crossref.\",\"samples\":[{\"format\":\"doi\",\"input\":\"10.1038/s41586-020-2649-2\"},{\"format\":\"doi\",\"input\":\"doi:10.1038/nature14539\"},{\"format\":\"doi\",\"input\":\"https://doi.org/10.1145/3368089.3409742\"}]},{\"title\":\"PubMed and PubMed Central\",\"description\":\"A PMID needs its PMID: label. A PMCID starts with PMC, with or without a PMCID: label.\",\"samples\":[{\"format\":\"pmid\",\"input\":\"PMID:26673779\"},{\"format\":\"pmcid\",\"input\":\"PMC3531190\"}]},{\"title\":\"arXiv\",\"description\":\"An arXiv: ID (modern or legacy), an arxiv.org link, or an arXiv DOI.\",\"samples\":[{\"format\":\"arxiv\",\"input\":\"arXiv:1706.03762\"},{\"format\":\"arxiv\",\"input\":\"https://arxiv.org/abs/1810.04805\"},{\"format\":\"arxiv\",\"input\":\"arXiv:hep-th/9711200\"},{\"format\":\"arxiv\",\"input\":\"10.48550/arXiv.2005.14165\"}]},{\"title\":\"ISBNs\",\"description\":\"A labeled ISBN-13 or ISBN-10, or a bare ISBN-13 starting with 978 or 979. Books come from Open Library, with Google Books as a fallback.\",\"samples\":[{\"format\":\"isbn\",\"input\":\"ISBN 978-0-14-032872-1\"},{\"format\":\"isbn\",\"input\":\"9780262033848\"},{\"format\":\"isbn\",\"input\":\"ISBN-10: 0-8112-0012-4\"}]},{\"title\":\"BibTeX and BibLaTeX\",\"description\":\"Whole entries, one or many. BibLaTeX fields such as date and location are understood.\",\"samples\":[{\"format\":\"bibtex\",\"input\":\"@article{knuth1984literate,\\n author = {Knuth, Donald E.},\\n title = {Literate Programming},\\n journal = {The Computer Journal},\\n year = {1984},\\n volume = {27},\\n number = {2},\\n pages = {97--111},\\n doi = {10.1093/comjnl/27.2.97}\\n}\"},{\"format\":\"bibtex\",\"input\":\"@book{borges1962labyrinths,\\n author = {Borges, Jorge Luis},\\n title = {Labyrinths: Selected Stories and Other Writings},\\n editor = {Yates, Donald A. and Irby, James E.},\\n date = {1962},\\n publisher = {New Directions},\\n location = {New York}\\n}\"}]},{\"title\":\"Formatted citations\",\"description\":\"Plain-text citations for books, journal articles, chapters, and webpages, in Chicago or APA shape. A citation that contains a DOI, PMID, PMCID, or arXiv ID is looked up by that identifier instead.\",\"samples\":[{\"format\":\"freetext\",\"input\":\"Binder, Amy J., and Jeffrey L. Kidder. The Channels of Student Activism: How the Left and Right Are Winning (and Losing) in Campus Politics Today. University of Chicago Press, 2022.\"},{\"format\":\"freetext\",\"input\":\"Dittmar, Emily L., and Douglas W. Schemske. “Temporal Variation in Selection Influences Microgeographic Local Adaptation.” American Naturalist 202, no. 4 (2023): 471–85.\"},{\"format\":\"freetext\",\"input\":\"Doyle, Kathleen. “The Queen Mary Psalter.” In The Book by Design: The Remarkable Story of the World’s Greatest Invention, edited by P. J. M. Marks and Stephen Parkin. University of Chicago Press, 2023.\"},{\"format\":\"freetext\",\"input\":\"Yale University. “About Yale: Yale Facts.” Accessed March 8, 2022. https://www.yale.edu/about-yale/yale-facts.\"},{\"format\":\"doi\",\"embedded\":true,\"input\":\"Dittmar, Emily L., and Douglas W. Schemske. “Temporal Variation in Selection Influences Microgeographic Local Adaptation.” American Naturalist 202, no. 4 (2023): 471–85. https://doi.org/10.1086/725865.\"}]}],\"features\":[\"Citation Style (block sidebar): switch among Chicago, APA, MLA, Harvard, IEEE, Vancouver, OSCOLA, ABNT, and more. Generated text reformats; your manual edits are kept.\",\"Edit an entry: select a citation and use its edit button to correct fields. Reset edits restores the generated text.\",\"Manual Entry: next to Paste / Import, add a citation field by field when there is nothing to paste.\",\"Duplicates: paste a DOI that is already in the list; it is skipped, not added twice.\",\"Order: notes and author-date styles sort alphabetically. Numeric styles (IEEE, Vancouver) keep your order; use Move citation up/down.\",\"Exports (block toolbar): copy the bibliography as text, or download BibTeX, BibLaTeX, RIS, or CSL-JSON.\",\"Per-entry Cite / Export (sidebar): gives readers copy and download links under each entry on the published page.\",\"Machine-readable output (sidebar): JSON-LD for search engines (on by default), COinS for Zotero, and embedded CSL-JSON.\",\"Front end: use View Post to see the published bibliography, then open its read-only REST data.\"],\"examples\":[{\"title\":\"Chicago notes-bibliography, with Cite / Export\",\"description\":\"A book, a chapter, a journal article, and a webpage, sorted alphabetically. Per-entry Cite / Export and COinS are on; view the post to try the copy and download links.\",\"attributes\":{\"bibliographyId\":\"demo-chicago-notes\",\"citationStyle\":\"chicago-notes-bibliography\",\"headingText\":\"Works Cited\",\"outputJsonLd\":true,\"outputCoins\":true,\"outputCslJson\":false,\"outputCiteExport\":true},\"citations\":[{\"type\":\"book\",\"title\":\"Labyrinths: Selected Stories and Other Writings\",\"author\":[{\"family\":\"Borges\",\"given\":\"Jorge Luis\"}],\"editor\":[{\"family\":\"Yates\",\"given\":\"Donald A.\"},{\"family\":\"Irby\",\"given\":\"James E.\"}],\"publisher\":\"New Directions\",\"publisher-place\":\"New York\",\"issued\":{\"date-parts\":[[1962]]}},{\"type\":\"chapter\",\"title\":\"The Library of Babel\",\"author\":[{\"family\":\"Borges\",\"given\":\"Jorge Luis\"}],\"translator\":[{\"family\":\"Irby\",\"given\":\"James E.\"}],\"container-title\":\"Labyrinths: Selected Stories and Other Writings\",\"editor\":[{\"family\":\"Yates\",\"given\":\"Donald A.\"},{\"family\":\"Irby\",\"given\":\"James E.\"}],\"publisher\":\"New Directions\",\"publisher-place\":\"New York\",\"issued\":{\"date-parts\":[[1962]]}},{\"type\":\"article-journal\",\"title\":\"Literate Programming\",\"author\":[{\"family\":\"Knuth\",\"given\":\"Donald E.\"}],\"container-title\":\"The Computer Journal\",\"volume\":\"27\",\"issue\":\"2\",\"page\":\"97-111\",\"DOI\":\"10.1093/comjnl/27.2.97\",\"issued\":{\"date-parts\":[[1984]]}},{\"type\":\"webpage\",\"title\":\"Block Editor Handbook\",\"author\":[{\"literal\":\"WordPress.org\"}],\"container-title\":\"WordPress Developer Resources\",\"URL\":\"https://developer.wordpress.org/block-editor/\"}],\"exports\":[{\"exportBibtex\":\"@book{Borges1962Labyrinths,\\n\\taddress = {New York},\\n\\tauthor = {Borges, Jorge Luis},\\n\\teditor = {Yates, Donald A. and Irby, James E.},\\n\\tyear = {1962},\\n\\tpublisher = {New Directions},\\n\\ttitle = {Labyrinths: Selected {Stories} and {Other} {Writings}},\\n}\\n\\n\\n\",\"exportBiblatex\":\"@book{Borges1962Labyrinths,\\n\\tauthor = {Borges, Jorge Luis},\\n\\teditor = {Yates, Donald A. and Irby, James E.},\\n\\tdate = {1962},\\n\\tlocation = {New York},\\n\\tpublisher = {New Directions},\\n\\ttitle = {Labyrinths: Selected {Stories} and {Other} {Writings}},\\n}\\n\\n\\n\"},{\"exportBibtex\":\"@inbook{Borges1962Library,\\n\\taddress = {New York},\\n\\tauthor = {Borges, Jorge Luis},\\n\\tbooktitle = {Labyrinths: Selected {Stories} and {Other} {Writings}},\\n\\teditor = {Yates, Donald A. and Irby, James E.},\\n\\tyear = {1962},\\n\\tpublisher = {New Directions},\\n\\ttitle = {The {Library} of {Babel}},\\n}\\n\\n\\n\",\"exportBiblatex\":\"@inbook{Borges1962Library,\\n\\tauthor = {Borges, Jorge Luis},\\n\\tbooktitle = {Labyrinths: Selected {Stories} and {Other} {Writings}},\\n\\teditor = {Yates, Donald A. and Irby, James E.},\\n\\tdate = {1962},\\n\\tlocation = {New York},\\n\\tpublisher = {New Directions},\\n\\ttitle = {The {Library} of {Babel}},\\n\\ttranslator = {Irby, James E.},\\n}\\n\\n\\n\"},{\"exportBibtex\":\"@article{Knuth1984Literate,\\n\\tauthor = {Knuth, Donald E.},\\n\\tjournal = {The Computer Journal},\\n\\tdoi = {10.1093/comjnl/27.2.97},\\n\\tnumber = {2},\\n\\tyear = {1984},\\n\\tpages = {97--111},\\n\\ttitle = {Literate {Programming}},\\n\\tvolume = {27},\\n}\\n\\n\\n\",\"exportBiblatex\":\"@article{Knuth1984Literate,\\n\\tauthor = {Knuth, Donald E.},\\n\\tjournaltitle = {The Computer Journal},\\n\\tdoi = {10.1093/comjnl/27.2.97},\\n\\tnumber = {2},\\n\\tdate = {1984},\\n\\tpages = {97--111},\\n\\ttitle = {Literate {Programming}},\\n\\tvolume = {27},\\n}\\n\\n\\n\"},{\"exportBibtex\":\"@misc{WordPressBlock,\\n\\tauthor = {{WordPress.org}},\\n\\ttitle = {Block {Editor} {Handbook}},\\n\\turl = {https://developer.wordpress.org/block-editor/},\\n\\thowpublished = {https://developer.wordpress.org/block-editor/},\\n}\\n\\n\\n\",\"exportBiblatex\":\"@online{WordPressBlock,\\n\\tauthor = {{WordPress.org}},\\n\\tbooktitle = {WordPress {Developer} {Resources}},\\n\\ttitle = {Block {Editor} {Handbook}},\\n\\turl = {https://developer.wordpress.org/block-editor/},\\n}\\n\\n\\n\"}]},{\"title\":\"APA 7 author-date\",\"description\":\"Journal articles and an arXiv preprint in APA style, with DOIs as links.\",\"attributes\":{\"bibliographyId\":\"demo-apa-7\",\"citationStyle\":\"apa-7\",\"headingText\":\"References\",\"outputJsonLd\":true,\"outputCoins\":false,\"outputCslJson\":false,\"outputCiteExport\":false},\"citations\":[{\"type\":\"article-journal\",\"title\":\"Deep learning\",\"author\":[{\"family\":\"LeCun\",\"given\":\"Yann\"},{\"family\":\"Bengio\",\"given\":\"Yoshua\"},{\"family\":\"Hinton\",\"given\":\"Geoffrey\"}],\"container-title\":\"Nature\",\"volume\":\"521\",\"issue\":\"7553\",\"page\":\"436-444\",\"DOI\":\"10.1038/nature14539\",\"issued\":{\"date-parts\":[[2015]]}},{\"type\":\"article\",\"title\":\"Attention is all you need\",\"author\":[{\"family\":\"Vaswani\",\"given\":\"Ashish\"},{\"family\":\"Shazeer\",\"given\":\"Noam\"},{\"family\":\"Parmar\",\"given\":\"Niki\"},{\"family\":\"Uszkoreit\",\"given\":\"Jakob\"},{\"family\":\"Jones\",\"given\":\"Llion\"},{\"family\":\"Gomez\",\"given\":\"Aidan N.\"},{\"family\":\"Kaiser\",\"given\":\"Łukasz\"},{\"family\":\"Polosukhin\",\"given\":\"Illia\"}],\"publisher\":\"arXiv\",\"number\":\"1706.03762\",\"DOI\":\"10.48550/arXiv.1706.03762\",\"issued\":{\"date-parts\":[[2017]]}},{\"type\":\"article-journal\",\"title\":\"Computing machinery and intelligence\",\"author\":[{\"family\":\"Turing\",\"given\":\"A. M.\"}],\"container-title\":\"Mind\",\"volume\":\"59\",\"issue\":\"236\",\"page\":\"433-460\",\"DOI\":\"10.1093/mind/LIX.236.433\",\"issued\":{\"date-parts\":[[1950]]}}]},{\"title\":\"IEEE numeric\",\"description\":\"Numbered entries keep the order you give them. Select the block and use Move citation up/down to renumber.\",\"attributes\":{\"bibliographyId\":\"demo-ieee\",\"citationStyle\":\"ieee\",\"headingText\":\"References\",\"outputJsonLd\":true,\"outputCoins\":false,\"outputCslJson\":false,\"outputCiteExport\":false},\"citations\":[{\"type\":\"article-journal\",\"title\":\"A Mathematical Theory of Communication\",\"author\":[{\"family\":\"Shannon\",\"given\":\"Claude E.\"}],\"container-title\":\"Bell System Technical Journal\",\"volume\":\"27\",\"issue\":\"3\",\"page\":\"379-423\",\"DOI\":\"10.1002/j.1538-7305.1948.tb01338.x\",\"issued\":{\"date-parts\":[[1948]]}},{\"type\":\"article-journal\",\"title\":\"Computing Machinery and Intelligence\",\"author\":[{\"family\":\"Turing\",\"given\":\"A. M.\"}],\"container-title\":\"Mind\",\"volume\":\"59\",\"issue\":\"236\",\"page\":\"433-460\",\"DOI\":\"10.1093/mind/LIX.236.433\",\"issued\":{\"date-parts\":[[1950]]}},{\"type\":\"article-journal\",\"title\":\"Literate Programming\",\"author\":[{\"family\":\"Knuth\",\"given\":\"Donald E.\"}],\"container-title\":\"The Computer Journal\",\"volume\":\"27\",\"issue\":\"2\",\"page\":\"97-111\",\"DOI\":\"10.1093/comjnl/27.2.97\",\"issued\":{\"date-parts\":[[1984]]}}]}]}\nJSON;\n/**\n * Playground demo page builder.\n *\n * `npm run playground:build` inlines this file into each demo blueprint's\n * runPHP step, after defining:\n *\n * - $borges_demo_json The contents of playground/demo-content.json.\n * - $borges_demo_intro An HTML lead paragraph for that blueprint.\n *\n * It rewrites post 1 as the demo page the blueprint lands on, and turns off\n * the editor's Welcome Guide so the page is visible straight away. Example\n * bibliographies are formatted with the plugin's own citeproc formatter and\n * rendered with its PHP port of save(), so they validate against whatever\n * version is installed. A release without that port (before 1.7.0) gets a\n * note instead.\n *\n * Not part of the plugin package (playground/ is in .distignore).\n *\n * @package BibliographyBuilder\n */\n\nrequire_once '/wordpress/wp-load.php';\n\n// Write as the admin, and keep kses from stripping the blocks' JSON-LD\n// scripts and data attributes: kses_init() ran before any user was set.\nwp_set_current_user( 1 );\nkses_remove_filters();\n\n$borges_demo = json_decode( $borges_demo_json, true );\n\n$borges_demo_block = static function ( $name, $attrs, $html ) {\n\treturn serialize_block(\n\t\tarray(\n\t\t\t'blockName' => $name,\n\t\t\t'attrs' => $attrs,\n\t\t\t'innerBlocks' => array(),\n\t\t\t'innerHTML' => $html,\n\t\t\t'innerContent' => array( $html ),\n\t\t)\n\t) . \"\\n\\n\";\n};\n\n$borges_demo_paragraph = static function ( $html ) use ( $borges_demo_block ) {\n\treturn $borges_demo_block( 'core/paragraph', array(), '' . $html . '
' );\n};\n\n$borges_demo_heading = static function ( $text, $level ) use ( $borges_demo_block ) {\n\t$attrs = 2 === $level ? array() : array( 'level' => $level );\n\t$tag = 'h' . $level;\n\n\treturn $borges_demo_block( 'core/heading', $attrs, '<' . $tag . ' class=\"wp-block-heading\">' . esc_html( $text ) . '' . $tag . '>' );\n};\n\n$borges_demo_code = static function ( $text ) use ( $borges_demo_block ) {\n\treturn $borges_demo_block(\n\t\t'core/code',\n\t\tarray(),\n\t\t'' . htmlspecialchars( $text, ENT_NOQUOTES, 'UTF-8' ) . ''\n\t);\n};\n\n$borges_demo_list = static function ( $items ) {\n\t$html = \"\\ndoi: prefix, or a doi.org link. Metadata comes from Crossref.",
+ "samples": [
+ { "format": "doi", "input": "10.1038/s41586-020-2649-2" },
+ { "format": "doi", "input": "doi:10.1038/nature14539" },
+ { "format": "doi", "input": "https://doi.org/10.1145/3368089.3409742" }
+ ]
+ },
+ {
+ "title": "PubMed and PubMed Central",
+ "description": "A PMID needs its PMID: label. A PMCID starts with PMC, with or without a PMCID: label.",
+ "samples": [
+ { "format": "pmid", "input": "PMID:26673779" },
+ { "format": "pmcid", "input": "PMC3531190" }
+ ]
+ },
+ {
+ "title": "arXiv",
+ "description": "An arXiv: ID (modern or legacy), an arxiv.org link, or an arXiv DOI.",
+ "samples": [
+ { "format": "arxiv", "input": "arXiv:1706.03762" },
+ { "format": "arxiv", "input": "https://arxiv.org/abs/1810.04805" },
+ { "format": "arxiv", "input": "arXiv:hep-th/9711200" },
+ { "format": "arxiv", "input": "10.48550/arXiv.2005.14165" }
+ ]
+ },
+ {
+ "title": "ISBNs",
+ "description": "A labeled ISBN-13 or ISBN-10, or a bare ISBN-13 starting with 978 or 979. Books come from Open Library, with Google Books as a fallback.",
+ "samples": [
+ { "format": "isbn", "input": "ISBN 978-0-14-032872-1" },
+ { "format": "isbn", "input": "9780262033848" },
+ { "format": "isbn", "input": "ISBN-10: 0-8112-0012-4" }
+ ]
+ },
+ {
+ "title": "BibTeX and BibLaTeX",
+ "description": "Whole entries, one or many. BibLaTeX fields such as date and location are understood.",
+ "samples": [
+ {
+ "format": "bibtex",
+ "input": "@article{knuth1984literate,\n author = {Knuth, Donald E.},\n title = {Literate Programming},\n journal = {The Computer Journal},\n year = {1984},\n volume = {27},\n number = {2},\n pages = {97--111},\n doi = {10.1093/comjnl/27.2.97}\n}"
+ },
+ {
+ "format": "bibtex",
+ "input": "@book{borges1962labyrinths,\n author = {Borges, Jorge Luis},\n title = {Labyrinths: Selected Stories and Other Writings},\n editor = {Yates, Donald A. and Irby, James E.},\n date = {1962},\n publisher = {New Directions},\n location = {New York}\n}"
+ }
+ ]
+ },
+ {
+ "title": "Formatted citations",
+ "description": "Plain-text citations for books, journal articles, chapters, and webpages, in Chicago or APA shape. A citation that contains a DOI, PMID, PMCID, or arXiv ID is looked up by that identifier instead.",
+ "samples": [
+ {
+ "format": "freetext",
+ "input": "Binder, Amy J., and Jeffrey L. Kidder. The Channels of Student Activism: How the Left and Right Are Winning (and Losing) in Campus Politics Today. University of Chicago Press, 2022."
+ },
+ {
+ "format": "freetext",
+ "input": "Dittmar, Emily L., and Douglas W. Schemske. “Temporal Variation in Selection Influences Microgeographic Local Adaptation.” American Naturalist 202, no. 4 (2023): 471–85."
+ },
+ {
+ "format": "freetext",
+ "input": "Doyle, Kathleen. “The Queen Mary Psalter.” In The Book by Design: The Remarkable Story of the World’s Greatest Invention, edited by P. J. M. Marks and Stephen Parkin. University of Chicago Press, 2023."
+ },
+ {
+ "format": "freetext",
+ "input": "Yale University. “About Yale: Yale Facts.” Accessed March 8, 2022. https://www.yale.edu/about-yale/yale-facts."
+ },
+ {
+ "format": "doi",
+ "embedded": true,
+ "input": "Dittmar, Emily L., and Douglas W. Schemske. “Temporal Variation in Selection Influences Microgeographic Local Adaptation.” American Naturalist 202, no. 4 (2023): 471–85. https://doi.org/10.1086/725865."
+ }
+ ]
+ }
+ ],
+ "features": [
+ "Citation Style (block sidebar): switch among Chicago, APA, MLA, Harvard, IEEE, Vancouver, OSCOLA, ABNT, and more. Generated text reformats; your manual edits are kept.",
+ "Edit an entry: select a citation and use its edit button to correct fields. Reset edits restores the generated text.",
+ "Manual Entry: next to Paste / Import, add a citation field by field when there is nothing to paste.",
+ "Duplicates: paste a DOI that is already in the list; it is skipped, not added twice.",
+ "Order: notes and author-date styles sort alphabetically. Numeric styles (IEEE, Vancouver) keep your order; use Move citation up/down.",
+ "Exports (block toolbar): copy the bibliography as text, or download BibTeX, BibLaTeX, RIS, or CSL-JSON.",
+ "Per-entry Cite / Export (sidebar): gives readers copy and download links under each entry on the published page.",
+ "Machine-readable output (sidebar): JSON-LD for search engines (on by default), COinS for Zotero, and embedded CSL-JSON.",
+ "Front end: use View Post to see the published bibliography, then open its read-only REST data."
+ ],
+ "examples": [
+ {
+ "title": "Chicago notes-bibliography, with Cite / Export",
+ "description": "A book, a chapter, a journal article, and a webpage, sorted alphabetically. Per-entry Cite / Export and COinS are on; view the post to try the copy and download links.",
+ "attributes": {
+ "bibliographyId": "demo-chicago-notes",
+ "citationStyle": "chicago-notes-bibliography",
+ "headingText": "Works Cited",
+ "outputJsonLd": true,
+ "outputCoins": true,
+ "outputCslJson": false,
+ "outputCiteExport": true
+ },
+ "citations": [
+ {
+ "type": "book",
+ "title": "Labyrinths: Selected Stories and Other Writings",
+ "author": [{ "family": "Borges", "given": "Jorge Luis" }],
+ "editor": [
+ { "family": "Yates", "given": "Donald A." },
+ { "family": "Irby", "given": "James E." }
+ ],
+ "publisher": "New Directions",
+ "publisher-place": "New York",
+ "issued": { "date-parts": [[1962]] }
+ },
+ {
+ "type": "chapter",
+ "title": "The Library of Babel",
+ "author": [{ "family": "Borges", "given": "Jorge Luis" }],
+ "translator": [{ "family": "Irby", "given": "James E." }],
+ "container-title": "Labyrinths: Selected Stories and Other Writings",
+ "editor": [
+ { "family": "Yates", "given": "Donald A." },
+ { "family": "Irby", "given": "James E." }
+ ],
+ "publisher": "New Directions",
+ "publisher-place": "New York",
+ "issued": { "date-parts": [[1962]] }
+ },
+ {
+ "type": "article-journal",
+ "title": "Literate Programming",
+ "author": [{ "family": "Knuth", "given": "Donald E." }],
+ "container-title": "The Computer Journal",
+ "volume": "27",
+ "issue": "2",
+ "page": "97-111",
+ "DOI": "10.1093/comjnl/27.2.97",
+ "issued": { "date-parts": [[1984]] }
+ },
+ {
+ "type": "webpage",
+ "title": "Block Editor Handbook",
+ "author": [{ "literal": "WordPress.org" }],
+ "container-title": "WordPress Developer Resources",
+ "URL": "https://developer.wordpress.org/block-editor/"
+ }
+ ],
+ "exports": [
+ {
+ "exportBibtex": "@book{Borges1962Labyrinths,\n\taddress = {New York},\n\tauthor = {Borges, Jorge Luis},\n\teditor = {Yates, Donald A. and Irby, James E.},\n\tyear = {1962},\n\tpublisher = {New Directions},\n\ttitle = {Labyrinths: Selected {Stories} and {Other} {Writings}},\n}\n\n\n",
+ "exportBiblatex": "@book{Borges1962Labyrinths,\n\tauthor = {Borges, Jorge Luis},\n\teditor = {Yates, Donald A. and Irby, James E.},\n\tdate = {1962},\n\tlocation = {New York},\n\tpublisher = {New Directions},\n\ttitle = {Labyrinths: Selected {Stories} and {Other} {Writings}},\n}\n\n\n"
+ },
+ {
+ "exportBibtex": "@inbook{Borges1962Library,\n\taddress = {New York},\n\tauthor = {Borges, Jorge Luis},\n\tbooktitle = {Labyrinths: Selected {Stories} and {Other} {Writings}},\n\teditor = {Yates, Donald A. and Irby, James E.},\n\tyear = {1962},\n\tpublisher = {New Directions},\n\ttitle = {The {Library} of {Babel}},\n}\n\n\n",
+ "exportBiblatex": "@inbook{Borges1962Library,\n\tauthor = {Borges, Jorge Luis},\n\tbooktitle = {Labyrinths: Selected {Stories} and {Other} {Writings}},\n\teditor = {Yates, Donald A. and Irby, James E.},\n\tdate = {1962},\n\tlocation = {New York},\n\tpublisher = {New Directions},\n\ttitle = {The {Library} of {Babel}},\n\ttranslator = {Irby, James E.},\n}\n\n\n"
+ },
+ {
+ "exportBibtex": "@article{Knuth1984Literate,\n\tauthor = {Knuth, Donald E.},\n\tjournal = {The Computer Journal},\n\tdoi = {10.1093/comjnl/27.2.97},\n\tnumber = {2},\n\tyear = {1984},\n\tpages = {97--111},\n\ttitle = {Literate {Programming}},\n\tvolume = {27},\n}\n\n\n",
+ "exportBiblatex": "@article{Knuth1984Literate,\n\tauthor = {Knuth, Donald E.},\n\tjournaltitle = {The Computer Journal},\n\tdoi = {10.1093/comjnl/27.2.97},\n\tnumber = {2},\n\tdate = {1984},\n\tpages = {97--111},\n\ttitle = {Literate {Programming}},\n\tvolume = {27},\n}\n\n\n"
+ },
+ {
+ "exportBibtex": "@misc{WordPressBlock,\n\tauthor = {{WordPress.org}},\n\ttitle = {Block {Editor} {Handbook}},\n\turl = {https://developer.wordpress.org/block-editor/},\n\thowpublished = {https://developer.wordpress.org/block-editor/},\n}\n\n\n",
+ "exportBiblatex": "@online{WordPressBlock,\n\tauthor = {{WordPress.org}},\n\tbooktitle = {WordPress {Developer} {Resources}},\n\ttitle = {Block {Editor} {Handbook}},\n\turl = {https://developer.wordpress.org/block-editor/},\n}\n\n\n"
+ }
+ ]
+ },
+ {
+ "title": "APA 7 author-date",
+ "description": "Journal articles and an arXiv preprint in APA style, with DOIs as links.",
+ "attributes": {
+ "bibliographyId": "demo-apa-7",
+ "citationStyle": "apa-7",
+ "headingText": "References",
+ "outputJsonLd": true,
+ "outputCoins": false,
+ "outputCslJson": false,
+ "outputCiteExport": false
+ },
+ "citations": [
+ {
+ "type": "article-journal",
+ "title": "Deep learning",
+ "author": [
+ { "family": "LeCun", "given": "Yann" },
+ { "family": "Bengio", "given": "Yoshua" },
+ { "family": "Hinton", "given": "Geoffrey" }
+ ],
+ "container-title": "Nature",
+ "volume": "521",
+ "issue": "7553",
+ "page": "436-444",
+ "DOI": "10.1038/nature14539",
+ "issued": { "date-parts": [[2015]] }
+ },
+ {
+ "type": "article",
+ "title": "Attention is all you need",
+ "author": [
+ { "family": "Vaswani", "given": "Ashish" },
+ { "family": "Shazeer", "given": "Noam" },
+ { "family": "Parmar", "given": "Niki" },
+ { "family": "Uszkoreit", "given": "Jakob" },
+ { "family": "Jones", "given": "Llion" },
+ { "family": "Gomez", "given": "Aidan N." },
+ { "family": "Kaiser", "given": "Łukasz" },
+ { "family": "Polosukhin", "given": "Illia" }
+ ],
+ "publisher": "arXiv",
+ "number": "1706.03762",
+ "DOI": "10.48550/arXiv.1706.03762",
+ "issued": { "date-parts": [[2017]] }
+ },
+ {
+ "type": "article-journal",
+ "title": "Computing machinery and intelligence",
+ "author": [{ "family": "Turing", "given": "A. M." }],
+ "container-title": "Mind",
+ "volume": "59",
+ "issue": "236",
+ "page": "433-460",
+ "DOI": "10.1093/mind/LIX.236.433",
+ "issued": { "date-parts": [[1950]] }
+ }
+ ]
+ },
+ {
+ "title": "IEEE numeric",
+ "description": "Numbered entries keep the order you give them. Select the block and use Move citation up/down to renumber.",
+ "attributes": {
+ "bibliographyId": "demo-ieee",
+ "citationStyle": "ieee",
+ "headingText": "References",
+ "outputJsonLd": true,
+ "outputCoins": false,
+ "outputCslJson": false,
+ "outputCiteExport": false
+ },
+ "citations": [
+ {
+ "type": "article-journal",
+ "title": "A Mathematical Theory of Communication",
+ "author": [{ "family": "Shannon", "given": "Claude E." }],
+ "container-title": "Bell System Technical Journal",
+ "volume": "27",
+ "issue": "3",
+ "page": "379-423",
+ "DOI": "10.1002/j.1538-7305.1948.tb01338.x",
+ "issued": { "date-parts": [[1948]] }
+ },
+ {
+ "type": "article-journal",
+ "title": "Computing Machinery and Intelligence",
+ "author": [{ "family": "Turing", "given": "A. M." }],
+ "container-title": "Mind",
+ "volume": "59",
+ "issue": "236",
+ "page": "433-460",
+ "DOI": "10.1093/mind/LIX.236.433",
+ "issued": { "date-parts": [[1950]] }
+ },
+ {
+ "type": "article-journal",
+ "title": "Literate Programming",
+ "author": [{ "family": "Knuth", "given": "Donald E." }],
+ "container-title": "The Computer Journal",
+ "volume": "27",
+ "issue": "2",
+ "page": "97-111",
+ "DOI": "10.1093/comjnl/27.2.97",
+ "issued": { "date-parts": [[1984]] }
+ }
+ ]
+ }
+ ]
+}
diff --git a/playground/demo-content.php b/playground/demo-content.php
new file mode 100644
index 0000000..ea1b235
--- /dev/null
+++ b/playground/demo-content.php
@@ -0,0 +1,204 @@
+ $name,
+ 'attrs' => $attrs,
+ 'innerBlocks' => array(),
+ 'innerHTML' => $html,
+ 'innerContent' => array( $html ),
+ )
+ ) . "\n\n";
+};
+
+$borges_demo_paragraph = static function ( $html ) use ( $borges_demo_block ) {
+ return $borges_demo_block( 'core/paragraph', array(), '' . $html . '
' ); +}; + +$borges_demo_heading = static function ( $text, $level ) use ( $borges_demo_block ) { + $attrs = 2 === $level ? array() : array( 'level' => $level ); + $tag = 'h' . $level; + + return $borges_demo_block( 'core/heading', $attrs, '<' . $tag . ' class="wp-block-heading">' . esc_html( $text ) . '' . $tag . '>' ); +}; + +$borges_demo_code = static function ( $text ) use ( $borges_demo_block ) { + return $borges_demo_block( + 'core/code', + array(), + '' . htmlspecialchars( $text, ENT_NOQUOTES, 'UTF-8' ) . ''
+ );
+};
+
+$borges_demo_list = static function ( $items ) {
+ $html = "\nmain branch, not a stable release. It is a sandbox: nothing here is kept after you close the tab.',
+ },
+ { file: '.wordpress-org/blueprints/blueprint.json', intro: RELEASE_INTRO },
+];
+
+function phpSingleQuoted(value) {
+ return `'${value.replace(/\\/g, '\\\\').replace(/'/g, "\\'")}'`;
+}
+
+/**
+ * The runPHP code for one blueprint.
+ *
+ * @param {string} intro Lead paragraph HTML.
+ * @return {string} PHP source.
+ */
+function buildDemoCode(intro) {
+ const data = JSON.parse(
+ fs.readFileSync(path.join(ROOT, 'playground/demo-content.json'), 'utf8')
+ );
+ delete data.$comment;
+
+ const json = JSON.stringify(data);
+ if (/^JSON;?$/mu.test(json)) {
+ throw new Error('demo-content.json would end the PHP nowdoc early.');
+ }
+
+ const script = fs
+ .readFileSync(path.join(ROOT, 'playground/demo-content.php'), 'utf8')
+ .replace(/^<\?php\n/u, '');
+
+ return [
+ '} Blueprints.
+ */
+function buildBlueprints() {
+ return DEMO_BLUEPRINTS.map(({ file, intro }) => {
+ const absolute = path.join(ROOT, file);
+ const current = fs.readFileSync(absolute, 'utf8');
+ const blueprint = JSON.parse(current);
+ const steps = blueprint.steps.filter((step) => step.step !== 'runPHP');
+
+ steps.push({ step: 'runPHP', code: buildDemoCode(intro) });
+ blueprint.steps = steps;
+
+ return {
+ file,
+ current,
+ expected: `${JSON.stringify(blueprint, null, '\t')}\n`,
+ };
+ });
+}
+
+if (require.main === module) {
+ const check = process.argv.includes('--check');
+ const stale = [];
+
+ for (const { file, current, expected } of buildBlueprints()) {
+ if (current === expected) {
+ continue;
+ }
+
+ if (check) {
+ stale.push(file);
+ } else {
+ fs.writeFileSync(path.join(ROOT, file), expected);
+ process.stdout.write(`updated ${file}\n`);
+ }
+ }
+
+ if (stale.length) {
+ process.stderr.write(
+ `Stale Playground blueprints (run npm run playground:build): ${stale.join(
+ ', '
+ )}\n`
+ );
+ process.exit(1);
+ }
+}
+
+module.exports = { buildBlueprints, DEMO_BLUEPRINTS };
diff --git a/src/playground-demo.test.js b/src/playground-demo.test.js
new file mode 100644
index 0000000..1159ef2
--- /dev/null
+++ b/src/playground-demo.test.js
@@ -0,0 +1,136 @@
+/**
+ * The Playground demo page (playground/demo-content.json) promises that each
+ * sample works and that the example bibliographies open without unsaved
+ * changes. These tests hold it to that, and keep the generated blueprints in
+ * sync with their source.
+ */
+
+import { parsePastedInput, extractEmbeddedIdentifier } from './lib/parser';
+import { computeExportStrings } from './hooks/compute-export-strings';
+
+// No network: every resolver fails, so an identifier sample surfaces the error
+// of the backend it was routed to. BibTeX and free text parse locally.
+jest.mock('@wordpress/api-fetch', () =>
+ jest.fn(() => Promise.reject(new Error('offline')))
+);
+jest.mock('@citation-js/plugin-doi', () => ({}));
+
+const demo = require('../playground/demo-content.json');
+const { buildBlueprints } = require('../scripts/build-playground-blueprints');
+
+const offlineFetch = () => Promise.reject(new Error('offline'));
+
+const BACKEND_ERRORS = {
+ doi: /DOI/,
+ pmid: /PMID/,
+ pmcid: /PMCID/,
+ arxiv: /arXiv/,
+ isbn: /ISBN/,
+};
+
+const samples = demo.sampleGroups.flatMap((group) =>
+ group.samples.map((sample) => [group.title, sample])
+);
+
+describe('Playground demo samples', () => {
+ it('covers every supported input format', () => {
+ const formats = new Set(samples.map(([, sample]) => sample.format));
+
+ expect([...formats].sort()).toEqual(
+ [
+ 'arxiv',
+ 'bibtex',
+ 'doi',
+ 'freetext',
+ 'isbn',
+ 'pmcid',
+ 'pmid',
+ ].sort()
+ );
+ });
+
+ it('fits in a single paste', () => {
+ expect(samples.length).toBeLessThanOrEqual(50);
+ });
+
+ const LOCAL_FORMATS = ['bibtex', 'freetext'];
+
+ it.each(
+ samples.filter(
+ ([, s]) => !s.embedded && LOCAL_FORMATS.includes(s.format)
+ )
+ )('%s: %p parses locally', async (group, { format, input }) => {
+ const result = await parsePastedInput(input, undefined, {
+ fetchFn: offlineFetch,
+ });
+
+ expect(result.errors).toEqual([]);
+ expect(result.entries).toHaveLength(1);
+ expect(result.entries[0].inputFormat).toBe(format);
+ });
+
+ it.each(
+ samples.filter(
+ ([, s]) => !s.embedded && !LOCAL_FORMATS.includes(s.format)
+ )
+ )('%s: %p reaches its resolver', async (group, { format, input }) => {
+ const result = await parsePastedInput(input, undefined, {
+ fetchFn: offlineFetch,
+ });
+
+ expect(result.entries).toEqual([]);
+ expect(result.errors).toHaveLength(1);
+ expect(result.errors[0]).toMatch(BACKEND_ERRORS[format]);
+ });
+
+ it.each(samples.filter(([, s]) => s.embedded))(
+ '%s: %p is looked up by its embedded identifier',
+ async (group, { format, input }) => {
+ expect(extractEmbeddedIdentifier(input)).toMatchObject({ format });
+
+ // Offline, the lookup fails and the citation text still parses.
+ const result = await parsePastedInput(input, undefined, {
+ fetchFn: offlineFetch,
+ });
+ expect(result.errors).toEqual([]);
+ expect(result.entries).toHaveLength(1);
+ }
+ );
+});
+
+describe('Playground demo examples', () => {
+ const withCiteExport = demo.examples.filter(
+ (example) => example.attributes.outputCiteExport
+ );
+
+ it('has an example with Cite / Export', () => {
+ expect(withCiteExport.length).toBeGreaterThan(0);
+ });
+
+ it.each(withCiteExport.map((example) => [example.title, example]))(
+ '%s stores the export strings the editor computes',
+ async (title, example) => {
+ expect(example.exports).toEqual(
+ await computeExportStrings(
+ example.citations,
+ example.attributes.citationStyle
+ )
+ );
+ }
+ );
+
+ it('stores no export strings where Cite / Export is off', () => {
+ demo.examples
+ .filter((example) => !example.attributes.outputCiteExport)
+ .forEach((example) => expect(example.exports).toBeUndefined());
+ });
+});
+
+describe('Playground demo blueprints', () => {
+ it.each(buildBlueprints().map((blueprint) => [blueprint.file, blueprint]))(
+ '%s is built from the current demo content (npm run playground:build)',
+ (file, { current, expected }) => {
+ expect(current).toBe(expected);
+ }
+ );
+});