@ca-plant-list/ca-plant-list 0.2.12 → 0.2.14
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/glossary/peduncle.md +1 -0
- package/data/illustrations/inkscape/flower.svg +115 -0
- package/data/illustrations/optimized/f-blue.svg +11 -5
- package/data/illustrations/optimized/f-orange.svg +11 -5
- package/data/illustrations/optimized/f-pink.svg +11 -5
- package/data/illustrations/optimized/f-red.svg +11 -5
- package/data/illustrations/optimized/f-white.svg +11 -5
- package/data/illustrations/optimized/f-yellow.svg +11 -5
- package/data/synonyms.csv +2 -0
- package/data/taxa.csv +8 -5
- package/data/text/Hedera-canariensis.md +1 -0
- package/data/text/Hedera-helix.md +1 -0
- package/data/text/Hypochaeris-glabra.md +1 -1
- package/data/text/Hypochaeris-radicata.md +1 -1
- package/ebook/css/main.css +2 -2
- package/jekyll/assets/css/main.css +1 -0
- package/lib/commandrunner.js +63 -0
- package/lib/config.js +7 -10
- package/lib/dataloader.js +7 -16
- package/lib/ebook/plantbook.js +6 -7
- package/lib/index.d.ts +20 -12
- package/lib/index.js +2 -1
- package/lib/pagerenderer.js +9 -10
- package/lib/taxa.js +8 -0
- package/lib/taxon.js +2 -3
- package/lib/web/pagetaxon.js +6 -5
- package/package.json +1 -1
- package/scripts/build-ebook.js +69 -5
- package/scripts/build-site.js +32 -6
@@ -0,0 +1 @@
|
|
1
|
+
A stalk supporting an inflorescence (one or more flowers).
|
@@ -0,0 +1,115 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
2
|
+
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
3
|
+
|
4
|
+
<svg
|
5
|
+
width="30"
|
6
|
+
height="30"
|
7
|
+
viewBox="0 0 30 30"
|
8
|
+
version="1.1"
|
9
|
+
id="svg1"
|
10
|
+
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
|
11
|
+
sodipodi:docname="flower.svg"
|
12
|
+
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
13
|
+
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
14
|
+
xmlns:xlink="http://www.w3.org/1999/xlink"
|
15
|
+
xmlns="http://www.w3.org/2000/svg"
|
16
|
+
xmlns:svg="http://www.w3.org/2000/svg">
|
17
|
+
<sodipodi:namedview
|
18
|
+
id="namedview1"
|
19
|
+
pagecolor="#ffffff"
|
20
|
+
bordercolor="#000000"
|
21
|
+
borderopacity="0.25"
|
22
|
+
inkscape:showpageshadow="2"
|
23
|
+
inkscape:pageopacity="0.0"
|
24
|
+
inkscape:pagecheckerboard="0"
|
25
|
+
inkscape:deskcolor="#d1d1d1"
|
26
|
+
inkscape:document-units="px"
|
27
|
+
showgrid="true"
|
28
|
+
inkscape:zoom="4"
|
29
|
+
inkscape:cx="61.5"
|
30
|
+
inkscape:cy="2.625"
|
31
|
+
inkscape:window-width="1920"
|
32
|
+
inkscape:window-height="991"
|
33
|
+
inkscape:window-x="-9"
|
34
|
+
inkscape:window-y="-9"
|
35
|
+
inkscape:window-maximized="1"
|
36
|
+
inkscape:current-layer="layer1">
|
37
|
+
<inkscape:grid
|
38
|
+
id="grid1"
|
39
|
+
units="px"
|
40
|
+
originx="0"
|
41
|
+
originy="0"
|
42
|
+
spacingx="1"
|
43
|
+
spacingy="1"
|
44
|
+
empcolor="#0099e5"
|
45
|
+
empopacity="0.30196078"
|
46
|
+
color="#0099e5"
|
47
|
+
opacity="0.14901961"
|
48
|
+
empspacing="5"
|
49
|
+
dotted="false"
|
50
|
+
gridanglex="30"
|
51
|
+
gridanglez="30"
|
52
|
+
visible="true" />
|
53
|
+
</sodipodi:namedview>
|
54
|
+
<defs
|
55
|
+
id="defs1" />
|
56
|
+
<g
|
57
|
+
inkscape:label="Layer 1"
|
58
|
+
inkscape:groupmode="layer"
|
59
|
+
id="layer1">
|
60
|
+
<ellipse
|
61
|
+
style="fill:#ffff00;stroke-width:0"
|
62
|
+
id="path1"
|
63
|
+
cx="15"
|
64
|
+
cy="15"
|
65
|
+
rx="2.5"
|
66
|
+
ry="15"
|
67
|
+
inkscape:tile-cx="15"
|
68
|
+
inkscape:tile-cy="15"
|
69
|
+
inkscape:tile-w="5"
|
70
|
+
inkscape:tile-h="30"
|
71
|
+
inkscape:tile-x0="12.5"
|
72
|
+
inkscape:tile-y0="0" />
|
73
|
+
<use
|
74
|
+
x="0"
|
75
|
+
y="0"
|
76
|
+
inkscape:tiled-clone-of="#path1"
|
77
|
+
xlink:href="#path1"
|
78
|
+
id="use1" />
|
79
|
+
<use
|
80
|
+
x="0"
|
81
|
+
y="0"
|
82
|
+
inkscape:tiled-clone-of="#path1"
|
83
|
+
xlink:href="#path1"
|
84
|
+
transform="rotate(30,15,15)"
|
85
|
+
id="use2" />
|
86
|
+
<use
|
87
|
+
x="0"
|
88
|
+
y="0"
|
89
|
+
inkscape:tiled-clone-of="#path1"
|
90
|
+
xlink:href="#path1"
|
91
|
+
transform="rotate(60,15,15)"
|
92
|
+
id="use3" />
|
93
|
+
<use
|
94
|
+
x="0"
|
95
|
+
y="0"
|
96
|
+
inkscape:tiled-clone-of="#path1"
|
97
|
+
xlink:href="#path1"
|
98
|
+
transform="rotate(90,15,15)"
|
99
|
+
id="use4" />
|
100
|
+
<use
|
101
|
+
x="0"
|
102
|
+
y="0"
|
103
|
+
inkscape:tiled-clone-of="#path1"
|
104
|
+
xlink:href="#path1"
|
105
|
+
transform="rotate(120,15,15)"
|
106
|
+
id="use5" />
|
107
|
+
<use
|
108
|
+
x="0"
|
109
|
+
y="0"
|
110
|
+
inkscape:tiled-clone-of="#path1"
|
111
|
+
xlink:href="#path1"
|
112
|
+
transform="rotate(150,15,15)"
|
113
|
+
id="use6" />
|
114
|
+
</g>
|
115
|
+
</svg>
|
@@ -1,5 +1,11 @@
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg"
|
2
|
-
|
3
|
-
<
|
4
|
-
|
5
|
-
|
1
|
+
<svg version="1.1" viewBox="0 0 30 30" xmlns="http://www.w3.org/2000/svg"
|
2
|
+
xmlns:xlink="http://www.w3.org/1999/xlink">
|
3
|
+
<ellipse id="a" cx="15" cy="15" rx="2.5" ry="15" fill="blue" stroke-width="0" />
|
4
|
+
<use xlink:href="#a" />
|
5
|
+
<use transform="rotate(30,15,15)" xlink:href="#a" />
|
6
|
+
<use transform="rotate(60,15,15)" xlink:href="#a" />
|
7
|
+
<use transform="rotate(90,15,15)" xlink:href="#a" />
|
8
|
+
<use transform="rotate(120,15,15)" xlink:href="#a" />
|
9
|
+
<use transform="rotate(150,15,15)" xlink:href="#a" />
|
10
|
+
</svg>
|
11
|
+
|
@@ -1,5 +1,11 @@
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg"
|
2
|
-
|
3
|
-
<
|
4
|
-
|
5
|
-
|
1
|
+
<svg version="1.1" viewBox="0 0 30 30" xmlns="http://www.w3.org/2000/svg"
|
2
|
+
xmlns:xlink="http://www.w3.org/1999/xlink">
|
3
|
+
<ellipse id="a" cx="15" cy="15" rx="2.5" ry="15" fill="orange" stroke-width="0" />
|
4
|
+
<use xlink:href="#a" />
|
5
|
+
<use transform="rotate(30,15,15)" xlink:href="#a" />
|
6
|
+
<use transform="rotate(60,15,15)" xlink:href="#a" />
|
7
|
+
<use transform="rotate(90,15,15)" xlink:href="#a" />
|
8
|
+
<use transform="rotate(120,15,15)" xlink:href="#a" />
|
9
|
+
<use transform="rotate(150,15,15)" xlink:href="#a" />
|
10
|
+
</svg>
|
11
|
+
|
@@ -1,5 +1,11 @@
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg"
|
2
|
-
|
3
|
-
<
|
4
|
-
|
5
|
-
|
1
|
+
<svg version="1.1" viewBox="0 0 30 30" xmlns="http://www.w3.org/2000/svg"
|
2
|
+
xmlns:xlink="http://www.w3.org/1999/xlink">
|
3
|
+
<ellipse id="a" cx="15" cy="15" rx="2.5" ry="15" fill="pink" stroke-width="0" />
|
4
|
+
<use xlink:href="#a" />
|
5
|
+
<use transform="rotate(30,15,15)" xlink:href="#a" />
|
6
|
+
<use transform="rotate(60,15,15)" xlink:href="#a" />
|
7
|
+
<use transform="rotate(90,15,15)" xlink:href="#a" />
|
8
|
+
<use transform="rotate(120,15,15)" xlink:href="#a" />
|
9
|
+
<use transform="rotate(150,15,15)" xlink:href="#a" />
|
10
|
+
</svg>
|
11
|
+
|
@@ -1,5 +1,11 @@
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg"
|
2
|
-
|
3
|
-
<
|
4
|
-
|
5
|
-
|
1
|
+
<svg version="1.1" viewBox="0 0 30 30" xmlns="http://www.w3.org/2000/svg"
|
2
|
+
xmlns:xlink="http://www.w3.org/1999/xlink">
|
3
|
+
<ellipse id="a" cx="15" cy="15" rx="2.5" ry="15" fill="red" stroke-width="0" />
|
4
|
+
<use xlink:href="#a" />
|
5
|
+
<use transform="rotate(30,15,15)" xlink:href="#a" />
|
6
|
+
<use transform="rotate(60,15,15)" xlink:href="#a" />
|
7
|
+
<use transform="rotate(90,15,15)" xlink:href="#a" />
|
8
|
+
<use transform="rotate(120,15,15)" xlink:href="#a" />
|
9
|
+
<use transform="rotate(150,15,15)" xlink:href="#a" />
|
10
|
+
</svg>
|
11
|
+
|
@@ -1,5 +1,11 @@
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg"
|
2
|
-
|
3
|
-
<
|
4
|
-
|
5
|
-
|
1
|
+
<svg version="1.1" viewBox="0 0 30 30" xmlns="http://www.w3.org/2000/svg"
|
2
|
+
xmlns:xlink="http://www.w3.org/1999/xlink">
|
3
|
+
<ellipse id="a" cx="15" cy="15" rx="2.5" ry="15" fill="white" stroke-width="0" />
|
4
|
+
<use xlink:href="#a" />
|
5
|
+
<use transform="rotate(30,15,15)" xlink:href="#a" />
|
6
|
+
<use transform="rotate(60,15,15)" xlink:href="#a" />
|
7
|
+
<use transform="rotate(90,15,15)" xlink:href="#a" />
|
8
|
+
<use transform="rotate(120,15,15)" xlink:href="#a" />
|
9
|
+
<use transform="rotate(150,15,15)" xlink:href="#a" />
|
10
|
+
</svg>
|
11
|
+
|
@@ -1,5 +1,11 @@
|
|
1
|
-
<svg xmlns="http://www.w3.org/2000/svg"
|
2
|
-
|
3
|
-
<
|
4
|
-
|
5
|
-
|
1
|
+
<svg version="1.1" viewBox="0 0 30 30" xmlns="http://www.w3.org/2000/svg"
|
2
|
+
xmlns:xlink="http://www.w3.org/1999/xlink">
|
3
|
+
<ellipse id="a" cx="15" cy="15" rx="2.5" ry="15" fill="yellow" stroke-width="0" />
|
4
|
+
<use xlink:href="#a" />
|
5
|
+
<use transform="rotate(30,15,15)" xlink:href="#a" />
|
6
|
+
<use transform="rotate(60,15,15)" xlink:href="#a" />
|
7
|
+
<use transform="rotate(90,15,15)" xlink:href="#a" />
|
8
|
+
<use transform="rotate(120,15,15)" xlink:href="#a" />
|
9
|
+
<use transform="rotate(150,15,15)" xlink:href="#a" />
|
10
|
+
</svg>
|
11
|
+
|
package/data/synonyms.csv
CHANGED
@@ -891,6 +891,8 @@ Hymenolobus procumbens,Hornungia procumbens
|
|
891
891
|
Hypericum formosum var. scouleri,Hypericum scouleri
|
892
892
|
Hypericum scouleri subsp. scouleri,Hypericum scouleri
|
893
893
|
Ibicella lutea,Proboscidea lutea,INAT
|
894
|
+
Iris amabilis,Iris macrosiphon
|
895
|
+
Iris californica,Iris macrosiphon
|
894
896
|
Iris douglasiana var. altissima,Iris douglasiana
|
895
897
|
Iris douglasiana var. major,Iris douglasiana
|
896
898
|
Iris douglasiana var. oregonensis,Iris douglasiana
|
package/data/taxa.csv
CHANGED
@@ -267,6 +267,7 @@ Calochortus albus,white globe lily,N,16710,1264,51315,white
|
|
267
267
|
Calochortus argillosus,clay mariposa lily,N,76542,1268,64330,"white,pink"
|
268
268
|
Calochortus clavatus var. pallidus,,N,55455,1275,58360
|
269
269
|
Calochortus invenustus,,N,16733,1284,64432
|
270
|
+
Calochortus leichtlinii
|
270
271
|
Calochortus luteus,yellow mariposa lily,N,16737,1290,51077,yellow
|
271
272
|
Calochortus pulchellus,Mt. Diablo fairy lantern,N,16755,1303,47326,,,,50,1B.2,,,S2,G2
|
272
273
|
Calochortus splendens,,N,16759,1306,58361
|
@@ -342,8 +343,8 @@ Castilleja wightii,Wight's paintbrush,N,18332,1738,67809
|
|
342
343
|
Caulanthus flavescens,,N,18399,11482,76161
|
343
344
|
Caulanthus lasiophyllus,California mustard,N,18404,11483,76165
|
344
345
|
Caulanthus lemmonii,,N,18406,9777,71133,,,,1864,1B.2,,,S3,G3
|
345
|
-
Ceanothus cuneatus,,N,18434,1770,49673,white
|
346
346
|
Ceanothus cuneatus var. cuneatus,buck brush,N,75440,1771,49672
|
347
|
+
Ceanothus cuneatus,,N,18434,1770,49673,white
|
347
348
|
Ceanothus foliosus,wavy leaved ceanothus,N,18446,1779,64077
|
348
349
|
Ceanothus leucodermis,chaparral whitethorn,N,18466,1803,76182
|
349
350
|
Ceanothus oliganthus var. sorediatus,jim brush,N,56109,1813,53361
|
@@ -825,8 +826,8 @@ Grindelia stricta var. angustifolia,marsh gumplant,N,77358,3968,61991,yellow
|
|
825
826
|
Gruvelia pusilla,little combseed,N,105901,14570,57694
|
826
827
|
Gutierrezia californica,California matchweed,N,3140,3977,57978
|
827
828
|
Hainardia cylindrica,,X,27553,3996,60285
|
828
|
-
Hedera canariensis,
|
829
|
-
Hedera helix,English ivy,X,27768,4023,55882
|
829
|
+
Hedera canariensis,Canary Islands ivy,X,81236,8467,64113,white,8,11
|
830
|
+
Hedera helix,English ivy,X,27768,4023,55882,white,8,11
|
830
831
|
Hedypnois rhagadioloides,,X,99769,13134,492864
|
831
832
|
Helenium bigelovii,,N,3201,4029,61807
|
832
833
|
Helenium puberulum,sneezeweed,N,3223,4031,53092
|
@@ -898,14 +899,15 @@ Hydrophyllum occidentale,western waterleaf,N,28634,4287,77471
|
|
898
899
|
Hypericum androsaemum,,X,77418,8601,77480
|
899
900
|
Hypericum perforatum subsp. perforatum,Klamath weed,X,91766,11762,79949
|
900
901
|
Hypericum scouleri,St. John's wort,N,28801,11763,77484
|
901
|
-
Hypochaeris glabra,smooth cat's ear,X,3623,4313,53103
|
902
|
-
Hypochaeris radicata,rough cat's ear,X,3625,4314,53104
|
902
|
+
Hypochaeris glabra,smooth cat's ear,X,3623,4313,53103,yellow,3,6
|
903
|
+
Hypochaeris radicata,rough cat's ear,X,3625,4314,53104,yellow,4,7
|
903
904
|
Idahoa scapigera,flat-pod,N,28891,4316,77486
|
904
905
|
Ilex aquifolium,English holly,X,28898,4317,53856
|
905
906
|
Impatiens balfourii,touch-me-not,X,28954,4320,77490
|
906
907
|
Iris douglasiana,Douglas' iris,N,29188,4346,50854
|
907
908
|
Iris foetidissima,stinking iris,X,29193,8604,64331
|
908
909
|
Iris longipetala,central coast iris,N,29293,4354,67703,,,,3169,4.2,,,S3,G3
|
910
|
+
Iris macrosiphon,,N,29289
|
909
911
|
Iris pseudacorus,yellow flag,X,29301,4358,47779
|
910
912
|
Isocoma arguta,Carquinez goldenbush,N,3633,4369,77510,,,,1264,1B.1,,,S1,G1
|
911
913
|
Isoetes howellii,Howell's quillwort,N,29392,4379,63823
|
@@ -1214,6 +1216,7 @@ Navarretia squarrosa,skunkweed,N,34475,5807,53157
|
|
1214
1216
|
Navarretia tagetina,,N,34477,5809,60226
|
1215
1217
|
Navarretia viscidula,sticky navarretia,N,34478,5810,78195
|
1216
1218
|
Nemophila heterophylla,,N,34539,5834,53158
|
1219
|
+
Nemophila menziesii var. atomaria,,N,62279,,,white,2,6
|
1217
1220
|
Nemophila menziesii var. menziesii,baby blue-eyes,N,62285,5839,50650
|
1218
1221
|
Nemophila parviflora var. parviflora,,N,62288,5842,58921
|
1219
1222
|
Nemophila pedunculata,,N,34544,5844,55461
|
@@ -0,0 +1 @@
|
|
1
|
+
Leaves unlobed to shallowly 3-lobed. Hairs red-orange.
|
@@ -0,0 +1 @@
|
|
1
|
+
Leaves palmately 3 to 5-lobed. Hairs white.
|
@@ -1 +1 @@
|
|
1
|
-
Annual. Ligules extend only slightly beyond involucre. Leaves hairless or very nearly so. Leaves basal.
|
1
|
+
Annual. [Peduncle](g/peduncle.html) has bracts. Ligules extend only slightly beyond involucre. Leaves hairless or very nearly so. Leaves basal.
|
@@ -1 +1 @@
|
|
1
|
-
Perennial. Ligules extend much beyond involucre. Leaves bristly and rough to touch. Leaves basal.
|
1
|
+
Perennial. [Peduncle](g/peduncle.html) has bracts. Ligules extend much beyond involucre. Leaves bristly and rough to touch. Leaves basal.
|
package/ebook/css/main.css
CHANGED
@@ -0,0 +1,63 @@
|
|
1
|
+
import commandLineArgs from "command-line-args";
|
2
|
+
import commandLineUsage from "command-line-usage";
|
3
|
+
|
4
|
+
const OPTION_DEFS = [
|
5
|
+
{ name: "help", type: Boolean },
|
6
|
+
];
|
7
|
+
|
8
|
+
class CommandRunner {
|
9
|
+
|
10
|
+
#commandName;
|
11
|
+
#commandDesc;
|
12
|
+
#optionDefs;
|
13
|
+
#optionHelp;
|
14
|
+
#additionalHelp;
|
15
|
+
#commandFunc;
|
16
|
+
|
17
|
+
constructor( commandName, commandDesc, optionDefs, optionHelp, additionalHelp = [], commandFunc ) {
|
18
|
+
this.#commandName = commandName;
|
19
|
+
this.#commandDesc = commandDesc;
|
20
|
+
this.#optionDefs = optionDefs;
|
21
|
+
this.#optionHelp = optionHelp;
|
22
|
+
this.#additionalHelp = additionalHelp;
|
23
|
+
this.#commandFunc = commandFunc;
|
24
|
+
}
|
25
|
+
|
26
|
+
async processCommandLine() {
|
27
|
+
|
28
|
+
const options = commandLineArgs( this.#optionDefs.concat( OPTION_DEFS ) );
|
29
|
+
|
30
|
+
if ( options.help ) {
|
31
|
+
this.showHelp();
|
32
|
+
return;
|
33
|
+
}
|
34
|
+
|
35
|
+
console.log( "Use --help to see all options" );
|
36
|
+
await this.#commandFunc( options );
|
37
|
+
|
38
|
+
}
|
39
|
+
|
40
|
+
showHelp() {
|
41
|
+
const help = [
|
42
|
+
{
|
43
|
+
header: this.#commandName,
|
44
|
+
content: this.#commandDesc
|
45
|
+
},
|
46
|
+
{
|
47
|
+
header: "Options",
|
48
|
+
optionList: [
|
49
|
+
{
|
50
|
+
name: "help",
|
51
|
+
type: Boolean,
|
52
|
+
description: "Print this usage guide."
|
53
|
+
},
|
54
|
+
]
|
55
|
+
}
|
56
|
+
];
|
57
|
+
help[ 1 ].optionList = help[ 1 ].optionList.concat( this.#optionHelp );
|
58
|
+
console.log( commandLineUsage( help.concat( this.#additionalHelp ) ) );
|
59
|
+
}
|
60
|
+
|
61
|
+
}
|
62
|
+
|
63
|
+
export { CommandRunner };
|
package/lib/config.js
CHANGED
@@ -4,18 +4,15 @@ import { Files } from "./files.js";
|
|
4
4
|
|
5
5
|
class Config {
|
6
6
|
|
7
|
-
static #config = {};
|
8
7
|
static #packageDir = path.dirname( path.dirname( url.fileURLToPath( import.meta.url ) ) );
|
9
8
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
console.log( e );
|
15
|
-
}
|
9
|
+
#config = {};
|
10
|
+
|
11
|
+
constructor( dataDir ) {
|
12
|
+
this.#config = JSON.parse( Files.read( dataDir + "/config.json" ) );
|
16
13
|
}
|
17
14
|
|
18
|
-
|
15
|
+
getConfigValue( prefix, name, subcat, dflt ) {
|
19
16
|
const obj = this.#config[ prefix ];
|
20
17
|
if ( obj ) {
|
21
18
|
if ( Object.hasOwn( obj, name ) ) {
|
@@ -34,11 +31,11 @@ class Config {
|
|
34
31
|
return dflt;
|
35
32
|
}
|
36
33
|
|
37
|
-
|
34
|
+
getCountyCodes() {
|
38
35
|
return this.#config[ "counties" ];
|
39
36
|
}
|
40
37
|
|
41
|
-
|
38
|
+
getLabel( name, dflt ) {
|
42
39
|
return this.getConfigValue( "labels", name, undefined, dflt );
|
43
40
|
}
|
44
41
|
|
package/lib/dataloader.js
CHANGED
@@ -2,26 +2,19 @@ import { CSV } from "./csv.js";
|
|
2
2
|
import { Taxa } from "./taxa.js";
|
3
3
|
import { Files } from "./files.js";
|
4
4
|
|
5
|
-
const OPTION_DEFS = [
|
6
|
-
{ name: "datadir", type: String, defaultValue: "./data" },
|
7
|
-
];
|
8
|
-
|
9
5
|
class DataLoader {
|
10
6
|
|
11
|
-
static
|
12
|
-
return OPTION_DEFS;
|
13
|
-
}
|
14
|
-
|
15
|
-
static load( options ) {
|
7
|
+
static load( dataDir ) {
|
16
8
|
|
17
|
-
function getIncludeList() {
|
9
|
+
function getIncludeList( dataDir ) {
|
18
10
|
// Read inclusion list.
|
19
11
|
const includeFileName = "taxa_include.csv";
|
20
|
-
|
21
|
-
|
12
|
+
const includeFilePath = dataDir + "/" + includeFileName;
|
13
|
+
if ( !Files.exists( includeFilePath ) ) {
|
14
|
+
console.log( includeFilePath + " not found; loading all taxa" );
|
22
15
|
return true;
|
23
16
|
}
|
24
|
-
const includeCSV = CSV.parseFile(
|
17
|
+
const includeCSV = CSV.parseFile( dataDir, includeFileName );
|
25
18
|
const include = {};
|
26
19
|
for ( const row of includeCSV ) {
|
27
20
|
include[ row[ "taxon_name" ] ] = row;
|
@@ -29,11 +22,9 @@ class DataLoader {
|
|
29
22
|
return include;
|
30
23
|
}
|
31
24
|
|
32
|
-
const taxaDir = options.datadir;
|
33
|
-
|
34
25
|
console.log( "loading data" );
|
35
26
|
|
36
|
-
return new Taxa( getIncludeList() );
|
27
|
+
return new Taxa( getIncludeList( dataDir ) );
|
37
28
|
|
38
29
|
}
|
39
30
|
|
package/lib/ebook/plantbook.js
CHANGED
@@ -8,7 +8,6 @@ import { PageListFlowers } from "./pages/page_list_flowers.js";
|
|
8
8
|
import { PageListSpecies } from "./pages/page_list_species.js";
|
9
9
|
import { TaxonPage } from "./pages/taxonpage.js";
|
10
10
|
import { TOCPage } from "./pages/tocpage.js";
|
11
|
-
import { Config } from "../config.js";
|
12
11
|
import { FLOWER_COLOR_NAMES } from "../taxa.js";
|
13
12
|
|
14
13
|
class PlantBook extends EBook {
|
@@ -17,13 +16,13 @@ class PlantBook extends EBook {
|
|
17
16
|
#glossary;
|
18
17
|
#images;
|
19
18
|
|
20
|
-
constructor( taxa ) {
|
19
|
+
constructor( outputDir, config, taxa ) {
|
21
20
|
|
22
21
|
super(
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
22
|
+
outputDir,
|
23
|
+
config.getConfigValue( "ebook", "filename" ),
|
24
|
+
config.getConfigValue( "ebook", "pub_id" ),
|
25
|
+
config.getConfigValue( "ebook", "title" )
|
27
26
|
);
|
28
27
|
|
29
28
|
this.#taxa = taxa;
|
@@ -89,7 +88,7 @@ class PlantBook extends EBook {
|
|
89
88
|
}
|
90
89
|
|
91
90
|
// Add taxon pages.
|
92
|
-
const taxa = this.#taxa.
|
91
|
+
const taxa = this.#taxa.getTaxonList();
|
93
92
|
for ( let index = 0; index < taxa.length; index++ ) {
|
94
93
|
const taxon = taxa[ index ];
|
95
94
|
xml += "<item id=\"t" + index + "\" href=\"" + taxon.getFileName() + "\" media-type=\"application/xhtml+xml\" />";
|
package/lib/index.d.ts
CHANGED
@@ -2,13 +2,20 @@ export class BasePageRenderer {
|
|
2
2
|
static render(outputDir: any, taxa: any, familyCols: any): void;
|
3
3
|
static renderTools(outputDir: any, taxa: any): void;
|
4
4
|
}
|
5
|
+
export class CommandRunner {
|
6
|
+
constructor(commandName: any, commandDesc: any, optionDefs: any, optionHelp: any, additionalHelp: any[], commandFunc: any);
|
7
|
+
processCommandLine(): Promise<void>;
|
8
|
+
showHelp(): void;
|
9
|
+
#private;
|
10
|
+
}
|
5
11
|
export class Config {
|
6
|
-
static "__#1@#config": {};
|
7
12
|
static "__#1@#packageDir": string;
|
8
|
-
static getConfigValue(prefix: any, name: any, subcat: any, dflt: any): any;
|
9
|
-
static getCountyCodes(): any;
|
10
|
-
static getLabel(name: any, dflt: any): any;
|
11
13
|
static getPackageDir(): string;
|
14
|
+
constructor(dataDir: any);
|
15
|
+
getConfigValue(prefix: any, name: any, subcat: any, dflt: any): any;
|
16
|
+
getCountyCodes(): any;
|
17
|
+
getLabel(name: any, dflt: any): any;
|
18
|
+
#private;
|
12
19
|
}
|
13
20
|
export class CSV {
|
14
21
|
static getMap(dir: any, fileName: any): {};
|
@@ -19,12 +26,7 @@ export class CSV {
|
|
19
26
|
static parseStream(dir: any, fileName: any, columns: boolean, delimiter: any, callback: any): Promise<void>;
|
20
27
|
}
|
21
28
|
export class DataLoader {
|
22
|
-
static
|
23
|
-
name: string;
|
24
|
-
type: StringConstructor;
|
25
|
-
defaultValue: string;
|
26
|
-
}[];
|
27
|
-
static load(options: any): Taxa;
|
29
|
+
static load(dataDir: any): Taxa;
|
28
30
|
}
|
29
31
|
import { Taxa } from "./taxa.js";
|
30
32
|
export class DateUtils {
|
@@ -132,6 +134,7 @@ export class HTML {
|
|
132
134
|
static wrap(elName: any, text: any, attributes?: {}): string;
|
133
135
|
}
|
134
136
|
import { BasePageRenderer } from "./basepagerenderer.js";
|
137
|
+
import { CommandRunner } from "./commandrunner.js";
|
135
138
|
import { Config } from "./config.js";
|
136
139
|
import { CSV } from "./csv.js";
|
137
140
|
import { DataLoader } from "./dataloader.js";
|
@@ -145,7 +148,7 @@ import { PlantBook } from "./ebook/plantbook.js";
|
|
145
148
|
import { Taxa } from "./taxa.js";
|
146
149
|
import { TAXA_COLNAMES } from "./taxon.js";
|
147
150
|
import { Taxon } from "./taxon.js";
|
148
|
-
export { BasePageRenderer, Config, CSV, DataLoader, ErrorLog, Exceptions, Families, Files, HTML, Jekyll, PlantBook, Taxa, TAXA_COLNAMES, Taxon };
|
151
|
+
export { BasePageRenderer, CommandRunner, Config, CSV, DataLoader, ErrorLog, Exceptions, Families, Files, HTML, Jekyll, PlantBook, Taxa, TAXA_COLNAMES, Taxon };
|
149
152
|
export class Jekyll {
|
150
153
|
static getFrontMatter(atts: any): string;
|
151
154
|
static hasInclude(baseDir: any, path: any): boolean;
|
@@ -174,8 +177,13 @@ export class Taxa {
|
|
174
177
|
}[]): string;
|
175
178
|
constructor(inclusionList: any, taxaMeta?: {}, taxonClass?: typeof Taxon, extraTaxa?: any[], extraSynonyms?: any[]);
|
176
179
|
getFlowerColor(name: any): any;
|
180
|
+
/**
|
181
|
+
*
|
182
|
+
* @deprecated
|
183
|
+
*/
|
177
184
|
getTaxa(): any[];
|
178
185
|
getTaxon(name: any): any;
|
186
|
+
getTaxonList(): any[];
|
179
187
|
#private;
|
180
188
|
}
|
181
189
|
export namespace TAXA_LIST_COLS {
|
@@ -256,7 +264,7 @@ export class Taxon {
|
|
256
264
|
getRPIRankAndThreatTooltip(): string;
|
257
265
|
getRPITaxonLink(): string;
|
258
266
|
getStatus(): any;
|
259
|
-
getStatusDescription(): any;
|
267
|
+
getStatusDescription(config: any): any;
|
260
268
|
getSynonyms(): any[];
|
261
269
|
isCANative(): boolean;
|
262
270
|
/**
|
package/lib/index.js
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
import { BasePageRenderer } from "./basepagerenderer.js";
|
2
|
+
import { CommandRunner } from "./commandrunner.js";
|
2
3
|
import { Config } from "./config.js";
|
3
4
|
import { CSV } from "./csv.js";
|
4
5
|
import { DataLoader } from "./dataloader.js";
|
@@ -12,4 +13,4 @@ import { PlantBook } from "./ebook/plantbook.js";
|
|
12
13
|
import { Taxa } from "./taxa.js";
|
13
14
|
import { Taxon, TAXA_COLNAMES } from "./taxon.js";
|
14
15
|
|
15
|
-
export { BasePageRenderer, Config, CSV, DataLoader, ErrorLog, Exceptions, Families, Files, HTML, Jekyll, PlantBook, Taxa, TAXA_COLNAMES, Taxon };
|
16
|
+
export { BasePageRenderer, CommandRunner, Config, CSV, DataLoader, ErrorLog, Exceptions, Families, Files, HTML, Jekyll, PlantBook, Taxa, TAXA_COLNAMES, Taxon };
|
package/lib/pagerenderer.js
CHANGED
@@ -1,7 +1,6 @@
|
|
1
|
-
import { Files, HTML } from "@ca-plant-list/ca-plant-list";
|
2
|
-
import {
|
1
|
+
import { Files, Taxa, HTML } from "@ca-plant-list/ca-plant-list";
|
2
|
+
import { TAXA_LIST_COLS } from "./taxa.js";
|
3
3
|
import { PageTaxon } from "./web/pagetaxon.js";
|
4
|
-
import { Config } from "./config.js";
|
5
4
|
import { RarePlants } from "./rareplants.js";
|
6
5
|
import { BasePageRenderer } from "./basepagerenderer.js";
|
7
6
|
import { GenericPage } from "./genericpage.js";
|
@@ -11,20 +10,20 @@ const RPI_COLUMNS = [ TAXA_LIST_COLS.SPECIES_BARE, TAXA_LIST_COLS.COMMON_NAME, T
|
|
11
10
|
|
12
11
|
class PageRenderer extends BasePageRenderer {
|
13
12
|
|
14
|
-
static render( outputDir, taxa ) {
|
13
|
+
static render( outputDir, config, taxa ) {
|
15
14
|
|
16
15
|
super.render( outputDir, taxa );
|
17
16
|
|
18
|
-
this.renderLists( outputDir, taxa );
|
17
|
+
this.renderLists( outputDir, config, taxa );
|
19
18
|
|
20
|
-
const taxonList = taxa.
|
19
|
+
const taxonList = taxa.getTaxonList();
|
21
20
|
for ( const taxon of taxonList ) {
|
22
|
-
new PageTaxon( outputDir, taxon ).render();
|
21
|
+
new PageTaxon( outputDir, config, taxon ).render();
|
23
22
|
}
|
24
23
|
|
25
24
|
}
|
26
25
|
|
27
|
-
static renderLists( outputDir, taxa ) {
|
26
|
+
static renderLists( outputDir, config, taxa ) {
|
28
27
|
|
29
28
|
function getListArray( listInfo, attributes = {}, columns ) {
|
30
29
|
|
@@ -76,8 +75,8 @@ class PageRenderer extends BasePageRenderer {
|
|
76
75
|
{
|
77
76
|
title: "All Species",
|
78
77
|
listInfo: [
|
79
|
-
{ name:
|
80
|
-
{ name:
|
78
|
+
{ name: config.getLabel( "native", "Native" ), filename: "list_native", include: ( t ) => t.isNative() },
|
79
|
+
{ name: config.getLabel( "introduced", "Introduced" ), filename: "list_introduced", include: ( t ) => !t.isNative() },
|
81
80
|
{ name: "All Plants", filename: "list_all", include: () => true },
|
82
81
|
]
|
83
82
|
},
|
package/lib/taxa.js
CHANGED
@@ -127,6 +127,10 @@ class Taxa {
|
|
127
127
|
return this.#flower_colors[ name ];
|
128
128
|
}
|
129
129
|
|
130
|
+
/**
|
131
|
+
*
|
132
|
+
* @deprecated
|
133
|
+
*/
|
130
134
|
getTaxa() {
|
131
135
|
return this.#sortedTaxa;
|
132
136
|
}
|
@@ -135,6 +139,10 @@ class Taxa {
|
|
135
139
|
return this.#taxa[ name ];
|
136
140
|
}
|
137
141
|
|
142
|
+
getTaxonList() {
|
143
|
+
return this.#sortedTaxa;
|
144
|
+
}
|
145
|
+
|
138
146
|
#loadSyns( synCSV, inclusionList ) {
|
139
147
|
for ( const syn of synCSV ) {
|
140
148
|
const currName = syn[ "Current" ];
|
package/lib/taxon.js
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
import { Config } from "./config.js";
|
2
1
|
import { Genera } from "./genera.js";
|
3
2
|
import { HTML } from "./html.js";
|
4
3
|
import { RarePlants } from "./rareplants.js";
|
@@ -224,12 +223,12 @@ class Taxon {
|
|
224
223
|
return this.#status;
|
225
224
|
}
|
226
225
|
|
227
|
-
getStatusDescription() {
|
226
|
+
getStatusDescription( config ) {
|
228
227
|
switch ( this.#status ) {
|
229
228
|
case "N":
|
230
229
|
return "Native";
|
231
230
|
case "NC":
|
232
|
-
return
|
231
|
+
return config.getLabel( "status-NC", "Introduced" );
|
233
232
|
case "X":
|
234
233
|
return "Introduced";
|
235
234
|
}
|
package/lib/web/pagetaxon.js
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
import { HTML } from "@ca-plant-list/ca-plant-list";
|
2
2
|
import { Jepson } from "../jepson.js";
|
3
|
-
import { Config } from "../config.js";
|
4
3
|
import { RarePlants } from "../rareplants.js";
|
5
4
|
import { GenericPage } from "../genericpage.js";
|
6
5
|
import { ExternalSites } from "../externalsites.js";
|
@@ -8,10 +7,12 @@ import { DateUtils } from "../dateutils.js";
|
|
8
7
|
|
9
8
|
class PageTaxon extends GenericPage {
|
10
9
|
|
10
|
+
#config;
|
11
11
|
#taxon;
|
12
12
|
|
13
|
-
constructor( outputDir, taxon ) {
|
13
|
+
constructor( outputDir, config, taxon ) {
|
14
14
|
super( outputDir, taxon.getName(), taxon.getBaseFileName() );
|
15
|
+
this.#config = config;
|
15
16
|
this.#taxon = taxon;
|
16
17
|
}
|
17
18
|
|
@@ -73,7 +74,7 @@ class PageTaxon extends GenericPage {
|
|
73
74
|
links.push(
|
74
75
|
HTML.getLink(
|
75
76
|
"https://www.calflora.org/entry/observ.html?track=m#srch=t&grezc=5&cols=b&lpcli=t&cc="
|
76
|
-
+
|
77
|
+
+ this.#config.getCountyCodes().join( "!" ) + "&incobs=f&taxon="
|
77
78
|
+ this.#taxon.getCalfloraName().replaceAll( " ", "+" ),
|
78
79
|
"Calflora",
|
79
80
|
{},
|
@@ -86,7 +87,7 @@ class PageTaxon extends GenericPage {
|
|
86
87
|
HTML.getLink(
|
87
88
|
ExternalSites.getInatObsLink(
|
88
89
|
{
|
89
|
-
project_id:
|
90
|
+
project_id: this.#config.getConfigValue( "inat", "project_id" ),
|
90
91
|
subview: "map",
|
91
92
|
taxon_id: iNatID
|
92
93
|
}
|
@@ -163,7 +164,7 @@ class PageTaxon extends GenericPage {
|
|
163
164
|
html += HTML.textElement( "div", cn.join( ", " ), { class: "section common-names" } );
|
164
165
|
}
|
165
166
|
|
166
|
-
html += HTML.textElement( "div", this.#taxon.getStatusDescription(), { class: "section native-status" } );
|
167
|
+
html += HTML.textElement( "div", this.#taxon.getStatusDescription( this.#config ), { class: "section native-status" } );
|
167
168
|
|
168
169
|
const family = this.#taxon.getFamily();
|
169
170
|
html += HTML.wrap(
|
package/package.json
CHANGED
package/scripts/build-ebook.js
CHANGED
@@ -1,10 +1,74 @@
|
|
1
1
|
#!/usr/bin/env node
|
2
2
|
|
3
|
-
import
|
4
|
-
import { PlantBook } from "@ca-plant-list/ca-plant-list";
|
3
|
+
import { CommandRunner, PlantBook } from "@ca-plant-list/ca-plant-list";
|
5
4
|
import { DataLoader } from "../lib/dataloader.js";
|
5
|
+
import { Config } from "../lib/config.js";
|
6
|
+
import { Files } from "../lib/files.js";
|
7
|
+
import { ErrorLog } from "../lib/errorlog.js";
|
6
8
|
|
7
|
-
const
|
9
|
+
const OUTPUT_DIR = "./output";
|
10
|
+
const LOC_DIR = "./locations";
|
11
|
+
|
12
|
+
const OPTION_DEFS = [
|
13
|
+
{ name: "datadir", type: String },
|
14
|
+
];
|
15
|
+
|
16
|
+
const OPTION_HELP = [
|
17
|
+
{
|
18
|
+
name: "datadir",
|
19
|
+
type: String,
|
20
|
+
typeLabel: "{underline path}",
|
21
|
+
description: "The directory in which the data files for the local plant list are located. If no directory is specified:\n"
|
22
|
+
+ "- if there is a {bold locations} subdirectory in the current directory, each subdirectory of the {bold locations} subdirectory"
|
23
|
+
+ " will be used as the data directory from which to generate an ebook (multiple ebooks will be generated)\n"
|
24
|
+
+ "- otherwise {bold ./data} will be used as the {bold datadir}"
|
25
|
+
},
|
26
|
+
];
|
27
|
+
|
28
|
+
const cr = new CommandRunner(
|
29
|
+
"ca-plant-book",
|
30
|
+
"A tool to generate an ebook with local plant data.",
|
31
|
+
OPTION_DEFS,
|
32
|
+
OPTION_HELP,
|
33
|
+
undefined,
|
34
|
+
generateEBooks,
|
35
|
+
);
|
36
|
+
await cr.processCommandLine();
|
37
|
+
|
38
|
+
async function generateEBooks( options ) {
|
39
|
+
|
40
|
+
const dataDir = options.datadir;
|
41
|
+
|
42
|
+
// If a data directory was specified, use it.
|
43
|
+
if ( dataDir ) {
|
44
|
+
await generateEBook( dataDir );
|
45
|
+
return;
|
46
|
+
}
|
47
|
+
|
48
|
+
// If there is a "locations" directory, generate a book for all subdirectories.
|
49
|
+
const hasLocations = Files.isDir( LOC_DIR );
|
50
|
+
if ( hasLocations ) {
|
51
|
+
// Generate ebook for each location.
|
52
|
+
const subdirs = Files.getDirEntries( LOC_DIR );
|
53
|
+
for ( const subdir of subdirs ) {
|
54
|
+
const suffix = "/" + subdir;
|
55
|
+
const path = LOC_DIR + suffix;
|
56
|
+
if ( Files.isDir( path ) ) {
|
57
|
+
await generateEBook( path, suffix );
|
58
|
+
}
|
59
|
+
}
|
60
|
+
return;
|
61
|
+
}
|
62
|
+
|
63
|
+
// Otherwise use the default directory.
|
64
|
+
await generateEBook( "./data" );
|
65
|
+
|
66
|
+
ErrorLog.write( OUTPUT_DIR + "/errors.tsv" );
|
67
|
+
|
68
|
+
}
|
69
|
+
|
70
|
+
async function generateEBook( dataDir, outputSuffix = "" ) {
|
71
|
+
const ebook = new PlantBook( OUTPUT_DIR + outputSuffix, new Config( dataDir ), DataLoader.load( dataDir ) );
|
72
|
+
await ebook.create();
|
73
|
+
}
|
8
74
|
|
9
|
-
const ebook = new PlantBook( DataLoader.load( options ) );
|
10
|
-
await ebook.create();
|
package/scripts/build-site.js
CHANGED
@@ -1,14 +1,40 @@
|
|
1
1
|
#!/usr/bin/env node
|
2
2
|
|
3
|
+
import { Config } from "../lib/config.js";
|
3
4
|
import { DataLoader } from "../lib/dataloader.js";
|
4
|
-
import { ErrorLog } from "../lib/errorlog.js";
|
5
5
|
import { PageRenderer } from "../lib/pagerenderer.js";
|
6
|
-
import
|
7
|
-
|
8
|
-
const options = commandLineArgs( DataLoader.getOptionDefs() );
|
6
|
+
import { CommandRunner } from "../lib/commandrunner.js";
|
7
|
+
import { ErrorLog } from "../lib/errorlog.js";
|
9
8
|
|
10
9
|
const OUTPUT_DIR = "./output";
|
11
10
|
|
12
|
-
|
11
|
+
const OPTION_DEFS = [
|
12
|
+
{ name: "datadir", type: String, defaultValue: "./data" },
|
13
|
+
];
|
14
|
+
|
15
|
+
const OPTION_HELP = [
|
16
|
+
{
|
17
|
+
name: "datadir",
|
18
|
+
type: String,
|
19
|
+
typeLabel: "{underline path}",
|
20
|
+
description: "The directory in which the data files for the local plant list are located. Defaults to {bold ./data}."
|
21
|
+
|
22
|
+
},
|
23
|
+
];
|
24
|
+
|
25
|
+
const cr = new CommandRunner(
|
26
|
+
"ca-plant-list",
|
27
|
+
"A tool to generate a website with local plant data.",
|
28
|
+
OPTION_DEFS,
|
29
|
+
OPTION_HELP,
|
30
|
+
undefined,
|
31
|
+
generateSite,
|
32
|
+
);
|
33
|
+
await cr.processCommandLine();
|
34
|
+
|
35
|
+
function generateSite( options ) {
|
36
|
+
const dataDir = options.datadir;
|
37
|
+
PageRenderer.render( OUTPUT_DIR, new Config( dataDir ), DataLoader.load( dataDir ) );
|
38
|
+
ErrorLog.write( OUTPUT_DIR + "/errors.tsv" );
|
39
|
+
}
|
13
40
|
|
14
|
-
ErrorLog.write( OUTPUT_DIR + "/errors.tsv" );
|