Skip to content

Commit f2879e9

Browse files
committed
copy jsdocs from README to code
1 parent f132711 commit f2879e9

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+650
-2711
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
.DS_Store
2+
build/
23
dist/
34
types/
45
node_modules/

README.md

+466-975
Large diffs are not rendered by default.

package.json

+3-6
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,11 @@
2828
"types/**/*.d.ts"
2929
],
3030
"scripts": {
31-
"test": "yarn test:mocha && yarn test:typecheck && yarn test:lint && yarn readme:check",
31+
"test": "yarn test:mocha && yarn test:typecheck && yarn test:lint",
3232
"test:mocha": "mkdir -p test/output && mocha --conditions=mocha 'test/**/*-test.*' 'test/plot.js'",
3333
"test:lint": "eslint src test",
3434
"test:typecheck": "tsc --noEmit",
35-
"readme:check": "tsx scripts/jsdoc-to-readme.ts --check",
36-
"readme:update": "tsx scripts/jsdoc-to-readme.ts",
37-
"prepublishOnly": "rm -rf dist && rollup -c && tsc",
35+
"prepublishOnly": "rm -rf build dist && rollup -c && tsc && tsx scripts/readme-to-jsdoc.ts",
3836
"postpublish": "git push && git push --tags",
3937
"dev": "vite"
4038
},
@@ -62,13 +60,12 @@
6260
"htl": "0.3",
6361
"js-beautify": "1",
6462
"jsdom": "19",
63+
"mkdirp": "^1.0.4",
6564
"mocha": "10",
6665
"module-alias": "2",
6766
"prettier": "^2.7.1",
6867
"rollup": "2",
6968
"rollup-plugin-terser": "7",
70-
"ts-morph": "^15.1.0",
71-
"tslib": "^2.4.0",
7269
"tsx": "^3.8.0",
7370
"typescript": "^4.6.4",
7471
"typescript-module-alias": "^1.0.2",

rollup.config.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export default [
3838
name: "Plot",
3939
format: "umd",
4040
extend: true,
41-
file: `dist/${filename}.umd.js`,
41+
file: `build/${filename}.umd.js`,
4242
globals: {d3: "d3"},
4343
paths: {d3: d3Path}
4444
}

scripts/jsdoc-to-readme.ts

-119
This file was deleted.

scripts/readme-to-jsdoc.ts

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import {readFileSync, writeFileSync} from "fs";
2+
import {dirname} from "path";
3+
import glob from "glob";
4+
import mkdirp from "mkdirp";
5+
6+
// Extract the documentation from the README.
7+
const readme = readFileSync("./README.md", "utf-8");
8+
const docmap = new Map<string, string[]>();
9+
let doc: {name: string; lines: string[]} | null = null;
10+
for (const [i, line] of readme.split("\n").entries()) {
11+
if (/<!--\s*jsdoc/.test(line)) {
12+
let match: RegExpExecArray | null;
13+
if ((match = /^<!--\s+jsdoc\s+(\w+)\s+-->$/.exec(line))) {
14+
const [, name] = match;
15+
if (doc) {
16+
throw new Error(`nested jsdoc directive on line ${i}: ${line}`);
17+
}
18+
if (docmap.has(name)) {
19+
throw new Error(`duplicate jsdoc directive on line ${i}: ${line}`);
20+
}
21+
doc = {name, lines: []};
22+
} else if ((match = /^<!--\s+jsdocEnd\s+(\w+)\s+-->$/.exec(line))) {
23+
const [, name] = match;
24+
if (!doc) {
25+
throw new Error(`orphaned jsdocEnd directive on line ${i}: ${line}`);
26+
}
27+
if (doc.name !== name) {
28+
throw new Error(`mismatched jsdocEnd ${doc.name} directive on line ${i}: ${line}`);
29+
}
30+
docmap.set(doc.name, doc.lines);
31+
doc = null;
32+
} else {
33+
throw new Error(`malformed jsdoc directive on line ${i}: ${line}`);
34+
}
35+
} else if (doc) {
36+
doc.lines.push(line);
37+
}
38+
}
39+
40+
// Make relative and anchor links absolute.
41+
for (const lines of docmap.values()) {
42+
for (let i = 0, n = lines.length; i < n; ++i) {
43+
const iline = lines[i];
44+
const oline = iline
45+
.replace(/\]\(#([^)]+)\)/g, "](./README.md#$1)")
46+
.replace(/\]\(\.\/([^)]+)\)/g, "](https://github.com/observablehq/plot/blob/main/$1)");
47+
if (iline !== oline) {
48+
process.stdout.write(`\x1b[2m${iline}\x1b[0m → \x1b[36m${oline}\x1b[0m\n`);
49+
process.exit(1);
50+
}
51+
}
52+
}
53+
54+
// Copy files from build/ to dist/, replacing /** @jsdoc name */ directives.
55+
const unused = new Set(docmap.keys());
56+
for (const file of glob.sync("build/**/*.js")) {
57+
process.stdout.write(`\x1b[2m${file}\x1b[0m`);
58+
const lines = readFileSync(file, "utf-8").split("\n");
59+
let count = 0;
60+
for (let i = 0, n = lines.length; i < n; ++i) {
61+
let match: RegExpExecArray | null;
62+
if ((match = /^\/\*\*\s+@jsdoc\s+(\w+)\s+\*\/$/.exec(lines[i]))) {
63+
const [, name] = match;
64+
const docs = docmap.get(name);
65+
if (!docs) throw new Error(`missing @jsdoc definition: ${name}`);
66+
if (file === "build/plot.umd.js") "ignore";
67+
else if (!unused.has(name)) throw new Error(`duplicate @jsdoc reference: ${name}`);
68+
else unused.delete(name);
69+
++count;
70+
lines[i] = docs
71+
.map((line, i, lines) => (i === 0 ? `/** ${line}` : i === lines.length - 1 ? ` * ${line}\n */` : ` * ${line}`))
72+
.join("\n");
73+
}
74+
}
75+
const ofile = file.replace(/^build\//, "dist/");
76+
process.stdout.write(` → \x1b[36m${ofile}\x1b[0m${count ? ` (${count} jsdoc${count === 1 ? "" : "s"})` : ""}\n`);
77+
const odir = dirname(ofile);
78+
mkdirp.sync(odir);
79+
writeFileSync(ofile, lines.join("\n"), "utf-8");
80+
}
81+
82+
for (const name of unused) {
83+
console.warn(`\x1b[33m[warning] unused @jsdoc directive:\x1b[0m ${name}`);
84+
}

src/format.ts

+3-33
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,7 @@ export function formatNumber(locale = "en-US"): (value: any) => string | undefin
2020
return (i: any) => (i != null && !isNaN(i) ? format.format(i) : undefined);
2121
}
2222

