@ca-plant-list/ca-plant-list 0.4.21 → 0.4.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/data/exceptions.json +22 -1
- package/data/synonyms.csv +2 -0
- package/data/taxa.csv +1754 -1753
- package/lib/basepagerenderer.js +10 -4
- package/lib/ebook/images.js +3 -3
- package/lib/ebook/pages/{page_list_families.js → pageListFamilies.js} +1 -1
- package/lib/ebook/pages/{page_list_flowers.js → pageListFlowers.js} +2 -2
- package/lib/ebook/pages/page_list_species.js +1 -1
- package/lib/ebook/pages/taxonpage.js +1 -1
- package/lib/ebook/pages/tocpage.js +2 -2
- package/lib/ebook/plantbook.js +3 -3
- package/lib/errorlog.js +1 -1
- package/lib/externalsites.js +113 -35
- package/lib/files.js +3 -5
- package/lib/flowercolor.js +2 -2
- package/lib/genera.js +4 -4
- package/lib/html.js +7 -8
- package/lib/htmltaxon.js +122 -33
- package/lib/index.d.ts +72 -27
- package/lib/index.js +3 -3
- package/lib/pagerenderer.js +6 -6
- package/lib/taxonomy/families.js +104 -0
- package/lib/{taxa.js → taxonomy/taxa.js} +18 -18
- package/lib/{taxon.js → taxonomy/taxon.js} +41 -111
- package/lib/taxonomy/taxonomy.js +17 -0
- package/lib/tools/calflora.js +2 -2
- package/lib/tools/calscape.js +3 -3
- package/lib/tools/cch2.js +128 -10
- package/lib/tools/fna.js +163 -0
- package/lib/tools/inat.js +3 -3
- package/lib/tools/jepsoneflora.js +21 -2
- package/lib/tools/rpi.js +5 -5
- package/lib/tools/supplementaltext.js +1 -1
- package/lib/tools/taxacsv.js +23 -4
- package/lib/types.js +10 -0
- package/lib/utils/inat-tools.js +2 -2
- package/lib/web/pageFamily.js +146 -0
- package/lib/web/pagetaxon.js +21 -63
- package/package.json +2 -1
- package/scripts/build-ebook.js +4 -4
- package/scripts/build-site.js +3 -3
- package/scripts/cpl-photos.js +1 -1
- package/scripts/cpl-tools.js +18 -2
- package/scripts/inatobsphotos.js +2 -2
- package/scripts/inattaxonphotos.js +2 -2
- package/lib/families.js +0 -243
- package/lib/jepson.js +0 -17
package/lib/basepagerenderer.js
CHANGED
@@ -2,12 +2,13 @@ import { Config } from "./config.js";
|
|
2
2
|
import { Files } from "./files.js";
|
3
3
|
import { Jekyll } from "./jekyll.js";
|
4
4
|
import { GlossaryPages } from "./web/glossarypages.js";
|
5
|
+
import { PageFamilyList } from "./web/pageFamily.js";
|
5
6
|
|
6
7
|
class BasePageRenderer {
|
7
8
|
/**
|
8
9
|
* @param {string} outputDir
|
9
|
-
* @param {import("./
|
10
|
-
* @param {import("./
|
10
|
+
* @param {import("./types.js").Taxa} taxa
|
11
|
+
* @param {import("./types.js").TaxaColDef[]} [familyCols]
|
11
12
|
*/
|
12
13
|
static renderBasePages(outputDir, taxa, familyCols) {
|
13
14
|
const siteGenerator = new Jekyll(outputDir);
|
@@ -21,7 +22,12 @@ class BasePageRenderer {
|
|
21
22
|
// Copy illustrations.
|
22
23
|
siteGenerator.copyIllustrations(taxa.getFlowerColors());
|
23
24
|
|
24
|
-
|
25
|
+
const fl = new PageFamilyList(
|
26
|
+
outputDir,
|
27
|
+
taxa.getFamilies().getFamilies(),
|
28
|
+
);
|
29
|
+
fl.render(familyCols);
|
30
|
+
fl.renderPages(outputDir, familyCols);
|
25
31
|
|
26
32
|
new GlossaryPages(siteGenerator).renderPages();
|
27
33
|
|
@@ -30,7 +36,7 @@ class BasePageRenderer {
|
|
30
36
|
|
31
37
|
/**
|
32
38
|
* @param {string} outputDir
|
33
|
-
* @param {import("./
|
39
|
+
* @param {import("./types.js").Taxa} taxa
|
34
40
|
*/
|
35
41
|
static renderTools(outputDir, taxa) {
|
36
42
|
const names = [];
|
package/lib/ebook/images.js
CHANGED
@@ -14,7 +14,7 @@ class Images {
|
|
14
14
|
/**
|
15
15
|
* @param {import("../sitegenerator.js").SiteGenerator} siteGenerator
|
16
16
|
* @param {string} contentDir
|
17
|
-
* @param {import("../
|
17
|
+
* @param {import("../types.js").Taxa} taxa
|
18
18
|
*/
|
19
19
|
constructor(siteGenerator, contentDir, taxa) {
|
20
20
|
this.#siteGenerator = siteGenerator;
|
@@ -23,7 +23,7 @@ class Images {
|
|
23
23
|
}
|
24
24
|
|
25
25
|
/**
|
26
|
-
* @param {import("../taxon.js").Taxon[]} taxa
|
26
|
+
* @param {import("../taxonomy/taxon.js").Taxon[]} taxa
|
27
27
|
*/
|
28
28
|
async createImages(taxa) {
|
29
29
|
const meter = new ProgressMeter("processing photos", taxa.length);
|
@@ -118,7 +118,7 @@ class Images {
|
|
118
118
|
}
|
119
119
|
|
120
120
|
/**
|
121
|
-
* @param {import("../taxon.js").Taxon} taxon
|
121
|
+
* @param {import("../taxonomy/taxon.js").Taxon} taxon
|
122
122
|
* @returns {import("../photo.js").Photo[]}
|
123
123
|
*/
|
124
124
|
static getTaxonPhotos(taxon) {
|
@@ -6,7 +6,7 @@ class PageListFamilies extends EBookPage {
|
|
6
6
|
|
7
7
|
/**
|
8
8
|
* @param {string} outputDir
|
9
|
-
* @param {import("../../
|
9
|
+
* @param {import("../../types.js").Families} families
|
10
10
|
*/
|
11
11
|
constructor(outputDir, families) {
|
12
12
|
super(outputDir + "/list_families.html", "All Families");
|
@@ -8,7 +8,7 @@ const FN_FLOWER_TIME_INDEX = "fm.html";
|
|
8
8
|
class PageListFlowers {
|
9
9
|
/**
|
10
10
|
* @param {string} contentDir
|
11
|
-
* @param {import("../../
|
11
|
+
* @param {import("../../types.js").Taxa} taxa
|
12
12
|
*/
|
13
13
|
static createPages(contentDir, taxa) {
|
14
14
|
new PageListFlowerTimeIndex(contentDir).create();
|
@@ -83,7 +83,7 @@ class PageListFlowerTime extends EBookPage {
|
|
83
83
|
|
84
84
|
/**
|
85
85
|
* @param {string} outputDir
|
86
|
-
* @param {import("../../
|
86
|
+
* @param {import("../../types.js").Taxa} taxa
|
87
87
|
* @param {number} month
|
88
88
|
*/
|
89
89
|
constructor(outputDir, taxa, month) {
|
@@ -13,7 +13,7 @@ class TaxonPage extends EBookPage {
|
|
13
13
|
|
14
14
|
/**
|
15
15
|
* @param {string} outputDir
|
16
|
-
* @param {import("../../taxon.js").Taxon} taxon
|
16
|
+
* @param {import("../../taxonomy/taxon.js").Taxon} taxon
|
17
17
|
* @param {Images} images
|
18
18
|
*/
|
19
19
|
constructor(outputDir, taxon, images) {
|
@@ -1,13 +1,13 @@
|
|
1
1
|
import { EBookPage } from "../ebookpage.js";
|
2
2
|
import { XHTML } from "../xhtml.js";
|
3
|
-
import { PageListFlowers } from "./
|
3
|
+
import { PageListFlowers } from "./pageListFlowers.js";
|
4
4
|
|
5
5
|
class TOCPage extends EBookPage {
|
6
6
|
#taxa;
|
7
7
|
|
8
8
|
/**
|
9
9
|
* @param {string} outputDir
|
10
|
-
* @param {import("../../taxa.js").Taxa} taxa
|
10
|
+
* @param {import("../../taxonomy/taxa.js").Taxa} taxa
|
11
11
|
*/
|
12
12
|
constructor(outputDir, taxa) {
|
13
13
|
super(outputDir + "/toc.xhtml", "Table of Contents");
|
package/lib/ebook/plantbook.js
CHANGED
@@ -3,9 +3,9 @@ import { EBook } from "./ebook.js";
|
|
3
3
|
import { EBookSiteGenerator } from "./ebooksitegenerator.js";
|
4
4
|
import { GlossaryPages } from "./glossarypages.js";
|
5
5
|
import { Images } from "./images.js";
|
6
|
-
import { PageListFamilies } from "./pages/
|
6
|
+
import { PageListFamilies } from "./pages/pageListFamilies.js";
|
7
7
|
import { PageListFlowerColor } from "./pages/page_list_flower_color.js";
|
8
|
-
import { PageListFlowers } from "./pages/
|
8
|
+
import { PageListFlowers } from "./pages/pageListFlowers.js";
|
9
9
|
import { PageListSpecies } from "./pages/page_list_species.js";
|
10
10
|
import { TaxonPage } from "./pages/taxonpage.js";
|
11
11
|
import { TOCPage } from "./pages/tocpage.js";
|
@@ -18,7 +18,7 @@ class PlantBook extends EBook {
|
|
18
18
|
/**
|
19
19
|
* @param {string} outputDir
|
20
20
|
* @param {import("../config.js").Config} config
|
21
|
-
* @param {import("../
|
21
|
+
* @param {import("../types.js").Taxa} taxa
|
22
22
|
*/
|
23
23
|
constructor(outputDir, config, taxa) {
|
24
24
|
super(
|
package/lib/errorlog.js
CHANGED
package/lib/externalsites.js
CHANGED
@@ -1,13 +1,51 @@
|
|
1
|
-
/** @typedef {{
|
2
|
-
coords?: [number, number];
|
3
|
-
project_id?: string;
|
4
|
-
subview?: "grid" | "list" | "map";
|
5
|
-
taxon_id?: string;
|
6
|
-
}} InatObsOptions */
|
7
|
-
|
8
1
|
export class ExternalSites {
|
9
2
|
/**
|
10
|
-
* @param {import("./
|
3
|
+
* @param {import("./types.js").Taxon} taxon
|
4
|
+
* @param {import("./types.js").Config} config
|
5
|
+
* @returns {URL|undefined}
|
6
|
+
*/
|
7
|
+
static getCalfloraObsLink(taxon, config) {
|
8
|
+
const name = taxon.getCalfloraName();
|
9
|
+
if (!name) {
|
10
|
+
return;
|
11
|
+
}
|
12
|
+
const url = new URL(
|
13
|
+
"https://www.calflora.org/entry/observ.html?track=m#srch=t&grezc=5&cols=b&lpcli=t&cc=" +
|
14
|
+
config.getCountyCodes().join("!") +
|
15
|
+
"&incobs=f&taxon=" +
|
16
|
+
name,
|
17
|
+
);
|
18
|
+
return url;
|
19
|
+
}
|
20
|
+
|
21
|
+
/**
|
22
|
+
* @param {import("./types.js").Taxon} taxon
|
23
|
+
* @returns {URL|undefined}
|
24
|
+
*/
|
25
|
+
static getCalfloraRefLink(taxon) {
|
26
|
+
const calfloraID = taxon.getCalfloraID();
|
27
|
+
if (!calfloraID) {
|
28
|
+
return;
|
29
|
+
}
|
30
|
+
return new URL("https://www.calflora.org/app/taxon?crn=" + calfloraID);
|
31
|
+
}
|
32
|
+
|
33
|
+
/**
|
34
|
+
* @param {import("./types.js").Taxon} taxon
|
35
|
+
* @returns {URL|undefined}
|
36
|
+
*/
|
37
|
+
static getCalscapeLink(taxon) {
|
38
|
+
const calscapeCN = taxon.getCalscapeCommonName();
|
39
|
+
if (!calscapeCN) {
|
40
|
+
return;
|
41
|
+
}
|
42
|
+
return new URL(
|
43
|
+
`https://www.calscape.org/${taxon.getCalscapeName().replaceAll(" ", "-")}-()`,
|
44
|
+
);
|
45
|
+
}
|
46
|
+
|
47
|
+
/**
|
48
|
+
* @param {import("./types.js").Taxon} taxon
|
11
49
|
* @param {import("./config.js").Config} config
|
12
50
|
* @returns {URL|undefined}
|
13
51
|
*/
|
@@ -21,7 +59,7 @@ export class ExternalSites {
|
|
21
59
|
}
|
22
60
|
|
23
61
|
/**
|
24
|
-
* @param {import("./
|
62
|
+
* @param {import("./types.js").Taxon} taxon
|
25
63
|
* @returns {URL|undefined}
|
26
64
|
*/
|
27
65
|
static getCCH2RefLink(taxon) {
|
@@ -35,40 +73,80 @@ export class ExternalSites {
|
|
35
73
|
}
|
36
74
|
|
37
75
|
/**
|
38
|
-
* @param {
|
76
|
+
* @param {import("./types.js").Taxon} taxon
|
77
|
+
* @returns {URL|undefined}
|
39
78
|
*/
|
40
|
-
static
|
79
|
+
static getFNARefLink(taxon) {
|
80
|
+
const name = taxon.getFNAName();
|
81
|
+
if (!name) {
|
82
|
+
return;
|
83
|
+
}
|
41
84
|
const url = new URL(
|
42
|
-
"
|
85
|
+
"http://floranorthamerica.org/" + name.replaceAll(" ", "_"),
|
43
86
|
);
|
87
|
+
return url;
|
88
|
+
}
|
44
89
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
90
|
+
/**
|
91
|
+
* @param {import("./types.js").Taxon} taxon
|
92
|
+
* @param {import("./config.js").Config} config
|
93
|
+
* @returns {URL|undefined}
|
94
|
+
*/
|
95
|
+
static getInatObsLink(taxon, config) {
|
96
|
+
const iNatID = taxon.getINatID();
|
97
|
+
if (!iNatID) {
|
98
|
+
return;
|
54
99
|
}
|
55
100
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
case "taxon_name":
|
65
|
-
if (typeof v === "string") {
|
66
|
-
url.searchParams.set(k, v);
|
67
|
-
}
|
68
|
-
break;
|
101
|
+
const url = new URL(
|
102
|
+
"https://www.inaturalist.org/observations?subview=map",
|
103
|
+
);
|
104
|
+
url.searchParams.set("taxon_id", iNatID);
|
105
|
+
for (const p of ["place_id", "project_id"]) {
|
106
|
+
const v = config.getConfigValue("inat", p);
|
107
|
+
if (v) {
|
108
|
+
url.searchParams.set(p, v);
|
69
109
|
}
|
70
110
|
}
|
71
111
|
|
72
|
-
return url
|
112
|
+
return url;
|
113
|
+
}
|
114
|
+
|
115
|
+
/**
|
116
|
+
* @param {import("./types.js").Taxon} taxon
|
117
|
+
* @returns {URL|undefined}
|
118
|
+
*/
|
119
|
+
static getINatRefLink(taxon) {
|
120
|
+
const iNatID = taxon.getINatID();
|
121
|
+
if (!iNatID) {
|
122
|
+
return;
|
123
|
+
}
|
124
|
+
return new URL("https://www.inaturalist.org/taxa/" + iNatID);
|
125
|
+
}
|
126
|
+
|
127
|
+
/**
|
128
|
+
* @param {import("./types.js").Taxonomy} taxon
|
129
|
+
* @returns {URL|undefined}
|
130
|
+
*/
|
131
|
+
static getJepsonRefLink(taxon) {
|
132
|
+
const id = taxon.getJepsonID();
|
133
|
+
if (!id) {
|
134
|
+
return;
|
135
|
+
}
|
136
|
+
return new URL(
|
137
|
+
"https://ucjeps.berkeley.edu/eflora/eflora_display.php?tid=" + id,
|
138
|
+
);
|
139
|
+
}
|
140
|
+
|
141
|
+
/**
|
142
|
+
* @param {import("./types.js").Taxon} taxon
|
143
|
+
* @returns {URL|undefined}
|
144
|
+
*/
|
145
|
+
static getRPIRefLink(taxon) {
|
146
|
+
const rpiID = taxon.getRPIID();
|
147
|
+
if (!rpiID) {
|
148
|
+
return;
|
149
|
+
}
|
150
|
+
return new URL("https://rareplants.cnps.org/Plants/Details/" + rpiID);
|
73
151
|
}
|
74
152
|
}
|
package/lib/files.js
CHANGED
@@ -13,15 +13,13 @@ class Files {
|
|
13
13
|
|
14
14
|
/**
|
15
15
|
* @param {string} fileName
|
16
|
-
* @param {
|
17
|
-
* @access private
|
16
|
+
* @param {import("node:stream").Stream} inStream
|
18
17
|
*/
|
19
18
|
static #createFileFromStream(fileName, inStream) {
|
20
19
|
/**
|
21
|
-
*
|
22
20
|
* @param {string} fileName
|
23
|
-
* @param {
|
24
|
-
* @param {
|
21
|
+
* @param {import("node:stream").Stream} inStream
|
22
|
+
* @param {function(boolean):void} resolve
|
25
23
|
*/
|
26
24
|
function implementation(fileName, inStream, resolve) {
|
27
25
|
const outStream = fs.createWriteStream(fileName);
|
package/lib/flowercolor.js
CHANGED
@@ -3,7 +3,7 @@ import { TextUtils } from "./textutils.js";
|
|
3
3
|
class FlowerColor {
|
4
4
|
#colorName;
|
5
5
|
#colorCode;
|
6
|
-
/** @type {import("./
|
6
|
+
/** @type {import("./types.js").Taxon[]} */
|
7
7
|
#taxa = [];
|
8
8
|
|
9
9
|
/**
|
@@ -16,7 +16,7 @@ class FlowerColor {
|
|
16
16
|
}
|
17
17
|
|
18
18
|
/**
|
19
|
-
* @param {import("./
|
19
|
+
* @param {import("./types.js").Taxon} taxon
|
20
20
|
*/
|
21
21
|
addTaxon(taxon) {
|
22
22
|
this.#taxa.push(taxon);
|
package/lib/genera.js
CHANGED
@@ -6,7 +6,7 @@ class Genera {
|
|
6
6
|
#genera;
|
7
7
|
|
8
8
|
/**
|
9
|
-
* @param {import("./
|
9
|
+
* @param {import("./types.js").Families} families
|
10
10
|
*/
|
11
11
|
constructor(families) {
|
12
12
|
const dataDir = Config.getPackageDir() + "/data";
|
@@ -15,7 +15,7 @@ class Genera {
|
|
15
15
|
}
|
16
16
|
|
17
17
|
/**
|
18
|
-
* @param {import("./
|
18
|
+
* @param {import("./types.js").Taxon} taxon
|
19
19
|
*/
|
20
20
|
addTaxon(taxon) {
|
21
21
|
const genusName = taxon.getGenusName();
|
@@ -46,7 +46,7 @@ class Genus {
|
|
46
46
|
#data;
|
47
47
|
|
48
48
|
/**
|
49
|
-
* @param {{family:string,familyObj:import("./
|
49
|
+
* @param {{family:string,familyObj:import("./types.js").Family,taxa:import("./types.js").Taxon[]}} data
|
50
50
|
*/
|
51
51
|
constructor(data) {
|
52
52
|
this.#data = data;
|
@@ -57,7 +57,7 @@ class Genus {
|
|
57
57
|
}
|
58
58
|
|
59
59
|
/**
|
60
|
-
* @returns {import("./
|
60
|
+
* @returns {import("./types.js").Taxon[]}
|
61
61
|
*/
|
62
62
|
getTaxa() {
|
63
63
|
return this.#data.taxa.sort((a, b) =>
|
package/lib/html.js
CHANGED
@@ -48,7 +48,7 @@ export class HTML {
|
|
48
48
|
|
49
49
|
/**
|
50
50
|
* Generate HTML for an <a> element.
|
51
|
-
* @param {string|undefined} href
|
51
|
+
* @param {URL|string|undefined} href
|
52
52
|
* @param {string} linkText
|
53
53
|
* @param {string|Object<string,string>} [attributes]
|
54
54
|
* @param {boolean} [openInNewWindow] true if the link should open in a new window.
|
@@ -57,7 +57,7 @@ export class HTML {
|
|
57
57
|
static getLink(href, linkText, attributes = {}, openInNewWindow) {
|
58
58
|
let html = "<a";
|
59
59
|
if (href !== undefined) {
|
60
|
-
html += this.renderAttribute("href", href);
|
60
|
+
html += this.renderAttribute("href", href.toString());
|
61
61
|
}
|
62
62
|
html += this.renderAttributes(attributes);
|
63
63
|
if (openInNewWindow) {
|
@@ -70,8 +70,7 @@ export class HTML {
|
|
70
70
|
* Get a Bootstrap formatted tooltip element.
|
71
71
|
* @param {string} text - The text or HTML that should trigger the tooltip on hover.
|
72
72
|
* @param {string} tooltip - The tooltip text or HTML.
|
73
|
-
* @param {
|
74
|
-
* @param {boolean} [options.icon] [true] display an icon after the text
|
73
|
+
* @param {{icon?:boolean}} options
|
75
74
|
* @returns {string} A <span> element to be used as a Bootstrap tooltip.
|
76
75
|
*/
|
77
76
|
static getToolTip(text, tooltip, options = {}) {
|
@@ -106,19 +105,19 @@ export class HTML {
|
|
106
105
|
|
107
106
|
/**
|
108
107
|
* @param {string} elName
|
109
|
-
* @param {string} text
|
108
|
+
* @param {string|number} text
|
110
109
|
* @param {Object<string,string>} [attributes]
|
111
110
|
*/
|
112
111
|
static textElement(elName, text, attributes = {}) {
|
113
|
-
return HTML.#getElement(elName, text, attributes, true);
|
112
|
+
return HTML.#getElement(elName, text.toString(), attributes, true);
|
114
113
|
}
|
115
114
|
|
116
115
|
/**
|
117
116
|
* @param {string} elName
|
118
|
-
* @param {string} text
|
117
|
+
* @param {string|number} text
|
119
118
|
* @param {string|Object<string,string>|undefined} [attributes]
|
120
119
|
*/
|
121
120
|
static wrap(elName, text, attributes) {
|
122
|
-
return HTML.#getElement(elName, text, attributes, false);
|
121
|
+
return HTML.#getElement(elName, text.toString(), attributes, false);
|
123
122
|
}
|
124
123
|
}
|