diff --git a/docs/executable-plugins.md b/docs/executable-plugins.md index 8cac122d4..0e4d3e585 100644 --- a/docs/executable-plugins.md +++ b/docs/executable-plugins.md @@ -8,18 +8,18 @@ MyST is able to invoke plugins written in different languages through standard I ## Defining a new directive :::{note} -There are many different ways to create an executable plugin. Here we'll use Python to implement an `unsplash-py` directive, but any programming language that can read and write from stdin, stdout, and stderr, and define a command line interface would work. +There are many different ways to create an executable plugin. Here we'll use Python to implement an `picsum-py` directive, but any programming language that can read and write from stdin, stdout, and stderr, and define a command line interface would work. ::: -First, we'll declare the plugin _specification_ that allows MyST to discover the directives, transforms, and/or roles that the plugin implements. This specification looks very similar to [the definition of a JavaScript plugin](javascript-plugins.md#unsplash-js-source), except the implementation logic (e.g. the directive `run` method) is not defined. +First, we'll declare the plugin _specification_ that allows MyST to discover the directives, transforms, and/or roles that the plugin implements. This specification looks very similar to [the definition of a JavaScript plugin](javascript-plugins.md#picsum-js-source), except the implementation logic (e.g. the directive `run` method) is not defined. -:::{literalinclude} unsplash.py -:caption: a plugin to add an `unsplash-py` directive that includes a beautiful, random picture based on a query string. +:::{literalinclude} picsum.py +:caption: A plugin to add an `picsum-py` directive that includes a beautiful, random picture based on a size and optional ID string. ::: this file should be executable, e.g. ```{code} shell -chmod +x ./unsplash.py +chmod +x ./picsum.py ``` and should be referenced from your `myst.yml` under the `projects.plugins`: @@ -29,7 +29,7 @@ and should be referenced from your `myst.yml` under the `projects.plugins`: project: plugins: - type: executable - path: unsplash.py + path: picsum.py ``` then start or build your document using `myst start` or `myst build`, and you will see that the plugin is loaded. @@ -37,18 +37,19 @@ then start or build your document using `myst start` or `myst build`, and you wi ```text myst start ... -🔌 unsplash images (unsplash.py) loaded: 1 directive +🔌 Lorem Picsum Images (picsum.py) loaded: 1 directive ... ``` you can now use the directive, for example: ```markdown -:::{unsplash-py} misty,mountains +:::{picsum-py} +:size: 600x250 ::: ``` -:::{unsplash-py} misty,mountains +:::{picsum-py} :size: 600x250 ::: diff --git a/docs/javascript-plugins.md b/docs/javascript-plugins.md index b82e54a8f..7127e0822 100644 --- a/docs/javascript-plugins.md +++ b/docs/javascript-plugins.md @@ -7,13 +7,13 @@ JavaScript plugins are native MyST plugins, which are loaded as modules into the ## Defining a new directive -To create a plugin, you will need a single Javascript file[^esm] that exports one or more of the objects above. For example, a simple directive that pulls a random image from [Unsplash](https://unsplash.com/) can be created with a single file that exports an `unsplash` directive. +To create a plugin, you will need a single Javascript file[^esm] that exports one or more of the objects above. For example, a simple directive that pulls a random image from [Unsplash](https://picsum.photos/) can be created with a single file that exports an `picsum` directive. [^esm]: The format of the Javascript should be an ECMAScript modules, not CommonJS. This means it uses `import` statements rather than `require()` and is the most modern style of Javascript. -:::{literalinclude} unsplash.mjs -:label: unsplash-js-source -:caption: A plugin to add an `unsplash` directive that includes a beautiful, random picture based on a query string. +:::{literalinclude} picsum.mjs +:label: picsum-js-source +:caption: A plugin to add an `picsum` directive that includes a beautiful, random picture based on a size and optional ID string. ::: This code should be referenced from your `myst.yml` under the `projects.plugins`: @@ -22,7 +22,7 @@ This code should be referenced from your `myst.yml` under the `projects.plugins` :filename: myst.yml project: plugins: - - unsplash.mjs + - picsum.mjs ``` Then start or build your document using `myst start` or `myst build`, and you will see that the plugin is loaded. @@ -30,18 +30,19 @@ Then start or build your document using `myst start` or `myst build`, and you wi ```text myst start ... -🔌 Unsplash Images (unsplash.mjs) loaded: 1 directive +🔌 Lorem Picsum Images (picsum.mjs) loaded: 1 directive ... ``` You can now use the directive, for example: ```markdown -:::{unsplash} misty,mountains +:::{picsum} +:size: 600x250 ::: ``` -:::{unsplash} misty,mountains +:::{picsum} :size: 600x250 ::: @@ -107,7 +108,7 @@ Below is the contents of each file for reference. ::::{dropdown} Plugin: Display an image -```{literalinclude} unsplash.mjs +```{literalinclude} picsum.mjs ``` diff --git a/docs/myst.yml b/docs/myst.yml index 6b14e0140..467678052 100644 --- a/docs/myst.yml +++ b/docs/myst.yml @@ -49,11 +49,11 @@ project: TOC: table of contents plugins: - directives.mjs - - unsplash.mjs + - picsum.mjs - latex.mjs - templates.mjs - type: executable - path: unsplash.py + path: picsum.py - type: executable path: markup.py - type: javascript diff --git a/docs/picsum.mjs b/docs/picsum.mjs new file mode 100644 index 000000000..02e9aba8b --- /dev/null +++ b/docs/picsum.mjs @@ -0,0 +1,31 @@ +const picsumDirective = { + name: 'picsum', + doc: 'An example directive for showing a nice random image at a custom size.', + alias: ['random-pic'], + arg: { + type: String, + doc: 'The ID of the image to use, e.g. 1', + }, + options: { + size: { type: String, doc: 'Size of the image, for example, `500x200`.' }, + }, + run(data) { + // Parse size + const match = (data.options?.size ?? '').match(/^(\d+)(?:x(\d+))?$/); + let sizeQuery = '200/200'; + if (match) { + const first = match[1]; + const second = match[2]; + sizeQuery = second ? `${first}/${second}` : first; + } + + const idQuery = data.arg ? `id/${data.arg}/` : ''; + const url = `https://picsum.photos/${idQuery}${sizeQuery}`; + const img = { type: 'image', url }; + return [img]; + }, +}; + +const plugin = { name: 'Lorem Picsum Images', directives: [picsumDirective] }; + +export default plugin; diff --git a/docs/unsplash.py b/docs/picsum.py similarity index 76% rename from docs/unsplash.py rename to docs/picsum.py index 9240c9a4f..7833fa03f 100755 --- a/docs/unsplash.py +++ b/docs/picsum.py @@ -2,18 +2,19 @@ import argparse import json import sys +import re plugin = { "name": "Unsplash Images", "directives": [ { - "name": "unsplash-py", + "name": "picsum-py", "doc": "An example directive for showing a nice random image at a custom size.", "alias": ["random-pic-py"], "arg": { "type": "string", - "doc": "The kinds of images to search for, e.g., `fruit`", + "doc": "The ID of the image to use, e.g. 1", }, "options": { "size": { @@ -44,11 +45,19 @@ def run_directive(name, data): :param name: name of the directive to run :param data: data of the directive to run """ - assert name == "unsplash-py" + assert name == "picsum-py" - query = data["arg"] - size = data["options"].get("size", "500x200") - url = f"https://source.unsplash.com/random/{size}/?{query}" + raw_id = data.get("arg") + raw_size = data["options"].get("size", "500x200") + match = re.match("^(\d+)(?:x(\d+))?$", raw_size) + if not match: + size_query = "200/200" + else: + size_query = f"{match[1]}/{match[2]}" if match[2] else match[1] + + id_query = f"/id/{raw_id}/" if raw_id else "" + + url = f"https://picsum.photos/{id_query}{size_query}" # Insert an image of a landscape img = { "type": "image", diff --git a/docs/unsplash.mjs b/docs/unsplash.mjs deleted file mode 100644 index 7a55dbe15..000000000 --- a/docs/unsplash.mjs +++ /dev/null @@ -1,20 +0,0 @@ -const unsplashDirective = { - name: 'unsplash', - doc: 'An example directive for showing a nice random image at a custom size.', - alias: ['random-pic'], - arg: { type: String, doc: 'The kinds of images to search for, e.g., `fruit`' }, - options: { - size: { type: String, doc: 'Size of the image, for example, `500x200`.' }, - }, - run(data) { - const query = data.arg; - const size = data.options.size || '500x200'; - const url = `https://source.unsplash.com/random/${size}/?${query}`; - const img = { type: 'image', url }; - return [img]; - }, -}; - -const plugin = { name: 'Unsplash Images', directives: [unsplashDirective] }; - -export default plugin;