23-
/**
24-
* ```js
25-
* Plot.formatMonth("es-MX", "long")(0) // "enero"
26-
* ```
27-
*
28-
* Returns a function that formats a given month number (from 0 = January to 11
29-
* = December) according to the specified *locale* and *format*. The *locale* is
30-
* a [BCP 47 language tag](https://tools.ietf.org/html/bcp47) and defaults to
31-
* U.S. English. The *format* is a [month
32-
* format](https://tc39.es/ecma402/#datetimeformat-objects): either *2-digit*,
33-
* *numeric*, *narrow*, *short*, *long*; if not specified, it defaults to
34-
* *short*.
35-
*/
23+
/** @jsdoc formatMonth */
3624
export function formatMonth(
3725
locale = "en-US",
3826
format: "numeric" | "2-digit" | "long" | "short" | "narrow" | undefined = "short"
@@ -42,32 +30,14 @@ export function formatMonth(
4230
i != null && !isNaN((i = +new Date(Date.UTC(2000, +i)))) ? fmt.format(i) : undefined;
4331
}
4432

45-
/**
46-
* ```js
47-
* Plot.formatWeekday("es-MX", "long")(0) // "domingo"
48-
* ```
49-
*
50-
* Returns a function that formats a given week day number (from 0 = Sunday to 6
51-
* = Saturday) according to the specified *locale* and *format*. The *locale* is
52-
* a [BCP 47 language tag](https://tools.ietf.org/html/bcp47) and defaults to
53-
* U.S. English. The *format* is a [weekday
54-
* format](https://tc39.es/ecma402/#datetimeformat-objects): either *narrow*,
55-
* *short*, or *long*; if not specified, it defaults to *short*.
56-
*/
33+
/** @jsdoc formatWeekday */
5734
export function formatWeekday(locale = "en-US", format: "long" | "short" | "narrow" | undefined = "short") {
5835
const fmt = weekdayFormat(locale, format);
5936
return (i: Date | number | null | undefined) =>
6037
i != null && !isNaN((i = +new Date(Date.UTC(2001, 0, +i)))) ? fmt.format(i) : undefined;
6138
}
6239

63-
/**
64-
* ```js
65-
* Plot.formatIsoDate(new Date("2020-01-01T00:00.000Z")) // "2020-01-01"
66-
* ```
67-
*
68-
* Given a *date*, returns the shortest equivalent ISO 8601 UTC string. If the
69-
* given *date* is not valid, returns `"Invalid Date"`.
70-
*/
40+
/** @jsdoc formatIsoDate */
7141
export function formatIsoDate(date: Date): string {
7242
return isoFormat(date, "Invalid Date");
7343
}

src/legends.js

+1-24
Original file line numberDiff line numberDiff line change
@@ -11,30 +11,7 @@ const legendRegistry = new Map([
1111
["opacity", legendOpacity]
1212
]);
1313

14-
/**
15-
* Returns a standalone legend for the scale defined by the given *options*
16-
* object. The *options* object must define at least one scale; see [Scale
17-
* options](https://github.com/observablehq/plot/blob/main/README.md#scale-options)
18-
* for how to define a scale. For example, here is a ramp legend of a linear
19-
* color scale with the default domain of [0, 1] and default scheme *turbo*:
20-
*
21-
* ```js
22-
* Plot.legend({color: {type: "linear"}})
23-
* ```
24-
*
25-
* The *options* object may also include any additional legend options described
26-
* in the previous section. For example, to make the above legend slightly
27-
* wider:
28-
*
29-
* ```js
30-
* Plot.legend({
31-
* width: 320,
32-
* color: {
33-
* type: "linear"
34-
* }
35-
* })
36-
* ```
37-
*/
14+
/** @jsdoc legend */
3815
export function legend(options = {}) {
3916
for (const [key, value] of legendRegistry) {
4017
const scale = options[key];

0 commit comments

Comments
 (0)