@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/scripts/build-site.js
CHANGED
@@ -6,7 +6,7 @@ import { Config } from "../lib/config.js";
|
|
6
6
|
import { PageRenderer } from "../lib/pagerenderer.js";
|
7
7
|
import { Files } from "../lib/files.js";
|
8
8
|
import { Program } from "../lib/program.js";
|
9
|
-
import { Taxa } from "../lib/taxa.js";
|
9
|
+
import { Taxa } from "../lib/taxonomy/taxa.js";
|
10
10
|
import { ErrorLog } from "../lib/errorlog.js";
|
11
11
|
|
12
12
|
class JekyllRenderer {
|
@@ -45,7 +45,7 @@ class JekyllRenderer {
|
|
45
45
|
options.push("--config", `"${configFiles.join()}"`);
|
46
46
|
|
47
47
|
const result = child_process.execSync(
|
48
|
-
"bundle exec jekyll build " + options.join(" ")
|
48
|
+
"bundle exec jekyll build " + options.join(" "),
|
49
49
|
);
|
50
50
|
console.log(result.toString());
|
51
51
|
}
|
@@ -60,7 +60,7 @@ async function build(options) {
|
|
60
60
|
const taxa = new Taxa(
|
61
61
|
Program.getIncludeList(options.datadir),
|
62
62
|
errorLog,
|
63
|
-
options.showFlowerErrors
|
63
|
+
options.showFlowerErrors,
|
64
64
|
);
|
65
65
|
PageRenderer.render(options.outputdir, new Config(options.datadir), taxa);
|
66
66
|
errorLog.write();
|
package/scripts/cpl-photos.js
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
import path from "path";
|
4
4
|
import { ErrorLog } from "../lib/errorlog.js";
|
5
5
|
import { Program } from "../lib/program.js";
|
6
|
-
import { Taxa } from "../lib/taxa.js";
|
6
|
+
import { Taxa } from "../lib/taxonomy/taxa.js";
|
7
7
|
import { getTaxonPhotos } from "../lib/utils/inat-tools.js";
|
8
8
|
import { existsSync } from "fs";
|
9
9
|
import { CSV } from "../lib/csv.js";
|
package/scripts/cpl-tools.js
CHANGED
@@ -10,15 +10,17 @@ import { INat } from "../lib/tools/inat.js";
|
|
10
10
|
import { JepsonEFlora } from "../lib/tools/jepsoneflora.js";
|
11
11
|
import { RPI } from "../lib/tools/rpi.js";
|
12
12
|
import { Config } from "../lib/config.js";
|
13
|
-
import { Taxa } from "../lib/taxa.js";
|
13
|
+
import { Taxa } from "../lib/taxonomy/taxa.js";
|
14
14
|
import { SupplementalText } from "../lib/tools/supplementaltext.js";
|
15
15
|
import { JepsonFamilies } from "../lib/tools/jepsonfamilies.js";
|
16
16
|
import { CCH2 } from "../lib/tools/cch2.js";
|
17
|
+
import { FNA } from "../lib/tools/fna.js";
|
17
18
|
|
18
19
|
const TOOLS = {
|
19
20
|
CALFLORA: "calflora",
|
20
21
|
CALSCAPE: "calscape",
|
21
22
|
CCH2: "cch",
|
23
|
+
FNA: "fna",
|
22
24
|
INAT: "inat",
|
23
25
|
JEPSON_EFLORA: "jepson-eflora",
|
24
26
|
JEPSON_FAM: "jepson-families",
|
@@ -30,6 +32,7 @@ const ALL_TOOLS = [
|
|
30
32
|
TOOLS.CALFLORA,
|
31
33
|
TOOLS.CALSCAPE,
|
32
34
|
TOOLS.CCH2,
|
35
|
+
TOOLS.FNA,
|
33
36
|
TOOLS.INAT,
|
34
37
|
TOOLS.JEPSON_EFLORA,
|
35
38
|
TOOLS.RPI,
|
@@ -84,11 +87,22 @@ async function build(program, options) {
|
|
84
87
|
await CCH2.analyze(
|
85
88
|
TOOLS_DATA_DIR,
|
86
89
|
options.datadir,
|
90
|
+
exceptions,
|
87
91
|
taxa,
|
88
92
|
errorLog,
|
89
93
|
!!options.update,
|
90
94
|
);
|
91
95
|
break;
|
96
|
+
case TOOLS.FNA:
|
97
|
+
await FNA.analyze(
|
98
|
+
TOOLS_DATA_DIR,
|
99
|
+
options.datadir,
|
100
|
+
taxa,
|
101
|
+
errorLog,
|
102
|
+
!!options.update,
|
103
|
+
);
|
104
|
+
break;
|
105
|
+
|
92
106
|
case TOOLS.INAT:
|
93
107
|
await INat.analyze(
|
94
108
|
TOOLS_DATA_DIR,
|
@@ -150,9 +164,11 @@ program.addHelpText(
|
|
150
164
|
"after",
|
151
165
|
`
|
152
166
|
Tools:
|
153
|
-
'all' runs the 'calflora', '${TOOLS.CALSCAPE}', 'inat', 'jepson-eflora', 'rpi', and 'text' tools.
|
167
|
+
'all' runs the 'calflora', '${TOOLS.CALSCAPE}', '${TOOLS.CCH2}, '${TOOLS.FNA}, 'inat', 'jepson-eflora', 'rpi', and 'text' tools.
|
154
168
|
'${TOOLS.CALFLORA}' retrieves data from Calflora and compares with local data.
|
155
169
|
'${TOOLS.CALSCAPE}' retrieves data from Calscape and compares with local data.
|
170
|
+
'${TOOLS.CCH2}' retrieves data from CCH2 and compares with local data.
|
171
|
+
'${TOOLS.FNA}' retrieves data from Flora of North America and compares with local data.
|
156
172
|
'${TOOLS.INAT}' retrieves data from iNaturalist and compares with local data.
|
157
173
|
'${TOOLS.JEPSON_EFLORA}' retrieves data from Jepson eFlora indexes and compares with local data.
|
158
174
|
'${TOOLS.JEPSON_FAM}' retrieves section, family and genus data from Jepson eFlora and creates data files for use by ca-plant-list.
|
package/scripts/inatobsphotos.js
CHANGED
@@ -6,7 +6,7 @@ import { stringify } from "csv-stringify";
|
|
6
6
|
import path from "path";
|
7
7
|
|
8
8
|
import { Program } from "../lib/program.js";
|
9
|
-
import { Taxa } from "../lib/taxa.js";
|
9
|
+
import { Taxa } from "../lib/taxonomy/taxa.js";
|
10
10
|
import { sleep } from "../lib/util.js";
|
11
11
|
|
12
12
|
/**
|
@@ -27,7 +27,7 @@ const ALLOWED_LICENSE_CODES = ["cc0", "cc-by", "cc-by-nc"];
|
|
27
27
|
const DEFAULT_FILENAME = "inatobsphotos.csv";
|
28
28
|
|
29
29
|
/**
|
30
|
-
* @param {import("../lib/
|
30
|
+
* @param {import("../lib/types.js").Taxon} taxon
|
31
31
|
* @param {InatObsPhotosCommandLineOptions} options
|
32
32
|
* @return {Promise<InatApiObservation[]>}
|
33
33
|
*/
|
@@ -7,7 +7,7 @@ import path from "path";
|
|
7
7
|
|
8
8
|
import { ErrorLog } from "../lib/errorlog.js";
|
9
9
|
import { Program } from "../lib/program.js";
|
10
|
-
import { Taxa } from "../lib/taxa.js";
|
10
|
+
import { Taxa } from "../lib/taxonomy/taxa.js";
|
11
11
|
import { chunk, sleep } from "../lib/util.js";
|
12
12
|
|
13
13
|
/**
|
@@ -23,7 +23,7 @@ const ALLOWED_LICENSE_CODES = ["cc0", "cc-by", "cc-by-nc"];
|
|
23
23
|
const DEFAULT_FILENAME = "inattaxonphotos.csv";
|
24
24
|
|
25
25
|
/**
|
26
|
-
* @param {import("../lib/
|
26
|
+
* @param {import("../lib/types.js").Taxon[]} taxa
|
27
27
|
* @return {Promise<import("../lib/utils/inat-tools.js").InatApiTaxon[]>}
|
28
28
|
*/
|
29
29
|
async function fetchInatTaxa(taxa) {
|
package/lib/families.js
DELETED
@@ -1,243 +0,0 @@
|
|
1
|
-
import { GenericPage } from "./genericpage.js";
|
2
|
-
import { HTML } from "./html.js";
|
3
|
-
import { Jepson } from "./jepson.js";
|
4
|
-
import { Files } from "./files.js";
|
5
|
-
import { Config } from "./config.js";
|
6
|
-
import { HTMLTaxon } from "./htmltaxon.js";
|
7
|
-
|
8
|
-
export class Family {
|
9
|
-
#name;
|
10
|
-
#data;
|
11
|
-
|
12
|
-
/**
|
13
|
-
* @param {string} name
|
14
|
-
* @param {*} data
|
15
|
-
*/
|
16
|
-
constructor(name, data) {
|
17
|
-
this.#name = name;
|
18
|
-
this.#data = data;
|
19
|
-
}
|
20
|
-
|
21
|
-
/**
|
22
|
-
* @param {import("./taxon.js").Taxon} taxon
|
23
|
-
*/
|
24
|
-
addTaxon(taxon) {
|
25
|
-
if (!this.#data.taxa) {
|
26
|
-
this.#data.taxa = [];
|
27
|
-
}
|
28
|
-
this.#data.taxa.push(taxon);
|
29
|
-
Sections.addTaxon(this.getSectionName(), taxon);
|
30
|
-
}
|
31
|
-
|
32
|
-
getBaseFileName() {
|
33
|
-
return this.getName();
|
34
|
-
}
|
35
|
-
|
36
|
-
getFileName(ext = "html") {
|
37
|
-
return this.getBaseFileName() + "." + ext;
|
38
|
-
}
|
39
|
-
|
40
|
-
getJepsonID() {
|
41
|
-
return this.#data.id;
|
42
|
-
}
|
43
|
-
|
44
|
-
getName() {
|
45
|
-
return this.#name;
|
46
|
-
}
|
47
|
-
|
48
|
-
getSectionName() {
|
49
|
-
return this.#data.section;
|
50
|
-
}
|
51
|
-
|
52
|
-
getTaxa() {
|
53
|
-
return this.#data.taxa;
|
54
|
-
}
|
55
|
-
}
|
56
|
-
|
57
|
-
class Families {
|
58
|
-
#families;
|
59
|
-
|
60
|
-
constructor() {
|
61
|
-
const dataDir = Config.getPackageDir() + "/data";
|
62
|
-
|
63
|
-
this.#families = JSON.parse(Files.read(dataDir + "/families.json"));
|
64
|
-
for (const [k, v] of Object.entries(this.#families)) {
|
65
|
-
this.#families[k] = new Family(k, v);
|
66
|
-
}
|
67
|
-
}
|
68
|
-
|
69
|
-
getFamilies() {
|
70
|
-
return Object.values(this.#families).sort((a, b) =>
|
71
|
-
a.getName().localeCompare(b.getName()),
|
72
|
-
);
|
73
|
-
}
|
74
|
-
|
75
|
-
/**
|
76
|
-
* @param {string} familyName
|
77
|
-
*/
|
78
|
-
getFamily(familyName) {
|
79
|
-
return this.#families[familyName];
|
80
|
-
}
|
81
|
-
|
82
|
-
/**
|
83
|
-
* @param {string} outputDir
|
84
|
-
* @param {import("./htmltaxon.js").TaxaColDef[]} [taxaColumns]
|
85
|
-
*/
|
86
|
-
renderPages(outputDir, taxaColumns) {
|
87
|
-
new PageFamilyList(outputDir, this.#families).render(taxaColumns);
|
88
|
-
|
89
|
-
const names = Object.keys(this.#families);
|
90
|
-
for (const name of names.sort()) {
|
91
|
-
const family = this.#families[name];
|
92
|
-
if (family.getTaxa()) {
|
93
|
-
new PageFamily(outputDir, family).render(taxaColumns);
|
94
|
-
}
|
95
|
-
}
|
96
|
-
}
|
97
|
-
}
|
98
|
-
|
99
|
-
class PageFamilyList extends GenericPage {
|
100
|
-
#families;
|
101
|
-
|
102
|
-
/**
|
103
|
-
* @param {string} outputDir
|
104
|
-
* @param {Object<string,Family>} families
|
105
|
-
*/
|
106
|
-
constructor(outputDir, families) {
|
107
|
-
super(outputDir, "Families", "list_families");
|
108
|
-
this.#families = families;
|
109
|
-
}
|
110
|
-
|
111
|
-
/**
|
112
|
-
* @param {import("./htmltaxon.js").TaxaColDef[]} [taxaColumns]
|
113
|
-
*/
|
114
|
-
render(taxaColumns) {
|
115
|
-
let html = this.getDefaultIntro();
|
116
|
-
|
117
|
-
const sections = Sections.getSections();
|
118
|
-
const sectionLinks = [];
|
119
|
-
for (const name of Object.keys(sections).sort()) {
|
120
|
-
const taxa = sections[name];
|
121
|
-
|
122
|
-
// Render the section page.
|
123
|
-
new PageSection(this.getOutputDir(), name, taxa).render(
|
124
|
-
taxaColumns,
|
125
|
-
);
|
126
|
-
|
127
|
-
// Render the link.
|
128
|
-
const href = "./" + name + ".html";
|
129
|
-
sectionLinks.push(
|
130
|
-
HTML.getLink(href, name) + " (" + taxa.length + ")",
|
131
|
-
);
|
132
|
-
}
|
133
|
-
html += HTML.wrap("ul", HTML.arrayToLI(sectionLinks), {
|
134
|
-
class: "listmenu",
|
135
|
-
});
|
136
|
-
|
137
|
-
html += "<table>";
|
138
|
-
html += "<thead>";
|
139
|
-
html += HTML.textElement("th", "Family");
|
140
|
-
html += HTML.textElement("th", "Number of Species", { class: "right" });
|
141
|
-
html += "</thead>";
|
142
|
-
|
143
|
-
html += "<tbody>";
|
144
|
-
const names = Object.keys(this.#families).sort();
|
145
|
-
for (const name of names) {
|
146
|
-
const family = this.#families[name];
|
147
|
-
const taxa = family.getTaxa();
|
148
|
-
if (!taxa) {
|
149
|
-
continue;
|
150
|
-
}
|
151
|
-
let cols = HTML.wrap(
|
152
|
-
"td",
|
153
|
-
HTML.getLink("./" + family.getFileName(), family.getName()),
|
154
|
-
);
|
155
|
-
cols += HTML.wrap("td", taxa.length, { class: "right" });
|
156
|
-
html += HTML.wrap("tr", cols);
|
157
|
-
}
|
158
|
-
html += "</tbody>";
|
159
|
-
|
160
|
-
html += "</table>";
|
161
|
-
|
162
|
-
this.writeFile(html);
|
163
|
-
}
|
164
|
-
}
|
165
|
-
|
166
|
-
class PageFamily extends GenericPage {
|
167
|
-
#family;
|
168
|
-
|
169
|
-
/**
|
170
|
-
* @param {string} outputDir
|
171
|
-
* @param {Family} family
|
172
|
-
*/
|
173
|
-
constructor(outputDir, family) {
|
174
|
-
super(outputDir, family.getName(), family.getBaseFileName());
|
175
|
-
this.#family = family;
|
176
|
-
}
|
177
|
-
|
178
|
-
/**
|
179
|
-
* @param {import("./htmltaxon.js").TaxaColDef[]} [columns]
|
180
|
-
*/
|
181
|
-
render(columns) {
|
182
|
-
let html = this.getDefaultIntro();
|
183
|
-
|
184
|
-
html += HTML.wrap(
|
185
|
-
"div",
|
186
|
-
Jepson.getEFloraLink(this.#family.getJepsonID()),
|
187
|
-
{ class: "section" },
|
188
|
-
);
|
189
|
-
|
190
|
-
html += HTMLTaxon.getTaxaTable(this.#family.getTaxa(), columns);
|
191
|
-
|
192
|
-
this.writeFile(html);
|
193
|
-
}
|
194
|
-
}
|
195
|
-
|
196
|
-
class PageSection extends GenericPage {
|
197
|
-
#taxa;
|
198
|
-
|
199
|
-
/**
|
200
|
-
* @param {string} outputDir
|
201
|
-
* @param {string} name
|
202
|
-
* @param {import("./taxon.js").Taxon[]} taxa
|
203
|
-
*/
|
204
|
-
constructor(outputDir, name, taxa) {
|
205
|
-
super(outputDir, name, name);
|
206
|
-
this.#taxa = taxa;
|
207
|
-
}
|
208
|
-
|
209
|
-
/**
|
210
|
-
* @param {import("./htmltaxon.js").TaxaColDef[]} [columns]
|
211
|
-
*/
|
212
|
-
render(columns) {
|
213
|
-
let html = this.getDefaultIntro();
|
214
|
-
|
215
|
-
html += HTMLTaxon.getTaxaTable(this.#taxa, columns);
|
216
|
-
|
217
|
-
this.writeFile(html);
|
218
|
-
}
|
219
|
-
}
|
220
|
-
|
221
|
-
class Sections {
|
222
|
-
/** @type {Object<string,import("./taxon.js").Taxon[]>} */
|
223
|
-
static #sections = {};
|
224
|
-
|
225
|
-
/**
|
226
|
-
* @param {string} name
|
227
|
-
* @param {import("./taxon.js").Taxon} taxon
|
228
|
-
*/
|
229
|
-
static addTaxon(name, taxon) {
|
230
|
-
let section = this.#sections[name];
|
231
|
-
if (!section) {
|
232
|
-
section = [];
|
233
|
-
this.#sections[name] = section;
|
234
|
-
}
|
235
|
-
section.push(taxon);
|
236
|
-
}
|
237
|
-
|
238
|
-
static getSections() {
|
239
|
-
return this.#sections;
|
240
|
-
}
|
241
|
-
}
|
242
|
-
|
243
|
-
export { Families };
|
package/lib/jepson.js
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
import { HTML } from "./html.js";
|
2
|
-
|
3
|
-
class Jepson {
|
4
|
-
/**
|
5
|
-
* @param {string} id
|
6
|
-
*/
|
7
|
-
static getEFloraLink(id) {
|
8
|
-
return HTML.getLink(
|
9
|
-
"https://ucjeps.berkeley.edu/eflora/eflora_display.php?tid=" + id,
|
10
|
-
"Jepson eFlora",
|
11
|
-
{},
|
12
|
-
true
|
13
|
-
);
|
14
|
-
}
|
15
|
-
}
|
16
|
-
|
17
|
-
export { Jepson };
|