@ca-plant-list/ca-plant-list 0.3.6 → 0.4.0
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/.vscode/settings.json +7 -1
- package/data/synonyms.csv +109 -3
- package/data/taxa.csv +65 -29
- package/data/text/Antennaria-media.md +1 -0
- package/data/text/Antennaria-rosea-subsp-rosea.md +1 -0
- package/data/text/Antirrhinum-thompsonii.md +1 -0
- package/data/text/Calyptridium-monospermum.md +1 -0
- package/data/text/Calyptridium-umbellatum.md +1 -0
- package/data/text/Camassia-leichtlinii-subsp-suksdorfii.md +1 -0
- package/data/text/Camassia-quamash-subsp-breviflora.md +1 -0
- package/data/text/Clarkia-affinis.md +1 -0
- package/data/text/Clarkia-breweri.md +1 -0
- package/data/text/Clarkia-concinna-subsp-automixa.md +1 -0
- package/data/text/Clarkia-modesta.md +1 -0
- package/data/text/Clarkia-purpurea-subsp-quadrivulnera.md +1 -0
- package/data/text/Clarkia-rubicunda.md +1 -0
- package/data/text/Delphinium-californicum-subsp-californicum.md +1 -1
- package/data/text/Delphinium-californicum-subsp-interius.md +1 -0
- package/data/text/Delphinium-glaucum.md +1 -0
- package/data/text/Delphinium-hesperium-subsp-hesperium.md +1 -1
- package/data/text/Delphinium-hesperium-subsp-pallescens.md +1 -0
- package/data/text/Delphinium-nuttallianum.md +1 -0
- package/data/text/Delphinium-parryi-subsp-parryi.md +1 -0
- package/data/text/Drymocallis-glandulosa-var-glandulosa.md +1 -0
- package/data/text/Drymocallis-lactea-var-austiniae.md +1 -0
- package/data/text/Erigeron-compositus.md +1 -0
- package/data/text/Erigeron-glacialis-var-glacialis.md +1 -0
- package/data/text/Erythranthe-breweri.md +1 -0
- package/data/text/Erythranthe-erubescens.md +1 -0
- package/data/text/Erythranthe-moschata.md +1 -0
- package/data/text/Erythranthe-primuloides.md +1 -0
- package/data/text/Erythranthe-tilingii.md +1 -0
- package/data/text/Lilium-pardalinum-subsp-shastense.md +1 -0
- package/data/text/Logfia-filaginoides.md +1 -0
- package/data/text/Logfia-gallica.md +1 -0
- package/data/text/Malacothamnus-arcuatus-var-elmeri.md +1 -0
- package/data/text/Malacothamnus-fremontii-var-fremontii.md +1 -0
- package/data/text/Navarretia-leptalea-subsp-bicolor.md +1 -0
- package/data/text/Navarretia-leptalea-subsp-leptalea.md +1 -0
- package/data/text/Polemonium-californicum.md +1 -0
- package/data/text/Polemonium-pulcherrimum-var-pulcherrimum.md +1 -0
- package/data/text/Primula-jeffreyi.md +1 -0
- package/data/text/Primula-tetrandra.md +1 -0
- package/data/text/Trifolium-obtusiflorum.md +1 -0
- package/data/text/Trifolium-willdenovii.md +1 -0
- package/lib/basepagerenderer.js +3 -4
- package/lib/config.js +42 -19
- package/lib/csv.js +54 -36
- package/lib/ebook/ebook.js +84 -57
- package/lib/ebook/ebookpage.js +22 -11
- package/lib/ebook/ebooksitegenerator.js +36 -14
- package/lib/ebook/glossarypages.js +20 -17
- package/lib/ebook/images.js +59 -42
- package/lib/ebook/pages/page_list_families.js +0 -2
- package/lib/ebook/pages/page_list_flower_color.js +14 -9
- package/lib/ebook/pages/page_list_flowers.js +59 -41
- package/lib/ebook/pages/page_list_species.js +15 -9
- package/lib/ebook/pages/taxonpage.js +3 -6
- package/lib/ebook/pages/tocpage.js +26 -20
- package/lib/ebook/plantbook.js +6 -13
- package/lib/ebook/{image.js → taxonimage.js} +2 -2
- package/lib/ebook/xhtml.js +3 -5
- package/lib/exceptions.js +42 -26
- package/lib/externalsites.js +11 -4
- package/lib/families.js +10 -10
- package/lib/flowercolor.js +42 -0
- package/lib/genera.js +13 -23
- package/lib/genericpage.js +38 -18
- package/lib/html.js +11 -23
- package/lib/htmltaxon.js +114 -14
- package/lib/index.d.ts +54 -0
- package/lib/index.js +2 -30
- package/lib/jekyll.js +49 -21
- package/lib/jepson.js +7 -8
- package/lib/markdown.js +13 -9
- package/lib/pagerenderer.js +162 -82
- package/lib/plants/glossary.js +14 -14
- package/lib/program.js +47 -0
- package/lib/rareplants.js +44 -30
- package/lib/sitegenerator.js +41 -24
- package/lib/taxa.js +25 -142
- package/lib/taxon.js +3 -5
- package/lib/web/glossarypages.js +37 -18
- package/lib/web/pagetaxon.js +1 -5
- package/package.json +5 -3
- package/schemas/exceptions.schema.json +57 -0
- package/scripts/build-ebook.js +39 -48
- package/scripts/build-site.js +49 -28
- package/types/classes.d.ts +154 -0
- package/lib/commandandtaxaprocessor.js +0 -25
- package/lib/commandprocessor.js +0 -108
- package/lib/generictaxaloader.js +0 -48
- package/lib/taxaloader.js +0 -48
- package/lib/taxaprocessor.js +0 -34
package/lib/rareplants.js
CHANGED
@@ -1,60 +1,74 @@
|
|
1
|
+
/** @type {Object<string,string>} */
|
1
2
|
const RANK_DESCRIPS = {
|
2
3
|
"1A": "Presumed Extirpated or Extinct",
|
3
4
|
"1B": "Rare or Endangered",
|
4
5
|
"2A": "Extirpated in California",
|
5
6
|
"2B": "Rare or Endangered in California",
|
6
|
-
|
7
|
-
|
7
|
+
3: "Needs Review",
|
8
|
+
4: "Uncommon in California",
|
8
9
|
};
|
9
10
|
|
11
|
+
/** @type {Object<string,string>} */
|
10
12
|
const THREAT_DESCRIPS = {
|
11
|
-
|
12
|
-
|
13
|
-
|
13
|
+
1: "Seriously threatened in California",
|
14
|
+
2: "Moderately threatened in California",
|
15
|
+
3: "Not very threatened in California",
|
14
16
|
};
|
15
17
|
|
18
|
+
/** @type {Object<string,string>} */
|
16
19
|
const CESA_DESCRIPS = {
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
20
|
+
CC: "Candidate",
|
21
|
+
CE: "Endangered",
|
22
|
+
CR: "Rare",
|
23
|
+
CT: "Threatened",
|
21
24
|
};
|
22
25
|
|
26
|
+
/** @type {Object<string,string>} */
|
23
27
|
const FESA_DESCRIPS = {
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
28
|
+
FE: "Endangered",
|
29
|
+
FT: "Threatened",
|
30
|
+
PE: "Proposed Endangered",
|
31
|
+
PT: "Proposed Threatened",
|
32
|
+
FC: "Candidate",
|
33
|
+
FD: "Delisted",
|
30
34
|
};
|
31
35
|
|
32
36
|
class RarePlants {
|
33
|
-
|
34
|
-
|
35
|
-
|
37
|
+
/**
|
38
|
+
* @param {string|undefined} cesa
|
39
|
+
*/
|
40
|
+
static getCESADescription(cesa) {
|
41
|
+
if (!cesa) {
|
36
42
|
return "";
|
37
43
|
}
|
38
|
-
return CESA_DESCRIPS[
|
44
|
+
return CESA_DESCRIPS[cesa];
|
39
45
|
}
|
40
46
|
|
41
|
-
|
42
|
-
|
47
|
+
/**
|
48
|
+
* @param {string|undefined} fesa
|
49
|
+
*/
|
50
|
+
static getFESADescription(fesa) {
|
51
|
+
if (!fesa) {
|
43
52
|
return "";
|
44
53
|
}
|
45
|
-
return FESA_DESCRIPS[
|
54
|
+
return FESA_DESCRIPS[fesa];
|
46
55
|
}
|
47
56
|
|
48
|
-
|
49
|
-
|
50
|
-
|
57
|
+
/**
|
58
|
+
* @param {string} rank
|
59
|
+
*/
|
60
|
+
static getRPIRankDescription(rank) {
|
61
|
+
const pieces = rank.split(".");
|
62
|
+
return RANK_DESCRIPS[pieces[0]];
|
51
63
|
}
|
52
64
|
|
53
|
-
|
54
|
-
|
55
|
-
|
65
|
+
/**
|
66
|
+
* @param {string} rank
|
67
|
+
*/
|
68
|
+
static getRPIRankAndThreatDescriptions(rank) {
|
69
|
+
const pieces = rank.split(".");
|
70
|
+
return [RANK_DESCRIPS[pieces[0]], THREAT_DESCRIPS[pieces[1]]];
|
56
71
|
}
|
57
|
-
|
58
72
|
}
|
59
73
|
|
60
|
-
export { RarePlants };
|
74
|
+
export { RarePlants };
|
package/lib/sitegenerator.js
CHANGED
@@ -6,32 +6,46 @@ import { Files } from "./files.js";
|
|
6
6
|
class SiteGenerator {
|
7
7
|
#baseDir;
|
8
8
|
|
9
|
-
|
9
|
+
/**
|
10
|
+
* @param {string} baseDir
|
11
|
+
*/
|
12
|
+
constructor(baseDir) {
|
10
13
|
this.#baseDir = baseDir;
|
11
14
|
}
|
12
15
|
|
13
|
-
|
14
|
-
|
16
|
+
/**
|
17
|
+
* @param {FlowerColor[]} flowerColors
|
18
|
+
*/
|
19
|
+
copyIllustrations(flowerColors) {
|
20
|
+
/**
|
21
|
+
* @param {string} outputDir
|
22
|
+
* @param {FlowerColor[]} flowerColors
|
23
|
+
*/
|
24
|
+
function createFlowerColorIcons(outputDir, flowerColors) {
|
15
25
|
// Read generic input.
|
16
|
-
const inputFileName = Files.join(
|
17
|
-
const srcSVG = Files.read(
|
18
|
-
for (
|
26
|
+
const inputFileName = Files.join(outputDir, "flower.svg");
|
27
|
+
const srcSVG = Files.read(inputFileName);
|
28
|
+
for (const color of flowerColors) {
|
19
29
|
Files.write(
|
20
|
-
Files.join(
|
21
|
-
srcSVG.replace(
|
30
|
+
Files.join(outputDir, "f-" + color.getColorName() + ".svg"),
|
31
|
+
srcSVG.replace("#ff0", color.getColorCode())
|
22
32
|
);
|
23
33
|
}
|
24
34
|
// Delete input file.
|
25
|
-
Files.rmDir(
|
35
|
+
Files.rmDir(inputFileName);
|
26
36
|
}
|
27
37
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
38
|
+
/**
|
39
|
+
* @param {string} outputDir
|
40
|
+
*/
|
41
|
+
function optimizeSVG(outputDir) {
|
42
|
+
const srcDir =
|
43
|
+
Config.getPackageDir() + "/data/illustrations/inkscape";
|
44
|
+
const entries = Files.getDirEntries(srcDir);
|
45
|
+
for (const entry of entries) {
|
46
|
+
const srcFile = Files.join(srcDir, entry);
|
47
|
+
const srcSVG = Files.read(srcFile);
|
48
|
+
const result = optimize(srcSVG, {
|
35
49
|
plugins: [
|
36
50
|
{
|
37
51
|
name: "preset-default",
|
@@ -55,24 +69,27 @@ class SiteGenerator {
|
|
55
69
|
"minifyStyles",
|
56
70
|
],
|
57
71
|
multipass: true,
|
58
|
-
}
|
59
|
-
Files.write(
|
72
|
+
});
|
73
|
+
Files.write(Files.join(outputDir, entry), result.data);
|
60
74
|
}
|
61
75
|
}
|
62
76
|
|
63
|
-
const outputDir = Files.join(
|
64
|
-
Files.mkdir(
|
77
|
+
const outputDir = Files.join(this.#baseDir, "i");
|
78
|
+
Files.mkdir(outputDir);
|
65
79
|
|
66
|
-
optimizeSVG(
|
67
|
-
createFlowerColorIcons(
|
80
|
+
optimizeSVG(outputDir);
|
81
|
+
createFlowerColorIcons(outputDir, flowerColors);
|
68
82
|
}
|
69
83
|
|
70
84
|
getBaseDir() {
|
71
85
|
return this.#baseDir;
|
72
86
|
}
|
73
87
|
|
74
|
-
|
75
|
-
|
88
|
+
/**
|
89
|
+
* @param {string} path
|
90
|
+
*/
|
91
|
+
mkdir(path) {
|
92
|
+
Files.mkdir(Files.join(this.#baseDir, path));
|
76
93
|
}
|
77
94
|
}
|
78
95
|
|
package/lib/taxa.js
CHANGED
@@ -1,15 +1,14 @@
|
|
1
1
|
import { Config } from "./config.js";
|
2
|
-
import { HTML } from "./html.js";
|
3
2
|
import { CSV } from "./csv.js";
|
4
|
-
import { RarePlants } from "./rareplants.js";
|
5
|
-
import { Families, Taxon } from "./index.js";
|
6
3
|
import { Genera } from "./genera.js";
|
7
|
-
import {
|
4
|
+
import { Taxon } from "./taxon.js";
|
5
|
+
import { Families } from "./families.js";
|
6
|
+
import { FlowerColor } from "./flowercolor.js";
|
8
7
|
|
9
8
|
const FLOWER_COLORS = [
|
10
9
|
{ name: "white", color: "white" },
|
11
10
|
{ name: "red", color: "red" },
|
12
|
-
{ name: "pink", color: "
|
11
|
+
{ name: "pink", color: "#ff69b4" },
|
13
12
|
{ name: "orange", color: "orange" },
|
14
13
|
{ name: "yellow", color: "yellow" },
|
15
14
|
{ name: "blue", color: "blue" },
|
@@ -18,74 +17,6 @@ const FLOWER_COLORS = [
|
|
18
17
|
{ name: "brown", color: "brown" },
|
19
18
|
];
|
20
19
|
|
21
|
-
/**
|
22
|
-
* @type {Object.<string,import("./index.js").TaxaCol>}
|
23
|
-
*/
|
24
|
-
const TAXA_LIST_COLS = {
|
25
|
-
CESA: {
|
26
|
-
title: "California",
|
27
|
-
data: (t) => RarePlants.getCESADescription(t.getCESA()),
|
28
|
-
},
|
29
|
-
COMMON_NAME: {
|
30
|
-
title: "Common Name",
|
31
|
-
data: (t) => t.getCommonNames().join(", "),
|
32
|
-
},
|
33
|
-
CNPS_RANK: {
|
34
|
-
title: "CNPS Rank",
|
35
|
-
data: (t) =>
|
36
|
-
HTML.getToolTip(
|
37
|
-
HTML.textElement("span", t.getRPIRankAndThreat()),
|
38
|
-
t.getRPIRankAndThreatTooltip()
|
39
|
-
),
|
40
|
-
},
|
41
|
-
FESA: {
|
42
|
-
title: "Federal",
|
43
|
-
data: (t) => RarePlants.getFESADescription(t.getFESA()),
|
44
|
-
},
|
45
|
-
SPECIES: {
|
46
|
-
title: "Species",
|
47
|
-
data: (t) => t.getHTMLLink(true, true),
|
48
|
-
},
|
49
|
-
SPECIES_BARE: {
|
50
|
-
title: "Species",
|
51
|
-
data: (t) => t.getHTMLLink(true, false),
|
52
|
-
},
|
53
|
-
};
|
54
|
-
|
55
|
-
const DEFAULT_COLUMNS = [TAXA_LIST_COLS.SPECIES, TAXA_LIST_COLS.COMMON_NAME];
|
56
|
-
|
57
|
-
class FlowerColor {
|
58
|
-
#color;
|
59
|
-
/** @type {Taxon[]} */
|
60
|
-
#taxa = [];
|
61
|
-
|
62
|
-
/**
|
63
|
-
* @param {string} color
|
64
|
-
*/
|
65
|
-
constructor(color) {
|
66
|
-
this.#color = color;
|
67
|
-
}
|
68
|
-
|
69
|
-
/**
|
70
|
-
* @param {Taxon} taxon
|
71
|
-
*/
|
72
|
-
addTaxon(taxon) {
|
73
|
-
this.#taxa.push(taxon);
|
74
|
-
}
|
75
|
-
|
76
|
-
getColorName(uc = false) {
|
77
|
-
return uc ? TextUtils.ucFirst(this.#color) : this.#color;
|
78
|
-
}
|
79
|
-
|
80
|
-
getFileName() {
|
81
|
-
return "list_fc_" + this.#color + ".html";
|
82
|
-
}
|
83
|
-
|
84
|
-
getTaxa() {
|
85
|
-
return this.#taxa;
|
86
|
-
}
|
87
|
-
}
|
88
|
-
|
89
20
|
class Taxa {
|
90
21
|
#families;
|
91
22
|
#errorLog;
|
@@ -98,21 +29,18 @@ class Taxa {
|
|
98
29
|
#isSubset;
|
99
30
|
|
100
31
|
/**
|
101
|
-
*
|
102
|
-
* @param {*} inclusionList
|
32
|
+
* @param {Object<string,TaxonData>|true} inclusionList
|
103
33
|
* @param {ErrorLog} errorLog
|
104
|
-
* @param {
|
105
|
-
* @param {
|
106
|
-
* @param {
|
107
|
-
* @param {
|
108
|
-
* @param {*} extraSynonyms
|
34
|
+
* @param {boolean} showFlowerErrors
|
35
|
+
* @param {function(TaxonData,Genera):Taxon} taxonFactory
|
36
|
+
* @param {TaxonData[]} [extraTaxa=[]]
|
37
|
+
* @param {SynonymData[]} [extraSynonyms=[]]
|
109
38
|
*/
|
110
39
|
constructor(
|
111
40
|
inclusionList,
|
112
41
|
errorLog,
|
113
42
|
showFlowerErrors,
|
114
|
-
|
115
|
-
taxonClass = Taxon,
|
43
|
+
taxonFactory = (td, g) => new Taxon(td, g),
|
116
44
|
extraTaxa = [],
|
117
45
|
extraSynonyms = []
|
118
46
|
) {
|
@@ -129,18 +57,11 @@ class Taxa {
|
|
129
57
|
this.#families = new Families();
|
130
58
|
|
131
59
|
const taxaCSV = CSV.parseFile(dataDir, "taxa.csv");
|
132
|
-
this.#loadTaxa(
|
133
|
-
taxaCSV,
|
134
|
-
inclusionList,
|
135
|
-
taxaMeta,
|
136
|
-
taxonClass,
|
137
|
-
showFlowerErrors
|
138
|
-
);
|
60
|
+
this.#loadTaxa(taxaCSV, inclusionList, taxonFactory, showFlowerErrors);
|
139
61
|
this.#loadTaxa(
|
140
62
|
extraTaxa,
|
141
63
|
inclusionList,
|
142
|
-
|
143
|
-
taxonClass,
|
64
|
+
taxonFactory,
|
144
65
|
showFlowerErrors
|
145
66
|
);
|
146
67
|
|
@@ -160,54 +81,14 @@ class Taxa {
|
|
160
81
|
this.#loadSyns(extraSynonyms, inclusionList);
|
161
82
|
}
|
162
83
|
|
163
|
-
/**
|
164
|
-
* @param {Taxon[]} taxa
|
165
|
-
* @param {import("./index.js").TaxaCol[]} columns
|
166
|
-
*/
|
167
|
-
static getHTMLTable(taxa, columns = DEFAULT_COLUMNS) {
|
168
|
-
let html = "<table><thead>";
|
169
|
-
for (const col of columns) {
|
170
|
-
const className = col.class;
|
171
|
-
const atts = className ? { class: className } : {};
|
172
|
-
html += HTML.textElement("th", col.title, atts);
|
173
|
-
}
|
174
|
-
html += "</thead>";
|
175
|
-
html += "<tbody>";
|
176
|
-
|
177
|
-
for (const taxon of taxa) {
|
178
|
-
html += "<tr>";
|
179
|
-
for (const col of columns) {
|
180
|
-
const data = col.data(taxon);
|
181
|
-
const className = col.class;
|
182
|
-
const atts = className ? { class: className } : {};
|
183
|
-
html += HTML.wrap("td", data, atts);
|
184
|
-
}
|
185
|
-
html += "</tr>";
|
186
|
-
}
|
187
|
-
|
188
|
-
html += "</tbody>";
|
189
|
-
html += "</table>";
|
190
|
-
|
191
|
-
return html;
|
192
|
-
}
|
193
|
-
|
194
84
|
getFamilies() {
|
195
85
|
return this.#families;
|
196
86
|
}
|
197
87
|
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
return this.#flower_colors[name];
|
203
|
-
}
|
204
|
-
|
205
|
-
static getFlowerColorNames() {
|
206
|
-
return FLOWER_COLORS.map((o) => o.name);
|
207
|
-
}
|
208
|
-
|
209
|
-
static getFlowerColors() {
|
210
|
-
return FLOWER_COLORS;
|
88
|
+
getFlowerColors() {
|
89
|
+
return Object.values(this.#flower_colors).filter(
|
90
|
+
(fc) => fc.getTaxa().length > 0
|
91
|
+
);
|
211
92
|
}
|
212
93
|
|
213
94
|
/**
|
@@ -237,8 +118,8 @@ class Taxa {
|
|
237
118
|
}
|
238
119
|
|
239
120
|
/**
|
240
|
-
* @param {
|
241
|
-
* @param {
|
121
|
+
* @param {SynonymData[]} synCSV
|
122
|
+
* @param {Object<string,TaxonData>|boolean} inclusionList
|
242
123
|
*/
|
243
124
|
#loadSyns(synCSV, inclusionList) {
|
244
125
|
for (const syn of synCSV) {
|
@@ -259,15 +140,17 @@ class Taxa {
|
|
259
140
|
}
|
260
141
|
|
261
142
|
/**
|
262
|
-
* @param {
|
263
|
-
* @param {
|
143
|
+
* @param {TaxonData[]} taxaCSV
|
144
|
+
* @param {Object<string,TaxonData>|true} inclusionList
|
145
|
+
* @param {function(TaxonData,Genera):Taxon} taxonFactory
|
264
146
|
* @param {boolean} showFlowerErrors
|
265
147
|
*/
|
266
|
-
#loadTaxa(taxaCSV, inclusionList,
|
148
|
+
#loadTaxa(taxaCSV, inclusionList, taxonFactory, showFlowerErrors) {
|
267
149
|
const genera = new Genera(this.#families);
|
268
150
|
for (const row of taxaCSV) {
|
269
151
|
const name = row["taxon_name"];
|
270
152
|
|
153
|
+
/** @type {TaxonData|{status?:string}} */
|
271
154
|
let taxon_overrides = {};
|
272
155
|
if (inclusionList !== true) {
|
273
156
|
taxon_overrides = inclusionList[name];
|
@@ -284,7 +167,7 @@ class Taxa {
|
|
284
167
|
if (status !== undefined) {
|
285
168
|
row["status"] = status;
|
286
169
|
}
|
287
|
-
const taxon =
|
170
|
+
const taxon = taxonFactory(row, genera);
|
288
171
|
this.#taxa[name] = taxon;
|
289
172
|
const colors = taxon.getFlowerColors();
|
290
173
|
if (colors) {
|
@@ -329,4 +212,4 @@ class Taxa {
|
|
329
212
|
}
|
330
213
|
}
|
331
214
|
|
332
|
-
export { Taxa
|
215
|
+
export { Taxa };
|
package/lib/taxon.js
CHANGED
@@ -1,7 +1,5 @@
|
|
1
|
-
import { HTML } from "./
|
1
|
+
import { HTML } from "./html.js";
|
2
2
|
import { RarePlants } from "./rareplants.js";
|
3
|
-
// eslint-disable-next-line no-unused-vars
|
4
|
-
import { Genera } from "./genera.js";
|
5
3
|
|
6
4
|
const TAXA_COLNAMES = {
|
7
5
|
BLOOM_START: "bloom_start",
|
@@ -38,7 +36,7 @@ class Taxon {
|
|
38
36
|
#synonyms = [];
|
39
37
|
|
40
38
|
/**
|
41
|
-
* @param {
|
39
|
+
* @param {TaxonData} data
|
42
40
|
* @param {Genera} genera
|
43
41
|
*/
|
44
42
|
constructor(data, genera) {
|
@@ -151,7 +149,7 @@ class Taxon {
|
|
151
149
|
}
|
152
150
|
|
153
151
|
getFamily() {
|
154
|
-
return this
|
152
|
+
return this.getGenus().getFamily();
|
155
153
|
}
|
156
154
|
|
157
155
|
getFESA() {
|
package/lib/web/glossarypages.js
CHANGED
@@ -1,46 +1,66 @@
|
|
1
|
-
import { Files, HTML } from "@ca-plant-list/ca-plant-list";
|
2
1
|
import { Glossary } from "../plants/glossary.js";
|
3
2
|
import { Markdown } from "../markdown.js";
|
3
|
+
import { HTML } from "../html.js";
|
4
|
+
import { Files } from "../files.js";
|
4
5
|
|
5
6
|
const ENTRY_DIR = "g";
|
6
7
|
|
7
8
|
class GlossaryPages {
|
8
|
-
|
9
9
|
#siteGenerator;
|
10
10
|
#glossary;
|
11
11
|
|
12
|
-
|
12
|
+
/**
|
13
|
+
* @param {SiteGenerator} siteGenerator
|
14
|
+
*/
|
15
|
+
constructor(siteGenerator) {
|
13
16
|
this.#siteGenerator = siteGenerator;
|
14
17
|
this.#glossary = new Glossary();
|
15
18
|
}
|
16
19
|
|
17
|
-
|
20
|
+
/**
|
21
|
+
* @param {GlossaryEntry} entry
|
22
|
+
*/
|
23
|
+
#generateEntryPage(entry) {
|
18
24
|
const title = entry.getTermName();
|
19
|
-
let html = HTML.textElement(
|
20
|
-
html += HTML.wrap(
|
21
|
-
|
25
|
+
let html = HTML.textElement("h1", title);
|
26
|
+
html += HTML.wrap("div", Markdown.strToHTML(entry.getMarkdown()), {
|
27
|
+
class: "glossary",
|
28
|
+
});
|
29
|
+
this.#siteGenerator.writeTemplate(
|
30
|
+
html,
|
31
|
+
{ title: title },
|
32
|
+
Files.join(ENTRY_DIR, title + ".html")
|
33
|
+
);
|
22
34
|
}
|
23
35
|
|
24
36
|
#generateEntryPages() {
|
25
|
-
|
26
37
|
// Make sure output directory exists.
|
27
|
-
this.#siteGenerator.mkdir(
|
38
|
+
this.#siteGenerator.mkdir(ENTRY_DIR);
|
28
39
|
|
29
40
|
const entries = this.#glossary.getEntries();
|
30
|
-
for (
|
31
|
-
this.#generateEntryPage(
|
41
|
+
for (const entry of entries) {
|
42
|
+
this.#generateEntryPage(entry);
|
32
43
|
}
|
33
44
|
}
|
34
45
|
|
35
46
|
#generateIndexPage() {
|
36
47
|
const links = [];
|
37
48
|
const entries = this.#glossary.getEntries();
|
38
|
-
for (
|
39
|
-
links.push(
|
49
|
+
for (const entry of entries) {
|
50
|
+
links.push(
|
51
|
+
HTML.getLink(
|
52
|
+
Files.join(ENTRY_DIR, entry.getHTMLFileName()),
|
53
|
+
entry.getTermName()
|
54
|
+
)
|
55
|
+
);
|
40
56
|
}
|
41
|
-
let html = HTML.wrap(
|
42
|
-
html += HTML.wrap(
|
43
|
-
this.#siteGenerator.writeTemplate(
|
57
|
+
let html = HTML.wrap("h1", "Glossary");
|
58
|
+
html += HTML.wrap("ol", HTML.arrayToLI(links));
|
59
|
+
this.#siteGenerator.writeTemplate(
|
60
|
+
html,
|
61
|
+
{ title: "Glossary" },
|
62
|
+
"glossary.html"
|
63
|
+
);
|
44
64
|
}
|
45
65
|
|
46
66
|
getGlossary() {
|
@@ -51,7 +71,6 @@ class GlossaryPages {
|
|
51
71
|
this.#generateIndexPage();
|
52
72
|
this.#generateEntryPages();
|
53
73
|
}
|
54
|
-
|
55
74
|
}
|
56
75
|
|
57
|
-
export { GlossaryPages };
|
76
|
+
export { GlossaryPages };
|
package/lib/web/pagetaxon.js
CHANGED
@@ -3,10 +3,6 @@ import { RarePlants } from "../rareplants.js";
|
|
3
3
|
import { GenericPage } from "../genericpage.js";
|
4
4
|
import { ExternalSites } from "../externalsites.js";
|
5
5
|
import { HTML } from "../html.js";
|
6
|
-
// eslint-disable-next-line no-unused-vars
|
7
|
-
import { Config } from "../config.js";
|
8
|
-
// eslint-disable-next-line no-unused-vars
|
9
|
-
import { Taxon } from "../taxon.js";
|
10
6
|
import { HTMLTaxon } from "../htmltaxon.js";
|
11
7
|
|
12
8
|
class PageTaxon extends GenericPage {
|
@@ -178,7 +174,7 @@ class PageTaxon extends GenericPage {
|
|
178
174
|
|
179
175
|
html += "</div>";
|
180
176
|
|
181
|
-
html += HTMLTaxon.getFlowerInfo(this.#taxon);
|
177
|
+
html += HTMLTaxon.getFlowerInfo(this.#taxon, undefined, false);
|
182
178
|
|
183
179
|
html += this.getMarkdown();
|
184
180
|
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@ca-plant-list/ca-plant-list",
|
3
|
-
"version": "0.
|
3
|
+
"version": "0.4.0",
|
4
4
|
"description": "Tools to create Jekyll files for a website listing plants in an area of California.",
|
5
5
|
"license": "MIT",
|
6
6
|
"repository": {
|
@@ -20,8 +20,7 @@
|
|
20
20
|
"dependencies": {
|
21
21
|
"@ca-plant-list/tools": "file:../ca-tools",
|
22
22
|
"archiver": "^5.3.1",
|
23
|
-
"
|
24
|
-
"command-line-usage": "^6.1.3",
|
23
|
+
"commander": "^12.1.0",
|
25
24
|
"csv-parse": "^5.3.1",
|
26
25
|
"image-size": "^1.1.1",
|
27
26
|
"markdown-it": "^13.0.1",
|
@@ -30,8 +29,11 @@
|
|
30
29
|
"unzipper": "^0.10.11"
|
31
30
|
},
|
32
31
|
"devDependencies": {
|
32
|
+
"@types/archiver": "^6.0.2",
|
33
|
+
"@types/markdown-it": "^14.1.2",
|
33
34
|
"@types/node": "^18.11.9",
|
34
35
|
"@types/unzipper": "^0.10.9",
|
36
|
+
"ajv-cli": "^5.0.0",
|
35
37
|
"dts-bundle-generator": "^9.3.1",
|
36
38
|
"eslint": "^8.26.0",
|
37
39
|
"typescript": "^5.3.3"
|
@@ -0,0 +1,57 @@
|
|
1
|
+
{
|
2
|
+
"type": "object",
|
3
|
+
"additionalProperties": {
|
4
|
+
"type": "object",
|
5
|
+
"properties": {
|
6
|
+
"calflora": {
|
7
|
+
"type": "object",
|
8
|
+
"properties": {
|
9
|
+
"badjepsonid": {
|
10
|
+
"const": true
|
11
|
+
},
|
12
|
+
"notintaxondata": {
|
13
|
+
"const": true
|
14
|
+
}
|
15
|
+
},
|
16
|
+
"additionalProperties": false
|
17
|
+
},
|
18
|
+
"comment": {
|
19
|
+
"type": "string"
|
20
|
+
},
|
21
|
+
"inat": {
|
22
|
+
"type": "object",
|
23
|
+
"properties": {
|
24
|
+
"notintaxondata": {
|
25
|
+
"const": true
|
26
|
+
}
|
27
|
+
},
|
28
|
+
"additionalProperties": false
|
29
|
+
},
|
30
|
+
"jepson": {
|
31
|
+
"type": "object",
|
32
|
+
"properties": {
|
33
|
+
"allowsynonym": {
|
34
|
+
"const": true
|
35
|
+
},
|
36
|
+
"notineflora": {
|
37
|
+
"const": true
|
38
|
+
}
|
39
|
+
},
|
40
|
+
"additionalProperties": false
|
41
|
+
},
|
42
|
+
"rpi": {
|
43
|
+
"type": "object",
|
44
|
+
"properties": {
|
45
|
+
"translation": {
|
46
|
+
"type": "string"
|
47
|
+
},
|
48
|
+
"translation-to-rpi": {
|
49
|
+
"type": "string"
|
50
|
+
}
|
51
|
+
},
|
52
|
+
"additionalProperties": false
|
53
|
+
}
|
54
|
+
},
|
55
|
+
"additionalProperties": false
|
56
|
+
}
|
57
|
+
}
|