diff --git a/contributor_docs/contributing_to_the_p5js_reference.md b/contributor_docs/contributing_to_the_p5js_reference.md index 8166404d47..a7f2b79f1d 100644 --- a/contributor_docs/contributing_to_the_p5js_reference.md +++ b/contributor_docs/contributing_to_the_p5js_reference.md @@ -1,207 +1,656 @@ + + # Contributing to the p5.js Reference -In p5.js, we author the code reference you see on the [reference](https://p5js.org/reference/) page on the p5.js website by including them alongside the library’s source code as specialized comments. These reference comments include the description, the function’s signature (its parameters and return value), and usage examples. In other words, the content on each p5.js function/variable’s reference page is built from the reference comments in the source code. +## Table of Contents +* [A quick introduction to reference comments](#a-quick-introduction-to-reference-comments) +* [Reference comment blocks for functions](#reference-comment-blocks-for-functions) +* [Reference comment blocks for p5.js variables](#reference-comment-blocks-for-p5js-variables) +* [Adding examples](#adding-examples) +* [Using assets in examples and descriptions](#using-assets) +* [Less common JSDoc tags](#less-common-jsdoc-tags) +* [Generating and previewing the reference](#generating-and-previewing-the-reference) +* [Linting the comments to find errors](#linting-the-docs) +* [Next steps](#next-steps) +* [Appendix: Summary of differences with p5.js v1.x](#doc-differences-v1-to-v2) + +In p5.js, we author the code reference you see on the [reference](https://beta.p5js.org/reference/) page on the p5.js website by including specialized comments alongside the library’s source code. For each p5 function, for example, a reference comment includes the name and description of the function, details of its parameters and return value, and examples of use. The content you see on each p5.js function/variable’s reference page is built from these reference comments in the source code. This document will show you how to write and format the reference comments so that they can eventually be rendered onto the website correctly. You should follow this guide whenever you are editing or writing a reference for any p5.js function or variable. +If you're looking to learn about the build process that generates the reference documentation from the source-code comments, see instead [Reference generation process](./reference_generation_process/) + +### A note about p5.js versions -## A quick introduction to how reference comments work +This document describes how to work with p5.js version 2.x, whose reference documentation is currently being hosted at https://beta.p5js.org/reference/. If you are documenting code for p5.js v1.x, you should consult [this document](https://p5js.org/contribute/contributing_to_the_p5js_reference/), instead, as some of the syntax and processes are different. + +(Most of the differences are detailed in [this appendix](#doc-differences-v1-to-v2)). + +## A quick introduction to reference comments When you look at the source code of p5.js, you will see many lines in the library being reference comments; they look like this: -``` +```js /** - * Calculates the sine of an angle. `sin()` is useful for many geometric tasks - * in creative coding. The values returned oscillate between -1 and 1 as the - * input angle increases. `sin()` takes into account the current - * angleMode. + * Calculates the sine of an angle. + * + * `sin()` is useful for many geometric tasks + * in creative coding. The values returned + * oscillate between -1 and 1 as the input + * angle increases. `sin()` calculates the + * sine of an angle, using radians by default, + * or according to the angleMode() + * setting (RADIANS or DEGREES). * * @method sin * @param {Number} angle the angle. * @return {Number} sine of the angle. * * @example - *
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * describe('A white ball on a string oscillates up and down.');
+ * }
+ *
* function draw() {
* background(200);
*
- * let t = frameCount;
+ * // Calculate the coordinates.
* let x = 50;
- * let y = 30 * sin(t * 0.05) + 50;
- * line(x, 50, x, y);
+ * let y = 30 * sin(frameCount * 0.05) + 50;
+ *
+ * // Draw the oscillator.
+ * line(50, y, x, y);
* circle(x, y, 20);
+ * }
*
- * describe('A white ball on a string oscillates up and down.');
+ * @example
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * describe('A series of black dots form a wave pattern.');
* }
- *
- *
* function draw() {
+ * // Calculate the coordinates.
* let x = frameCount;
* let y = 30 * sin(x * 0.1) + 50;
+ *
+ * // Draw the point.
* point(x, y);
+ * }
*
- * describe('A series of black dots form a wave pattern.');
+ * @example
+ * function setup() {
+ * createCanvas(100, 100);
+ *
+ * background(200);
+ *
+ * describe('A series of black dots form an infinity symbol.');
* }
- *
- *
* function draw() {
- * let t = frameCount;
- * let x = 30 * cos(t * 0.1) + 50;
- * let y = 10 * sin(t * 0.2) + 50;
- * point(x, y);
+ * // Calculate the coordinates.
+ * let x = 30 * cos(frameCount * 0.1) + 50;
+ * let y = 10 * sin(frameCount * 0.2) + 50;
*
- * describe('A series of black dots form an infinity symbol.');
+ * // Draw the point.
+ * point(x, y);
* }
- *
- *
+ * ...
+```
+
+### `@method` - specifying the function name
+
+[`@method`](https://jsdoc.app/tags-function) is used to define the name of the function, in this case `sin`. Note that the function name does not include the brackets `()`.
+
+You may sometimes see this missing from the reference. In that case JSDoc will try to infer it by looking at the name of the function from the following source code. It is recommended to include the function name using the @method tag where possible.
+
+This tag is also useful when detailing multiple signatures for a function (see later).
+
+### `@param` - specifying details of each parameter
+
+[`@param`](https://jsdoc.app/tags-param) is used to define the parameters or arguments that the function accepts. It is used once per parameter.
+
+The general format for a parameter is:
```
@param {type} name Description here.
```
+For example, the `sin()` function has:
+```
+@param {Number} angle the angle.
+```
+
+1. Following the keyword `@param`, the _type_ of the parameter is mentioned in curly brackets `{}`. (in this case, `{Number}`)
+ - This is strongly recommended but can be omitted in certain cases (notably in p5.strands).
+
+2. After the type, the next _word_ (in this case, `angle`) is the name of the parameter.
+ - This must exactly match the name of the relevant parameter in the source code.
+
+3. After the name, the rest of the line is the description of the parameter.
+
If the parameter is optional, add square brackets around the name:
```
@param {type} [name] Description here.
```
+#### Examples of parameter types
-### Additional info: Constants
+An example from [rect()](https://beta.p5js.org/reference/p5/rect/), where the topleft ("tl") parameter is optional:
+```
+@param {Number} [tl] optional radius of top-left corner.
+```
+An example from [createCanvas](https://beta.p5js.org/reference/p5/createcanvas/) where a "renderer" parameter can optionally be supplied:
-If the parameter takes one or more values defined in [`constants.js`](https://github.com/processing/p5.js/blob/main/src/core/constants.js), then the type should be specified as `{Constant}` and the valid values should be enumerated in the comment following the `either` keyword, e.g.:
+```
+@param {(P2D|WEBGL)} [renderer] either P2D or WEBGL. Defaults to P2D.
+```
+A more advanced example from [hue](https://beta.p5js.org/reference/p5/hue/) where the color parameter can be a p5.Color object, an array of numbers, or a string:
```
-@param {Constant} horizAlign horizontal alignment, either LEFT, CENTER, or RIGHT
+* @param {p5.Color|Number[]|String} color
```
-For return types you should follow this format:
+**"Number" not "number". "String" not "string"**
+
+Throughout the p5.js documentation, primitive types are all capitalized: String, Number, Boolean, etc. (This is an example where our convention differs from JSDoc.)
+
+#### Parameters that expect arrays
+
+When specifying an array type, use `type[]` rather than `Array
* // Move the mouse across the canvas
* function draw() {
* background(244, 248, 252);
* line(mouseX, 0, mouseX, 100);
- * describe('horizontal black line moves left and right with mouse x-position');
+ * describe('horizontal black line moves
+ * left and right with mouse x-position');
* }
- *
- *
* const c = color(255, 204, 0);
* fill(c);
* rect(15, 20, 35, 60);
@@ -221,66 +668,118 @@ The relevant `@example` tag to create the above is as follows:
* describe(
* 'Two rectangles with black edges. The rectangle on the left is yellow and the one on the right is red.'
* );
- *
- * ` tag. In between the opening and closing `` tag, you will insert the relevant example code. The basic principle of writing good example code for the reference is to keep things simple and minimal. The example should be meaningful and explain how the feature works without being too complicated. The example’s canvas should be 100x100 pixels and if the `setup()` function is not included, such as in the example above, the code will be automatically wrapped in a `setup()` function with a default 100x100 pixels gray background canvas created. We won’t go through the details about best practices and code style for the example code here; please see the reference style guide instead.
+Generally, each example should be a self-contained complete sketch that will run on the reference website and which could be run directly if pasted into (for example) the web editor.
+
+It should declare `setup()` and `draw()` functions as required.
+
+The example’s canvas should be 100x100 pixels.
+
+### About the complexity of examples
+
+The basic principle of writing good example code for the reference is to keep things simple and minimal. The example should be meaningful and explain how the feature works without being too complicated.
+
+While it may be tempting to make a more interesting, engaging, or "cool" example using other functions (e.g. noise()), or using clever math, that makes it harder for readers to understand. Try to minimize the pre-requisites necessary for the reader to follow your example.
-You can have multiple examples for one feature. To do so, add an additional `` and `` HTML block right after the first closed, separated by a blank line.
+We won’t go through the details about best practices and code style for the example code here; please see the [reference style guide](https://beta.p5js.org/contribute/documentation_style_guide/), instead.
+
+### Providing multiple examples
+
+You can have multiple examples for one feature. These should be separated by a blank line and a new @example tag for each.
+
+Example:
```
* @example
-*
-*
* arc(50, 50, 80, 80, 0, PI + QUARTER_PI, OPEN);
* describe('An ellipse created using an arc with its top right open.');
-*
-*
*
-*
-*
+* @example
* arc(50, 50, 80, 80, 0, PI, OPEN);
* describe('The bottom half of an ellipse created using arc.');
-*
-*
```
+### Inserting examples _within_ the description
+
+It is possible, and often desirable, to include one or two early runnable examples _within_ the description section, before the main "Examples" section of the page. (This is particularly useful when a function or class has a lengthy description section.)
-If you do not want the reference page to execute your example code (i.e., you just want the code to show up), include the class “`norender`” in the ``:
+The p5.Image reference has a good example of this. ([Source here](https://github.com/processing/p5.js/blob/6a61f7fb3055969fe53d9f82027f891d245b3e9f/src/webgl/material.js#L597)).
+
+To add such an example, instead of using an `@example` tag, surround the example code in a "fenced" markdown code-block with the annotation `js example`. Here's an example of how it should look:
+
+````
+* ```js example
+* function setup(){
+* fill('orange');
+* circle(0, 30, 10);
+* }
+* ```
+````
+
+To make the code-block, surround your example code before and after by three backticks on a newline.
+The opening backticks should be immediately followed by the annotation `js example`. Remember, you should not use an `@example` tag in this case.
+
+**Why is this important?**
+
+Early examples like this allow the reader to quickly play with, and get an early understanding of, a p5.js feature _without_ having to read or scroll through possibly overwhelming amounts of documentation discussing in-depth details of the feature.
+
+### When examples omit setup()
+
+If the `setup()` function is not included, such as in the example above, the code will be automatically wrapped in a `setup()` function with a default 100x100 pixels gray background canvas created. While you will see such examples included in this guide for brevity, it is generally preferred that your example be a complete sketch.
+
+### Preventing execution of example code with `norender`
+
+If you do not want the reference page to run an example's code (i.e., you only want the _code_ to be shown, not its result), follow the `@example` tag with `// META:norender` on the next line:
```
* @example
-*
-*
+* // META:norender
* arc(50, 50, 80, 80, 0, PI + QUARTER_PI, OPEN);
* describe('ellipse created using arc with its top right open');
-*
-*
```
-If you do not want the example to be run as part of the automated tests (for example, if the example requires user interaction), include the class “`notest`” in the ``:
+## Using assets in examples and descriptions
+
+If your example code (or the description section) uses asset files (e.g. images, fonts, sounds), here's how to work with them.
+1. Add the asset file(s) in the _p5.js-website_ repo's [/public/assets](https://github.com/processing/p5.js-website/tree/2.0/public/assets) folder.
+2. Refer to the asset with the path `assets/filename.ext` in the code example or description.
+Examples:
+
+For a full working example, see the [tint()](https://beta.p5js.org/reference/p5/tint/) reference.
+
+```js
+img = await loadImage('assets/rockies.jpg');
```
-* @example
-*
-* function setup() {
-* let c = createCanvas(100, 100);
-* saveCanvas(c, 'myCanvas', 'jpg');
-* }
-*
+The above code will load the image file, [/public/assets/rockies.jpg](https://github.com/processing/p5.js-website/blob/2.0/public/assets/rockies.jpg), stored in the p5.js-website repo.
+
+```js
+font = await loadFont('assets/inconsolata.otf');
```
+The above code will load the font file, [/public/assets/inconsolata.otf](https://github.com/processing/p5.js-website/blob/2.0/public/assets/inconsolata.otf), stored in the p5.js-website repo.
+
+### Asset hosting differs from p5 v1
+
+Note that this hosting location is a significant change from p5 v1.x where such assets were stored instead in the _p5.js_ repo.
+
+### Re-using existing assets
+
+You may wish to make use of an asset that's already in that directory, linking to it in the same way. (Reusing assets also provides familiarity to the reader across the documentation). You can see all such assets [here](https://github.com/processing/p5.js-website/tree/2.0/public/assets). (Cloning that repo and using a file explorer to open `public/assets` will make it easier to browse the assets.)
+
+### Hotlinking asset files in examples
+
+Whilst it is technically possible to hotlink to an asset file hosted elsewhere (such as [wikimedia commons](https://commons.wikimedia.org/wiki/Commons:Reusing_content_outside_Wikimedia/technical)) when permitted by the copyright license and hosting provider, anyone could later change, vandalize, rename, or delete that hotlinked asset.
-If your example uses external asset files, put them in the [/docs/yuidoc-p5-theme/assets](https://github.com/processing/p5.js/tree/main/docs/yuidoc-p5-theme/assets) folder (or reuse one already in there) then link to them with "assets/filename.ext" in the code. See the [tint()](https://p5js.org/reference/p5/tint/) reference for example.
+(It also makes offline copies of the reference much harder to produce.)
+It is recommended, instead, to use assets hosted by the p5.js-website itself, as described previously here.
### Add a canvas description using `describe()`
Finally, for every example you add, you are required to use the p5.js function `describe()` in the example to create a screen-reader accessible description for the canvas. Include only one parameter: a string with a brief description of what is happening on the canvas.
-```
+```js
* @example
-*
-*
* let xoff = 0.0;
* function draw() {
* background(204);
@@ -289,11 +788,8 @@ Finally, for every example you add, you are required to use the p5.js function `
* line(n, 0, n, height);
* describe('A vertical line moves randomly from left to right.');
* }
-*
-*
*
-*
-*
+* @example
* let noiseScale = 0.02;
* function draw() {
* background(0);
@@ -304,41 +800,99 @@ Finally, for every example you add, you are required to use the p5.js function `
* }
* describe('A horizontal wave pattern moves in the opposite direction of the mouse.');
* }
-*
-*
```
-For more on `describe()` visit the [web accessibility contributor documentation](./web_accessibility/#describe), and the [Writing Accessible Canvas Descriptions](https://p5js.org/tutorials/writing-accessible-canvas-descriptions/) tutorial.
+For more on `describe()` visit the [web accessibility contributor documentation](./web_accessibility/#describe), and the [Writing Accessible Canvas Descriptions](https://beta.p5js.org/tutorials/writing-accessible-canvas-descriptions/) tutorial.
-With all the above you should have most of the tools needed to write and edit p5.js reference comments. However, there are a few more specialized usage of JSDoc style reference comments that you may come across in p5.js. These are situationally useful and not something that you need often.
+## Less common JSDoc tags
+With all the above you should have most of the tools needed to write and edit p5.js reference comments. However, there are a few more specialized usages of JSDoc reference comments that you may come across in p5.js. These are situationally useful and not something that you need often.
### `@private` tag
-You can use the `@private` if a property or variable is a private function or variable. If a feature is marked as `@private` it will not be included as part of the rendered reference on the website. The reason to use the `@private` tag to mark a reference comments block as private is when you document internal features for the library itself. For example, see the reference comments for `_start` below:
+You can use the `@private` if a property or variable or class is private. If a feature is marked as `@private` it will not be included as part of the rendered reference on the website. This is done automatically for methods whose names start with `_`.
+The tag is used when documenting internal features for the library itself.
+Example:
-```
+Here's `invert` from `src/image/filters.js`:
+
+```js
/**
- * _start calls preload() setup() and draw()
- *
- * @method _start
+ * Sets each pixel to its inverse value.
+ * No parameter is used.
* @private
+ * @param {Canvas} canvas
*/
-p5.prototype._start = function () {
+invert(canvas) {
+ //...
+}
```
-
### `@module` and related tags
-At the top of each source code file will be a `@module` tag. Modules correspond to a group of features in p5.js which on the rendered reference page on the website are split into the corresponding sections. Inside each module, there are additional submodules defined with the `@submodule` tag.
+#### `@module` and `@submodule`
+
+At the top of each source code file will be a comment block with a `@module` tag. A module is a top-level grouping of features in the reference pages on the website. This does _not_ necessarily correspond to any specific software `module` concept in the code itself.
+
+After the `@module` tag, an optional `@submodule` tag can be used to further group features for the website. This `@submodule` tag can be set differently on any comment block in the file to change the submodule for a specific feature.
+
+The convention p5.js follows is that each subfolder in the `src/` folder will be one `@module` while each file inside the subfolder will be its own `@submodule` under the overall subfolder’s `@module`. Unless you are adding new subfolders/files to the p5.js source code, you shouldn’t need to edit a file's top-level reference comment block.
+
+On the website, the [top-level reference page](https://beta.p5js.org/reference) presents a list functions and variables grouped by their modules and submodules.
+
+Examples of module + submodule groupings
+
+The ["Image" module](https://beta.p5js.org/reference/#Image) in `src/image/` has the following submodules: "Loading & Displaying", "Pixels", and "p5.Image".
+
+The ["Color" module](https://beta.p5js.org/reference/#Color) in `src/color/` has the following submodules:
+ "Creating & Reading", "Setting", and "Color Conversion".
+
+The _conceptual_ ["3D" module](https://beta.p5js.org/reference/#3D) documents code mostly from `src/webgl/` (there is no `src/3D/`), and has the following submodules: "Camera", "Interaction", "Lights", "Material", "strands", "p5.Camera", "p5.Shader".
+
+Examples:
+
+For just a category:
+```
+/**
+ * @module Rendering
+ */
+```
+
+For both:
+
+```
+/**
+ * @module Data
+ * @submodule LocalStorage
+ */
+```
+
+#### The `@for` tag
The `@for` tag defines the relationship between this module and the overall `p5` class, effectively saying this module is a part of the `p5` class.
-The `@requires` tag defines the required imported modules that the current module depends on.
+It is also used when documenting class properties, to ensure the documentation attaches to the correct class. (Currently class properties are documented _outside_ their class.)
+Example:
```
+ /**
+ * The x component of the vector
+ * @type {Number}
+ * @for p5.Vector
+ * @property x
+ * @name x
+ */
+```
+
+#### The @requires tag
+
+The `@requires` tag defines the required imported modules that the current module depends on.
+
+Example of `@for` and `@requires`
+
+```js
/**
* @module Color
* @submodule Creating & Reading
@@ -347,70 +901,359 @@ The `@requires` tag defines the required imported modules that the current modul
* @requires constants
*/
```
+#### The @beta tag - marking experimental API features
+
+This tag is used to mark that a feature is experimental and that its details may change or it may be removed. A warning will be presented explaining this on the reference page.
+
+It should be placed on a separate line in the comment block and does not need any argument.
+```js
+
+ /**
+ * Create a new shader that can change how
+ * fills are drawn.
+ *
+ * ...omitted...
+ *
+ * @method buildMaterialShader
+ * @submodule p5.strands
+ * @beta
+ * @param {Function} callback A function
+ * building a p5.strands shader.
+ * @returns {p5.Shader} The material shader.
+ */
+```
+
+#### The @deprecated tag
+
+Marks that a feature will be removed from a future version of p5.js, possibly also indicating a better option.
+
+Follow the tag with:
+* Text explaining that the feature will be removed from a future version.
+* (If possible) A suggested replacement to be used (with link).
+
+Example (imagined):
+
+```js
+/**
+* Create a p5.Vector from polar coordinates.
+*
+* @method createVectorFromPolarCoordinates
+* @deprecated This will be removed from a
+* future version of p5.js.
+*
+* p5.Vector.fromAngle() is recommended,
+* instead.
+*/
+```
+
+Example (real):
+
+```js
+/**
+* Splits a `String` into pieces and returns an
+* array containing the pieces.
+*
+* @method splitTokens
+* @deprecated This will be removed in a future
+* version of p5.js to make way for a new,
+* friendlier version :)
+* @param {String} value string to split.
+* @param {String} [delim] character(s) to use
+ for splitting the string.
+* @return {String[]} separated strings.
+*
+*/
+```
+### Creating and documenting classes
-The convention p5.js follows is that each subfolder in the `src/` folder will be one `@module` while each file inside the subfolder will be its own `@submodule` under the overall subfolder’s `@module`. Unless you are adding new subfolders/files to the p5.js source code, you shouldn’t need to edit this reference comments block.
+It's unlikely you'll need the following more advanced material unless you're creating new classes.
+Classes are to be created *outside* of the addon function, and assigned to `p5` *inside*. The class name should be the same always:
-### `@class` tag
+```js
+class MyClass {
+ // ...
+}
-Class constructors are defined with the `@class` tag and the `@constructor` tag. The format for this block is similar to how a function is defined with the `@method` block, the class’s name will need to be defined with the `@class` tag and the `@constructor` tag will indicate the class has a constructor function. See the example below for the `p5.Color` class:
+export default function myAddon(p5, fn) {
+ p5.MyClass = MyClass;
+}
+```
+Document class methods directly above the members in classes, *without* a `@method` tag:
+
+```js
+class MyClass {
+ /**
+ * Description goes here
+ */
+ myMethod() {
+ return 4;
+ }
+}
```
+
+Documentation for the class itself should go at the spot where the class is added to `p5` and not right next to the class definition. This needs to include the `@class` tag, including a `p5.` prefix on the class name. Also include the parameters for the constructor in this description, if they exist.
+
+```js
+class MyClass {
+ constructor(n) {
+ this.n = n;
+ }
+}
+
+export default function myAddon(p5, fn) {
+ /**
+ * Description of the class goes here!
+ *
+ * @class p5.MyClass
+ * @param {Number} n A number to pass in
+ */
+ p5.MyClass = MyClass;
+}
+```
+
+Here's an excerpt of the `p5.Color` class:
+
+```js
+class Color {
+ //...
+}
+
+function color(p5, fn, lifecycles){
/**
- * A class to describe a color. Each `p5.Color` object stores the color mode
- * and level maxes that were active during its construction. These values are
- * used to interpret the arguments passed to the object's constructor. They
- * also determine output formatting such as when
- * saturation() is called.
+ * A class to describe a color.
*
- * Color is stored internally as an array of ideal RGBA values in floating
- * point form, normalized from 0 to 1. These values are used to calculate the
- * closest screen colors, which are RGBA levels from 0 to 255. Screen colors
- * are sent to the renderer.
+ * Each `p5.Color` object stores the color mode
+ * and level maxes that were active during its
+ * construction. These values are used to
+ * interpret the arguments passed to the
+ * object's constructor. They also determine
+ * output formatting such as when
+ * saturation()
+ * is called.
*
- * When different color representations are calculated, the results are cached
- * for performance. These values are normalized, floating-point numbers.
+ * Color is stored internally as an array of
+ * ideal RGBA values in floating point form,
+ * normalized from 0 to 1. These values are
+ * used to calculate the closest screen colors,
+ * which are RGBA levels from 0 to 255. Screen
+ * colors are sent to the renderer.
*
- * color() is the recommended way to create an instance
- * of this class.
+ * When different color representations are
+ * calculated, the results are cached for
+ * performance. These values are normalized,
+ * floating-point numbers.
+ *
+ * Note: color() is
+ * the recommended way to create an instance of
+ * this class.
*
* @class p5.Color
- * @constructor
- * @param {p5} [pInst] pointer to p5 instance.
+ * @param {p5} pInst pointer to p5 instance.
*
- * @param {Number[]|String} vals an array containing the color values
- * for red, green, blue and alpha channel
- * or CSS color.
+ * @param {Number[]|String} vals an array
+ * containing the color values for red, green,
+ * blue and alpha channel or CSS color.
+ */
+/**
+ * @class p5.Color
+ * @param {Number[]|String} vals
*/
+p5.Color = Color;
```
+Documentation for class properties should appear after the class is added to `p5`, not within the class itself. It needs to have the `@for` tag referencing its class, and the `@property` tag naming the property itself:
+
+```js
+class MyClass {
+ myProperty;
+ constructor() {
+ myProperty = 2;
+ }
+}
+
+export default function myAddon(p5, fn) {
+ /**
+ * Description of the class goes here!
+ *
+ * @class p5.MyClass
+ */
+ p5.MyClass = MyClass;
+
+ /**
+ * Description of the property goes here!
+ *
+ * @property {Number} myProperty
+ * @for p5.MyClass
+ */
+}
+```
+
## Generating and previewing the reference
-The p5.js repository is set up so that you can generate and preview the reference without needing to build and run the p5.js website as well.
+### A quick first in-editor preview for vs code users
-- The main command to generate the reference from the reference comments in the source code is to run the following command.
+In some editors, such as vs code, you can hover over a function or variable to see immediately - in a pop-up - a rendering of the information from the documentation above it. This can be a useful first quick preview, though it won't show everything - it won't run your code examples, or show linked images, for example.
+### Previewing your work on the website, locally
+
+At some point you will want to preview how your changes will look on the website. This involves run the website locally and having it import your p5.js code from a branch of your repo.
+
+Steps:
+
+1. Commit your changes to a local branch of your fork of the p5.js repo. The changes don't need to be pushed to github for this purpose, but they do need to be committed on a branch.
+1. Clone [the p5.js-website repo](https://github.com/processing/p5.js-website/tree/2.0) locally.
+1. Open a terminal in your new p5.js-website repo
+1. Check out the branch "2.0"
+1. Run `npm install`
+1. Run the following command, using the path to **your** local p5.js repo before the `#`, and the name of **your** branch after the `#`:
+
+```sh
+npm run custom:dev path/to/YOUR/local/repo#yourBranch
```
-npm run docs
+
+For example, if your work is in a branch called `my-amazing-branch` on a local p5.js repo called `p5.js` as a sibling directory next to the current `p5.js-website` directory, you could run the following:
+
+```sh
+npm run custom:dev ../p5.js#my-amazing-branch
+```
+
+This will build the local website reference pages from the data in your branch and then start a development preview of the website.
+
+6. Find the URL that is logged in the console and visit it in your browser in order to test out your changes.
+
+If you prefer to preview work that's already on github, you can do so. Use the repo URL instead of its local path, as follows:
+
+```sh
+npm run custom:dev https://github.com/yourUsername/p5.js.git#yourBranch
+```
+
+#### Resetting your changes
+
+When you're done with this preview, you can run this command to reset your changes:
+```sh
+npm run custom:cleanup
+```
+
+#### Troubleshooting
+
+* [Run the documentation linter](#linting-the-docs) on your source files.
+* Review the log from the above `custom:dev` process, for mentions of your code.
+* Don't forget that if you're [using local asset files](#using-assets), they'll need to be in the _website_ repo.
+
+#### Limitations
+
+The website won't be _fully_ functional when partially prepared in this way. Notably:
+
+* Links between pages may be broken:
+ * You'll need to ensure local links end with a trailing slash '/', to be matched by Astro.
+* The search facility will not work by default
+ * Look into `npm run build:search` to build the necessary index files.
+ * ...or just find your function/variable in the [top-level listing](https://beta.p5js.org/reference/).
+
+
+## Linting the comments to find errors
+
+The documentation.js tool can also be used for "linting". This is a process which will look for content in the comment blocks that the tool doesn't understand, or thinks might be incorrect.
+
+If something from your documentation comments is not showing up correctly on the reference site, running the linting tool may yield some clues.
+Alternatively, you might just want to run it to try to find any potential problems _before_ you commit.
+
+We can run it from the command line, in the p5.js repo:
+
+```bash
+npx documentation lint "src/**/*.js"
```
-This will generate the necessary preview files and the main `docs/reference/data.json` file, which is the same file (after minification) that will be used to render the reference page on the website.
+This will produce _lots_ of warnings, across many files! These do not necessarily mean there is a problem: for various reasons, the codebase uses some documentation tags that documentation.js doesn't understand (but tolerates) in order to organize the reference.
+
+However, you can look through for any warnings relating to the file _you_ are working on, to see if anything stands out. (e.g. a misspelled tag, mismatching parameter name, or "Unknown content")
-- For continuous work on the reference, you can run the following command.
+**Example of a minor issue found by the linter:**
```
-npm run docs:dev
+/path/to/p5.js/src/io/p5.TableRow.js
+153:1 warning An explicit parameter named rowID was specified but didn't match inferred information r
```
-This will launch a live preview of the rendered reference that will update each time you make changes (you will need to refresh the page after making changes to see them appear). This is useful, especially for previewing example code running in the browser.
+**Explanation: **
-- The main template files are stored in the `docs/` folder and, in most cases, you should not make changes directly to files in this folder, except to add new asset files in the `docs/yuidoc-p5-theme/assets` folder.
+The above warning says that there's a problem:
+* in the file `p5.TableRow.js`
+* on line 153, anywhere from character 1
+* where @param "rowID" was documented...
+* ...but there's no parameter of that name in the function that follows.
+ * (It has inferred we must be talking about "r" - the only parameter the function has.)
+
+Here's a minimal example of hypothetical code in `p5.TableRow.js` that would have caused this warning. (Content unrelated to the warning is not shown here).
+
+```js
+/**
+ * Returns a ref to the specified p5.TableRow.
+ *
+ * @param {Number} rowID ID of the row to get.
+ */
+getRow (r) {
+ return this.rows[r];
+}
+```
## Next steps
-For additional details about the reference system, you can checkout the documentation for [JSDoc](https://jsdoc.app/) and [YUIDoc](https://yui.github.io/yuidoc/).
+* If you haven't already, be sure to read the [contributor guidelines](./contributor_guidelines/).
+* If you want more detail on JSDoc tags, check out the official documentation [JSDoc](https://jsdoc.app/).
+* If you're curious, you can read about p5.js's [reference generation process](./reference_generation_process/) (but it's not required!)
+* For examples of issues related to the reference, have a look at [#6519](https://github.com/processing/p5.js/issues/6519) and [#6045](https://github.com/processing/p5.js/issues/6045).
+
+## Appendix: Summary of documentation differences between p5.js v1 and v2
+
+### Overview: Syntax and tooling per p5.js version
+
+* in p5 v2, documentation comments are:
+ * written in JSDoc syntax
+ * processed with a [tool called documentation.js](https://documentation.js.org/).
+ * (Some non-JSDoc tags remain in use as the p5 documentation build system is quite customized.)
+
+* in p5 v1, documentation comments are:
+ * written in YUIDoc syntax
+ * processed with a [tool called YUIDoc](https://yui.github.io/yuidoc/).
+
+### Syntax differences between YUIDoc and JSDoc
-For examples of issues related to the reference, have a look at [#6519](https://github.com/processing/p5.js/issues/6519) and [#6045](https://github.com/processing/p5.js/issues/6045). The [contributor guidelines](./contributor_guidelines.md) document is also a good place to start.
+* YUIDoc requires function names be provided with the `@method` tag, whereas JSDoc can generally extract that information from the implementation source code.
+* JSDoc does not have either `@submodule` or `@for` tags (YUIDoc does) but we continue to use them throughout the v2.x codebase as a mechanism by which we group functions, variables, and classes on the website. If you run `documentation lint` you'll see complaints about these tags but Documentation.js collects the tagged information into its output without problem for the subsequent build-processes to use.
+
+### Other documentation differences between versions
+
+* Hosting assets: For v2, code example assets (images, fonts, etc) go in the website repo's `public/assets` folder. In v1 these went in the `docs/yuidoc-p5-theme/assets` folder of the p5.js repo.
+
+* Previewing the reference: In v2, previewing the reference site locally can no longer be done with the p5.js repo alone, but requires running build:reference on the website repo. In v1 this was possible without requiring the website repo.
+
+* Constants: In v2, constants accepted in a function parameter are shown as options in that parameter's type, whereas in v1 they are listed only in the parameter's free-text description and the type is set as (literally) `{Constant}`.
+
+Example:
+
+For p5 v1.x:
+```js
+/**
+ * @method textAlign
+ * @param {Constant} horizAlign horizontal
+ * alignment, either LEFT, CENTER, or RIGHT.
+ * ...
+ */
+ ```
+
+For p5 v2.x:
+```js
+/**
+ * @method textAlign
+ * @param {LEFT|CENTER|RIGHT} horizAlign
+ * horizontal alignment.
+ * ...
+ */
+ ```
+* p5 v2.x no longer uses `` wrappers around code examples.
\ No newline at end of file
diff --git a/contributor_docs/documentation_style_guide.md b/contributor_docs/documentation_style_guide.md
index 3ef6b8f30e..d2299b27ab 100644
--- a/contributor_docs/documentation_style_guide.md
+++ b/contributor_docs/documentation_style_guide.md
@@ -15,7 +15,7 @@ Our community is large and diverse. Many people learn to code using p5.js, and a
## Table of Contents
### Writing
-- [YUIDoc](#yuidoc)
+- [documentation.js and JSDoc](#documentationjs-and-jsdoc)
- [English](#english)
- [Oxford Comma](#oxford-comma)
- [Wording](#wording)
@@ -42,15 +42,13 @@ Our community is large and diverse. Many people learn to code using p5.js, and a
- [Classes](#classes)
- [Assets](#assets)
-## YUIDoc
+## documentation.js and JSDoc
-We use YUIDoc to generate the p5.js API documentation. To generate the docs, navigate to the p5.js root directory, run `npm install`, and execute:
+We use [documentation.js](https://documentation.js.org/) to generate the p5.js API documentation from [JSDoc](https://jsdoc.app/) comments in the p5.js source code.
-```
-$ npm run grunt yui:dev
-```
+Refer to the [inline documentation guide](./contributing_to_the_p5js_reference.md) for more information on how to structure the documentation comments and what tags to use.
-The output will appear in docs/reference. Refer to the [inline documentation guide](./contributing_to_the_p5js_reference.md) for more information.
+It also discusses how to [generate and preview the reference documentation](./contributing_to_the_p5js_reference/#generating-and-previewing-the-reference) to see your changes.
**[⬆ back to top](#table-of-contents)**
@@ -141,7 +139,7 @@ Always use `let` to declare variables.
**Accessibility terminology**
-The following terminology is adapted from the WordPress documentation guidelines for [Writing inclusive documentation](https://make.wordpress.org/docs/style-guide/general-guidelines/inclusivity/#accessibility-terminology). For more background on people-first language, see the CDC's guide on [Communicating With and About People with Disabilities](https://www.cdc.gov/ncbddd/disabilityandhealth/materials/factsheets/fs-communicating-with-people.html).
+The following terminology is adapted from the WordPress documentation guidelines for [Writing inclusive documentation](https://make.wordpress.org/docs/style-guide/general-guidelines/inclusivity/#accessibility-terminology). For more background on people-first language, see the CDC's guide on [Communicating With and About People with Disabilities](https://www.cdc.gov/disability-and-health/articles-documents/communicating-with-and-about-people-with-disabilities.html).
| Recommended | Not Recommended |
| -- | -- |
@@ -1267,25 +1265,30 @@ class Mover {
## Assets
-- Always load assets from a folder called "assets".
+Whether assets (such as images, fonts, sound files, etc) are being used in the descriptions or code examples of the reference documentation, or in tutorials, the same rules apply:
-> Why? It models good project organization. It's also required for assets to load on the p5.js website. Place assets in the following folders to include them in our online documentation:
-- Examples: [src/data/examples/assets](https://github.com/processing/p5.js-website/tree/main/src/data/examples)
-- Reference Pages: [src/templates/pages/reference/assets](https://github.com/processing/p5.js-website/tree/main/src/templates/pages/reference/assets)
-- Learn Pages: [src/assets/learn](https://github.com/processing/p5.js-website/tree/main/src/assets/learn)
+- Always load assets from a folder called `assets`.
+- Store the assets in the `public/assets` folder of the p5.js-website repository.
+
+> Why? It models good project organization. It's also required for assets to load on the p5.js website.
```javascript
let img;
// Bad.
-function preload() {
- img = loadImage('moonwalk.jpg');
+async function setup() {
+ img = await loadImage('moonwalk.jpg');
+ //...
}
// Good.
-function preload() {
- img = loadImage('assets/moonwalk.jpg');
+async function setup() {
+ img = await loadImage('assets/moonwalk.jpg');
+ //...
}
```
+There is more on working with assets in the guide: [Contributing to the p5.js reference](./contributing_to_the_p5js_reference/#using-assets).
+
+
**[⬆ back to top](#table-of-contents)**
diff --git a/contributor_docs/jsdoc.md b/contributor_docs/jsdoc.md
index f996d53f18..63f0349bd1 100644
--- a/contributor_docs/jsdoc.md
+++ b/contributor_docs/jsdoc.md
@@ -1,153 +1,3 @@
# JSDoc Best Practices
-Documentation on the website is built from the comments in the p5.js repo. Here are a few things to keep in mind in order for the documentation to be parsed correctly!
-
-## For everything
-
-- At the top of a file, add a comment with the `@module` tag, and optionally also the `@submodule`. These reference the category and subcategory names that the contents of the file should appear under in the reference:
-
- e.g. for just a category:
- ```js
- /**
- * @module Rendering
- */
- ```
-
- e.g. for both:
- ```js
- /**
- * @module Data
- * @submodule LocalStorage
- */
- ```
-
-## For classes
-
-
-- Create classes *outside* of the addon function, and assign them to `p5` *inside.* The class name should be the same always:
-
- ```js
- class MyClass {
- // ...
- }
-
- export default function myAddon(p5, fn) {
- p5.MyClass = MyClass;
- }
- ```
-
-- Document class methods directly above the members in classes, *without* a `@method` tag:
-
- ```js
- class MyClass {
- /**
- * Description goes here
- */
- myMethod() {
- return 4;
- }
- }
- ```
-
-- Documentation for the class itself should go at the spot where the class is added to `p5` and not right next to the class definition. This needs to include the `@class` tag, including a `p5.` prefix on the class name. Also include the parameters for the constructor in this description, if they exist.
-
- ```js
- class MyClass {
- constructor(n) {
- this.n = n;
- }
- }
-
- export default function myAddon(p5, fn) {
- /**
- * Description of the class goes here!
- *
- * @class p5.MyClass
- * @param {Number} n A number to pass in
- */
- p5.MyClass = MyClass;
- }
- ```
-
-- Documentation for class properties should appear after the class is added to `p5`, not within the class itself. It needs to have the `@for` tag referencing its class, and the `@property` tag naming the property itself:
-
- ```js
- class MyClass {
- myProperty;
- constructor() {
- myProperty = 2;
- }
- }
-
- export default function myAddon(p5, fn) {
- /**
- * Description of the class goes here!
- *
- * @class p5.MyClass
- */
- p5.MyClass = MyClass;
-
- /**
- * Description of the property goes here!
- *
- * @property {Number} myProperty
- * @for p5.MyClass
- */
- }
- ```
-
-## For global functions
-
-- Add a comment with the `@method` tag listing its name:
-
- ```js
- export default function myAddon(p5, fn) {
- /**
- * Description goes here!
- *
- * @method myFunction
- */
- p5.myFunction = function() {
- return 8;
- };
- }
- ```
-
-- For dynamically generated methods, do the same as usual, but add `@for p5`.
-
- ```js
- function myAddon(p5, fn) {
- for (const key of ['nameA', 'nameB']) {
- fn[key] = function() {
- return `Hello from ${key}!`;
- };
- }
-
- /**
- * @method nameA
- * @for p5
- */
-
- /**
- * @method nameB
- * @for p5
- */
- }
- ```
-
-- Mark things that you don't want showing up as `@private`. This is done automatically for methods whose names start with `_`.
-
- ```js
- class MyClass {
- /**
- * @private
- */
- privateMethodA() {
- // ...
- }
-
- _privateMethodB() {
- // ...
- }
- }
- ```
+This material has been moved into [Contributing to the p5.js Reference](./contributing_to_the_p5js_reference.md)
\ No newline at end of file