@ca-plant-list/ca-plant-list 0.2.11 → 0.2.12
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/taxa.csv +15 -15
- package/data/text/Arctostaphylos-auriculata.md +1 -0
- package/data/text/Arctostaphylos-crustacea-subsp-crustacea.md +1 -0
- package/data/text/Arctostaphylos-glandulosa-subsp-glandulosa.md +1 -0
- package/data/text/Arctostaphylos-glauca.md +1 -0
- package/data/text/Arctostaphylos-manzanita-subsp-laevigata.md +1 -0
- package/data/text/Arctostaphylos-manzanita-subsp-manzanita.md +1 -0
- package/data/text/Arctostaphylos-pallida.md +1 -0
- package/data/text/Oxalis incarnata.md +1 -0
- package/data/text/Oxalis-corniculata.md +1 -0
- package/data/text/Oxalis-oregana.md +1 -0
- package/data/text/Oxalis-pilosa.md +1 -0
- package/lib/basepagerenderer.js +4 -4
- package/lib/dataloader.js +1 -10
- package/lib/ebook/images.js +5 -3
- package/lib/ebook/pages/page_list_flowers.js +6 -5
- package/lib/ebook/plantbook.js +14 -12
- package/lib/exceptions.js +21 -21
- package/lib/families.js +50 -53
- package/lib/genera.js +6 -4
- package/lib/index.d.ts +15 -21
- package/lib/pagerenderer.js +12 -12
- package/lib/taxa.js +29 -32
- package/package.json +1 -1
- package/scripts/build-ebook.js +1 -3
- package/scripts/build-site.js +1 -2
package/data/taxa.csv
CHANGED
@@ -1061,24 +1061,24 @@ Ludwigia palustris,,N,31651,5083,60221
|
|
1061
1061
|
Ludwigia peploides subsp. montevidensis,water-primrose,X,51358,5085,61049
|
1062
1062
|
Ludwigia peploides subsp. peploides,,X,51359,5086,61046
|
1063
1063
|
Lunaria annua,moonwort,X,31676,5091,55886
|
1064
|
-
Lupinus affinis,,N,31690,5095,77846
|
1065
|
-
Lupinus albifrons var. albifrons,bush lupine,N,61188,5099,53418
|
1064
|
+
Lupinus affinis,,N,31690,5095,77846,blue,3,5
|
1065
|
+
Lupinus albifrons var. albifrons,bush lupine,N,61188,5099,53418,blue,3,6
|
1066
1066
|
Lupinus albifrons var. collinus,,N,61189,5100,61795
|
1067
|
-
Lupinus arboreus,yellow bush lupine,N,31731,5106,61010
|
1067
|
+
Lupinus arboreus,yellow bush lupine,N,31731,5106,61010,yellow,4,7
|
1068
1068
|
Lupinus benthamii,spider lupine,N,31791,5117,59565
|
1069
|
-
Lupinus bicolor,miniature lupine,N,31793,5118,50614,blue
|
1069
|
+
Lupinus bicolor,miniature lupine,N,31793,5118,50614,blue,3,6
|
1070
1070
|
Lupinus chamissonis,beach blue lupine,N,31831,5125,61011
|
1071
1071
|
Lupinus concinnus,Bajada lupine,N,31835,5129,58901
|
1072
|
-
Lupinus formosus var. formosus,"summer lupine,western lupine",N,61315,5148,61822,blue
|
1072
|
+
Lupinus formosus var. formosus,"summer lupine,western lupine",N,61315,5148,61822,blue,4,9
|
1073
1073
|
Lupinus latifolius var. dudleyi,,N,76660,5161,81063
|
1074
|
-
Lupinus latifolius var. latifolius,wood lupine,N,75772,5162,64242,blue
|
1074
|
+
Lupinus latifolius var. latifolius,"broadleaf lupine,wood lupine",N,75772,5162,64242,blue,4,9
|
1075
1075
|
Lupinus littoralis var. variicolor,,N,80538,14304
|
1076
1076
|
Lupinus luteolus,butter lupine,N,31956,5176,77875
|
1077
|
-
Lupinus microcarpus var. densiflorus,,N,76668,5184,241537,"yellow,white"
|
1078
|
-
Lupinus microcarpus var. microcarpus,chick lupine,N,75776,5186,58159,"pink,blue"
|
1079
|
-
Lupinus nanus,sky lupine,N,31978,5189,50612,blue
|
1077
|
+
Lupinus microcarpus var. densiflorus,,N,76668,5184,241537,"yellow,white",4,6
|
1078
|
+
Lupinus microcarpus var. microcarpus,chick lupine,N,75776,5186,58159,"pink,blue",3,6
|
1079
|
+
Lupinus nanus,sky lupine,N,31978,5189,50612,blue,3,6
|
1080
1080
|
Lupinus pachylobus,big pod lupine,N,31998,5196,50613
|
1081
|
-
Lupinus succulentus,arroyo lupine,N,32095,5217,56759,blue
|
1081
|
+
Lupinus succulentus,arroyo lupine,N,32095,5217,56759,blue,2,5
|
1082
1082
|
Luzula comosa var. comosa,wood rush,N,72790,11810,81079
|
1083
1083
|
Luzula subsessilis,,N,32171,11815,77901
|
1084
1084
|
Lychnis coronaria,rose campion,X,32177,5229,485191
|
@@ -1237,11 +1237,11 @@ Oenothera xenogaura,,X,89232,11890,545863
|
|
1237
1237
|
Olea europaea,olive,X,35090,5912,57140
|
1238
1238
|
Osmorhiza berteroi,wood cicely,N,35560,10164,53166
|
1239
1239
|
Osmorhiza brachypoda,California cicely,N,35564,6000,58793
|
1240
|
-
Oxalis corniculata,creeping wood sorrel,X,35609,6010,53168
|
1241
|
-
Oxalis incarnata,crimson wood sorrel,X,35636,6012,61776
|
1242
|
-
Oxalis oregana,redwood sorrel,N,35641,6015,47757
|
1243
|
-
Oxalis pes-caprae,Bermuda-buttercup,X,35642,6016,53169
|
1244
|
-
Oxalis pilosa,hairy wood sorrel,N,35601,11895,78300
|
1240
|
+
Oxalis corniculata,creeping wood sorrel,X,35609,6010,53168,yellow,1,12
|
1241
|
+
Oxalis incarnata,crimson wood sorrel,X,35636,6012,61776,"white,pink",3,6
|
1242
|
+
Oxalis oregana,redwood sorrel,N,35641,6015,47757,"white,pink",2,8
|
1243
|
+
Oxalis pes-caprae,Bermuda-buttercup,X,35642,6016,53169,yellow,1,5
|
1244
|
+
Oxalis pilosa,hairy wood sorrel,N,35601,11895,78300,yellow,2,9
|
1245
1245
|
Packera breweri,Brewer groundsel,N,77383,9613,56983
|
1246
1246
|
Panicum acuminatum,Pacific panic grass,N,35923,6044,128949
|
1247
1247
|
Panicum capillare,witchgrass,N,36094,6048,78337
|
@@ -0,0 +1 @@
|
|
1
|
+
No burl. Height 1-4.5 meters. Endemic to Mt. Diablo area.
|
@@ -0,0 +1 @@
|
|
1
|
+
Burl prominent. Height 1-3 meters. Petiole 2-5mm.
|
@@ -0,0 +1 @@
|
|
1
|
+
Durl hemispheric. Height 1-4 meters; shrub or erect. Petiole 5-10mm.
|
@@ -0,0 +1 @@
|
|
1
|
+
No burl. Height 1-8 meters, erect.
|
@@ -0,0 +1 @@
|
|
1
|
+
No burl. Height 2-8 meters.
|
@@ -0,0 +1 @@
|
|
1
|
+
No burl. Height 2-8 meters. Petiole 6-12mm.
|
@@ -0,0 +1 @@
|
|
1
|
+
No burl. Height 2-4 meters, erect. Petiole < 2mm, clasping branches
|
@@ -0,0 +1 @@
|
|
1
|
+
Stems often with bulblets. Sepals less than 6 mm, tips with 2 orange tubercles.
|
@@ -0,0 +1 @@
|
|
1
|
+
Petals less than 8mm. Stem rooting at nodes. Often red at base of petals.
|
@@ -0,0 +1 @@
|
|
1
|
+
No bulbs.
|
@@ -0,0 +1 @@
|
|
1
|
+
Petals 8-12mm. Stem generally not rooting at nodes.
|
package/lib/basepagerenderer.js
CHANGED
@@ -5,7 +5,7 @@ import { GlossaryPages } from "./web/glossarypages.js";
|
|
5
5
|
|
6
6
|
class BasePageRenderer {
|
7
7
|
|
8
|
-
static render( outputDir,
|
8
|
+
static render( outputDir, taxa, familyCols ) {
|
9
9
|
|
10
10
|
// Copy static files
|
11
11
|
Files.rmDir( outputDir );
|
@@ -20,14 +20,14 @@ class BasePageRenderer {
|
|
20
20
|
|
21
21
|
new GlossaryPages( outputDir ).renderPages();
|
22
22
|
|
23
|
-
this.renderTools( outputDir,
|
23
|
+
this.renderTools( outputDir, taxa );
|
24
24
|
|
25
25
|
}
|
26
26
|
|
27
|
-
static renderTools( outputDir,
|
27
|
+
static renderTools( outputDir, taxa ) {
|
28
28
|
|
29
29
|
const names = [];
|
30
|
-
for ( const taxon of
|
30
|
+
for ( const taxon of taxa.getTaxa() ) {
|
31
31
|
const row = [];
|
32
32
|
row.push( taxon.getName() );
|
33
33
|
const cn = taxon.getCommonNames().join( ", " );
|
package/lib/dataloader.js
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
import { CSV } from "./csv.js";
|
2
2
|
import { Taxa } from "./taxa.js";
|
3
|
-
import { Families } from "./families.js";
|
4
|
-
import { Exceptions } from "./exceptions.js";
|
5
3
|
import { Files } from "./files.js";
|
6
4
|
|
7
5
|
const OPTION_DEFS = [
|
@@ -14,11 +12,6 @@ class DataLoader {
|
|
14
12
|
return OPTION_DEFS;
|
15
13
|
}
|
16
14
|
|
17
|
-
static init( taxaDir ) {
|
18
|
-
Exceptions.init( taxaDir );
|
19
|
-
Families.init();
|
20
|
-
}
|
21
|
-
|
22
15
|
static load( options ) {
|
23
16
|
|
24
17
|
function getIncludeList() {
|
@@ -40,9 +33,7 @@ class DataLoader {
|
|
40
33
|
|
41
34
|
console.log( "loading data" );
|
42
35
|
|
43
|
-
|
44
|
-
|
45
|
-
Taxa.init( getIncludeList() );
|
36
|
+
return new Taxa( getIncludeList() );
|
46
37
|
|
47
38
|
}
|
48
39
|
|
package/lib/ebook/images.js
CHANGED
@@ -3,18 +3,20 @@ import path from "node:path";
|
|
3
3
|
|
4
4
|
import sharp from "sharp";
|
5
5
|
|
6
|
-
import { Config, CSV, Files
|
6
|
+
import { Config, CSV, Files } from "@ca-plant-list/ca-plant-list";
|
7
7
|
|
8
8
|
import { Image } from "./image.js";
|
9
9
|
import { EBook } from "./ebook.js";
|
10
10
|
|
11
11
|
class Images {
|
12
12
|
|
13
|
+
#taxa;
|
13
14
|
#contentDir;
|
14
15
|
#images = {};
|
15
16
|
|
16
|
-
constructor( contentDir ) {
|
17
|
+
constructor( contentDir, taxa ) {
|
17
18
|
this.#contentDir = contentDir;
|
19
|
+
this.#taxa = taxa;
|
18
20
|
}
|
19
21
|
|
20
22
|
async createImages() {
|
@@ -29,7 +31,7 @@ class Images {
|
|
29
31
|
for ( const row of rows ) {
|
30
32
|
|
31
33
|
const name = row[ "taxon_name" ];
|
32
|
-
const taxon =
|
34
|
+
const taxon = this.#taxa.getTaxon( name );
|
33
35
|
if ( !taxon ) {
|
34
36
|
continue;
|
35
37
|
}
|
@@ -2,16 +2,15 @@ import { EBookPage } from "../ebookpage.js";
|
|
2
2
|
import { XHTML } from "../xhtml.js";
|
3
3
|
import { DateUtils } from "../../dateutils.js";
|
4
4
|
import { EBook } from "../ebook.js";
|
5
|
-
import { Taxa } from "../../taxa.js";
|
6
5
|
|
7
6
|
const FN_FLOWER_TIME_INDEX = "fm.html";
|
8
7
|
|
9
8
|
class PageListFlowers {
|
10
9
|
|
11
|
-
static createPages( contentDir ) {
|
10
|
+
static createPages( contentDir, taxa ) {
|
12
11
|
new PageListFlowerTimeIndex( contentDir ).create();
|
13
12
|
for ( let m1 = 1; m1 < 13; m1++ ) {
|
14
|
-
new PageListFlowerTime( contentDir, m1 ).create();
|
13
|
+
new PageListFlowerTime( contentDir, taxa, m1 ).create();
|
15
14
|
}
|
16
15
|
}
|
17
16
|
|
@@ -70,14 +69,16 @@ class PageListFlowerTimeIndex extends EBookPage {
|
|
70
69
|
|
71
70
|
class PageListFlowerTime extends EBookPage {
|
72
71
|
|
72
|
+
#taxa;
|
73
73
|
#m1;
|
74
74
|
#m2;
|
75
75
|
|
76
|
-
constructor( outputDir, month ) {
|
76
|
+
constructor( outputDir, taxa, month ) {
|
77
77
|
super(
|
78
78
|
outputDir + "/" + PageListFlowerTime.getFileNameBloomTime( month ),
|
79
79
|
"Flowering in " + DateUtils.getMonthName( month ) + " - " + DateUtils.getMonthName( month % 12 + 1 )
|
80
80
|
);
|
81
|
+
this.#taxa = taxa;
|
81
82
|
this.#m1 = month;
|
82
83
|
this.#m2 = month % 12 + 1;
|
83
84
|
}
|
@@ -92,7 +93,7 @@ class PageListFlowerTime extends EBookPage {
|
|
92
93
|
|
93
94
|
const range = [ this.#m1, this.#m2 ];
|
94
95
|
const links = [];
|
95
|
-
for ( const taxon of
|
96
|
+
for ( const taxon of this.#taxa.getTaxa() ) {
|
96
97
|
const m1 = taxon.getBloomStart();
|
97
98
|
const m2 = taxon.getBloomEnd();
|
98
99
|
if ( m1 && DateUtils.monthRangesOverlap( range, [ m1, m2 ] ) ) {
|
package/lib/ebook/plantbook.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
import { Families
|
1
|
+
import { Families } from "@ca-plant-list/ca-plant-list";
|
2
2
|
import { EBook } from "./ebook.js";
|
3
3
|
import { GlossaryPages } from "./glossarypages.js";
|
4
4
|
import { Images } from "./images.js";
|
@@ -13,10 +13,11 @@ import { FLOWER_COLOR_NAMES } from "../taxa.js";
|
|
13
13
|
|
14
14
|
class PlantBook extends EBook {
|
15
15
|
|
16
|
+
#taxa;
|
16
17
|
#glossary;
|
17
18
|
#images;
|
18
19
|
|
19
|
-
constructor() {
|
20
|
+
constructor( taxa ) {
|
20
21
|
|
21
22
|
super(
|
22
23
|
"output",
|
@@ -25,8 +26,9 @@ class PlantBook extends EBook {
|
|
25
26
|
Config.getConfigValue( "ebook", "title" )
|
26
27
|
);
|
27
28
|
|
29
|
+
this.#taxa = taxa;
|
28
30
|
this.#glossary = new GlossaryPages();
|
29
|
-
this.#images = new Images( this.getContentDir() );
|
31
|
+
this.#images = new Images( this.getContentDir(), taxa );
|
30
32
|
|
31
33
|
}
|
32
34
|
|
@@ -35,18 +37,18 @@ class PlantBook extends EBook {
|
|
35
37
|
const contentDir = this.getContentDir();
|
36
38
|
|
37
39
|
console.log( "creating taxon pages" );
|
38
|
-
const
|
39
|
-
for ( const taxon of
|
40
|
+
const taxonList = this.#taxa.getTaxa();
|
41
|
+
for ( const taxon of taxonList ) {
|
40
42
|
const name = taxon.getName();
|
41
43
|
new TaxonPage( contentDir, taxon, this.#images[ name ] ).create();
|
42
44
|
}
|
43
45
|
|
44
46
|
// Create lists.
|
45
47
|
for ( const colorName of FLOWER_COLOR_NAMES ) {
|
46
|
-
new PageListFlowerColor( contentDir,
|
48
|
+
new PageListFlowerColor( contentDir, this.#taxa.getFlowerColor( colorName ) ).create();
|
47
49
|
}
|
48
50
|
|
49
|
-
PageListFlowers.createPages( contentDir );
|
51
|
+
PageListFlowers.createPages( contentDir, this.#taxa );
|
50
52
|
|
51
53
|
new PageListFamilies( contentDir ).create();
|
52
54
|
for ( const family of Families.getFamilies() ) {
|
@@ -57,7 +59,7 @@ class PlantBook extends EBook {
|
|
57
59
|
const name = family.getName();
|
58
60
|
new PageListSpecies( contentDir, taxa, name + ".html", name ).create();
|
59
61
|
}
|
60
|
-
new PageListSpecies( contentDir,
|
62
|
+
new PageListSpecies( contentDir, taxonList, "list_species.html", "All Species" ).create();
|
61
63
|
|
62
64
|
await this.#images.createImages( contentDir );
|
63
65
|
this.#glossary.createPages( contentDir );
|
@@ -73,7 +75,7 @@ class PlantBook extends EBook {
|
|
73
75
|
xml += "<item id=\"lspecies\" href=\"list_species.html\" media-type=\"application/xhtml+xml\" />";
|
74
76
|
xml += "<item id=\"lfamilies\" href=\"list_families.html\" media-type=\"application/xhtml+xml\" />";
|
75
77
|
for ( const colorName of FLOWER_COLOR_NAMES ) {
|
76
|
-
const color =
|
78
|
+
const color = this.#taxa.getFlowerColor( colorName );
|
77
79
|
xml += "<item id=\"l" + color.getColorName() + "\" href=\"" + color.getFileName() + "\" media-type=\"application/xhtml+xml\" />";
|
78
80
|
}
|
79
81
|
|
@@ -87,7 +89,7 @@ class PlantBook extends EBook {
|
|
87
89
|
}
|
88
90
|
|
89
91
|
// Add taxon pages.
|
90
|
-
const taxa =
|
92
|
+
const taxa = this.#taxa.getTaxa();
|
91
93
|
for ( let index = 0; index < taxa.length; index++ ) {
|
92
94
|
const taxon = taxa[ index ];
|
93
95
|
xml += "<item id=\"t" + index + "\" href=\"" + taxon.getFileName() + "\" media-type=\"application/xhtml+xml\" />";
|
@@ -105,7 +107,7 @@ class PlantBook extends EBook {
|
|
105
107
|
|
106
108
|
// Add lists.
|
107
109
|
for ( const colorName of FLOWER_COLOR_NAMES ) {
|
108
|
-
const color =
|
110
|
+
const color = this.#taxa.getFlowerColor( colorName );
|
109
111
|
xml += "<itemref idref=\"l" + color.getColorName() + "\"/>";
|
110
112
|
}
|
111
113
|
xml += PageListFlowers.getSpineEntries();
|
@@ -123,7 +125,7 @@ class PlantBook extends EBook {
|
|
123
125
|
}
|
124
126
|
|
125
127
|
// Add taxa.
|
126
|
-
for ( let index = 0; index <
|
128
|
+
for ( let index = 0; index < this.#taxa.getTaxa().length; index++ ) {
|
127
129
|
xml += "<itemref idref=\"t" + index + "\"/>";
|
128
130
|
}
|
129
131
|
|
package/lib/exceptions.js
CHANGED
@@ -3,13 +3,30 @@ import { Files } from "./files.js";
|
|
3
3
|
|
4
4
|
class Exceptions {
|
5
5
|
|
6
|
-
|
6
|
+
#exceptions = {};
|
7
7
|
|
8
|
-
|
8
|
+
constructor( dir ) {
|
9
|
+
|
10
|
+
function readConfig( fileName ) {
|
11
|
+
return JSON.parse( Files.read( fileName ) );
|
12
|
+
}
|
13
|
+
|
14
|
+
// Read default configuration.
|
15
|
+
this.#exceptions = readConfig( Config.getPackageDir() + "/data/exceptions.json" );
|
16
|
+
|
17
|
+
// Add/overwrite with local configuration.
|
18
|
+
const localExceptions = readConfig( dir + "/exceptions.json" );
|
19
|
+
for ( const [ k, v ] of Object.entries( localExceptions ) ) {
|
20
|
+
this.#exceptions[ k ] = v;
|
21
|
+
}
|
22
|
+
|
23
|
+
}
|
24
|
+
|
25
|
+
getExceptions() {
|
9
26
|
return Object.entries( this.#exceptions );
|
10
27
|
}
|
11
28
|
|
12
|
-
|
29
|
+
getValue( name, cat, subcat, defaultValue ) {
|
13
30
|
const taxonData = this.#exceptions[ name ];
|
14
31
|
if ( taxonData ) {
|
15
32
|
const catData = taxonData[ cat ];
|
@@ -21,7 +38,7 @@ class Exceptions {
|
|
21
38
|
return defaultValue;
|
22
39
|
}
|
23
40
|
|
24
|
-
|
41
|
+
hasException( name, cat, subcat ) {
|
25
42
|
const taxonData = this.#exceptions[ name ];
|
26
43
|
if ( taxonData ) {
|
27
44
|
const catData = taxonData[ cat ];
|
@@ -32,23 +49,6 @@ class Exceptions {
|
|
32
49
|
return false;
|
33
50
|
}
|
34
51
|
|
35
|
-
static init( dir ) {
|
36
|
-
|
37
|
-
function readConfig( fileName ) {
|
38
|
-
return JSON.parse( Files.read( fileName ) );
|
39
|
-
}
|
40
|
-
|
41
|
-
// Read default configuration.
|
42
|
-
this.#exceptions = readConfig( Config.getPackageDir() + "/data/exceptions.json" );
|
43
|
-
|
44
|
-
// Add/overwrite with local configuration.
|
45
|
-
const localExceptions = readConfig( dir + "/exceptions.json" );
|
46
|
-
for ( const [ k, v ] of Object.entries( localExceptions ) ) {
|
47
|
-
this.#exceptions[ k ] = v;
|
48
|
-
}
|
49
|
-
|
50
|
-
}
|
51
|
-
|
52
52
|
}
|
53
53
|
|
54
54
|
export { Exceptions };
|
package/lib/families.js
CHANGED
@@ -4,21 +4,56 @@ import { Jepson } from "./jepson.js";
|
|
4
4
|
import { Taxa } from "./taxa.js";
|
5
5
|
import { Files } from "./files.js";
|
6
6
|
import { Config } from "./config.js";
|
7
|
-
import { Genera } from "./genera.js";
|
8
7
|
|
9
|
-
class
|
8
|
+
class Family {
|
10
9
|
|
11
|
-
|
10
|
+
#name;
|
11
|
+
#data;
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
constructor( name, data ) {
|
14
|
+
this.#name = name;
|
15
|
+
this.#data = data;
|
15
16
|
}
|
16
17
|
|
17
|
-
|
18
|
-
|
18
|
+
addTaxon( taxon ) {
|
19
|
+
if ( !this.#data.taxa ) {
|
20
|
+
this.#data.taxa = [];
|
21
|
+
}
|
22
|
+
this.#data.taxa.push( taxon );
|
23
|
+
Sections.addTaxon( this.getSectionName(), taxon );
|
24
|
+
}
|
25
|
+
|
26
|
+
getBaseFileName() {
|
27
|
+
return this.getName();
|
28
|
+
}
|
29
|
+
|
30
|
+
getFileName( ext = "html" ) {
|
31
|
+
return this.getBaseFileName() + "." + ext;
|
19
32
|
}
|
20
33
|
|
21
|
-
|
34
|
+
getJepsonID() {
|
35
|
+
return this.#data.id;
|
36
|
+
}
|
37
|
+
|
38
|
+
getName() {
|
39
|
+
return this.#name;
|
40
|
+
}
|
41
|
+
|
42
|
+
getSectionName() {
|
43
|
+
return this.#data.section;
|
44
|
+
}
|
45
|
+
|
46
|
+
getTaxa() {
|
47
|
+
return this.#data.taxa;
|
48
|
+
}
|
49
|
+
|
50
|
+
}
|
51
|
+
|
52
|
+
class Families {
|
53
|
+
|
54
|
+
static #families;
|
55
|
+
|
56
|
+
static {
|
22
57
|
|
23
58
|
const dataDir = Config.getPackageDir() + "/data";
|
24
59
|
|
@@ -27,8 +62,14 @@ class Families {
|
|
27
62
|
this.#families[ k ] = new Family( k, v );
|
28
63
|
}
|
29
64
|
|
30
|
-
|
65
|
+
}
|
31
66
|
|
67
|
+
static getFamilies() {
|
68
|
+
return Object.values( this.#families ).sort( ( a, b ) => a.getName().localeCompare( b.getName() ) );
|
69
|
+
}
|
70
|
+
|
71
|
+
static getFamily( familyName ) {
|
72
|
+
return this.#families[ familyName ];
|
32
73
|
}
|
33
74
|
|
34
75
|
static renderPages( outputDir, taxaColumns ) {
|
@@ -145,50 +186,6 @@ class PageSection extends GenericPage {
|
|
145
186
|
}
|
146
187
|
}
|
147
188
|
|
148
|
-
class Family {
|
149
|
-
|
150
|
-
#name;
|
151
|
-
#data;
|
152
|
-
|
153
|
-
constructor( name, data ) {
|
154
|
-
this.#name = name;
|
155
|
-
this.#data = data;
|
156
|
-
}
|
157
|
-
|
158
|
-
addTaxon( taxon ) {
|
159
|
-
if ( !this.#data.taxa ) {
|
160
|
-
this.#data.taxa = [];
|
161
|
-
}
|
162
|
-
this.#data.taxa.push( taxon );
|
163
|
-
Sections.addTaxon( this.getSectionName(), taxon );
|
164
|
-
}
|
165
|
-
|
166
|
-
getBaseFileName() {
|
167
|
-
return this.getName();
|
168
|
-
}
|
169
|
-
|
170
|
-
getFileName( ext = "html" ) {
|
171
|
-
return this.getBaseFileName() + "." + ext;
|
172
|
-
}
|
173
|
-
|
174
|
-
getJepsonID() {
|
175
|
-
return this.#data.id;
|
176
|
-
}
|
177
|
-
|
178
|
-
getName() {
|
179
|
-
return this.#name;
|
180
|
-
}
|
181
|
-
|
182
|
-
getSectionName() {
|
183
|
-
return this.#data.section;
|
184
|
-
}
|
185
|
-
|
186
|
-
getTaxa() {
|
187
|
-
return this.#data.taxa;
|
188
|
-
}
|
189
|
-
|
190
|
-
}
|
191
|
-
|
192
189
|
class Sections {
|
193
190
|
|
194
191
|
static #sections = {};
|
package/lib/genera.js
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
import { Config } from "./config.js";
|
1
2
|
import { Families } from "./families.js";
|
2
3
|
import { Files } from "./files.js";
|
3
4
|
|
@@ -5,6 +6,11 @@ class Genera {
|
|
5
6
|
|
6
7
|
static #genera;
|
7
8
|
|
9
|
+
static {
|
10
|
+
const dataDir = Config.getPackageDir() + "/data";
|
11
|
+
this.#genera = JSON.parse( Files.read( dataDir + "/genera.json" ) );
|
12
|
+
}
|
13
|
+
|
8
14
|
static addTaxon( taxon ) {
|
9
15
|
|
10
16
|
const genusName = taxon.getGenusName();
|
@@ -38,10 +44,6 @@ class Genera {
|
|
38
44
|
}
|
39
45
|
}
|
40
46
|
|
41
|
-
static init( dataDir ) {
|
42
|
-
this.#genera = JSON.parse( Files.read( dataDir + "/genera.json" ) );
|
43
|
-
}
|
44
|
-
|
45
47
|
}
|
46
48
|
|
47
49
|
class Genus {
|
package/lib/index.d.ts
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
export class BasePageRenderer {
|
2
|
-
static render(outputDir: any,
|
3
|
-
static renderTools(outputDir: any,
|
2
|
+
static render(outputDir: any, taxa: any, familyCols: any): void;
|
3
|
+
static renderTools(outputDir: any, taxa: any): void;
|
4
4
|
}
|
5
5
|
export class Config {
|
6
6
|
static "__#1@#config": {};
|
@@ -24,9 +24,9 @@ export class DataLoader {
|
|
24
24
|
type: StringConstructor;
|
25
25
|
defaultValue: string;
|
26
26
|
}[];
|
27
|
-
static
|
28
|
-
static load(options: any): void;
|
27
|
+
static load(options: any): Taxa;
|
29
28
|
}
|
29
|
+
import { Taxa } from "./taxa.js";
|
30
30
|
export class DateUtils {
|
31
31
|
static getMonthName(monthNum: any): string;
|
32
32
|
static monthRangesOverlap(r1: any, r2: any): any;
|
@@ -37,17 +37,16 @@ export class ErrorLog {
|
|
37
37
|
static write(fileName: any): void;
|
38
38
|
}
|
39
39
|
export class Exceptions {
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
40
|
+
constructor(dir: any);
|
41
|
+
getExceptions(): [string, any][];
|
42
|
+
getValue(name: any, cat: any, subcat: any, defaultValue: any): any;
|
43
|
+
hasException(name: any, cat: any, subcat: any): boolean;
|
44
|
+
#private;
|
45
45
|
}
|
46
46
|
export class Families {
|
47
|
-
static "__#
|
47
|
+
static "__#13@#families": any;
|
48
48
|
static getFamilies(): any[];
|
49
49
|
static getFamily(familyName: any): any;
|
50
|
-
static init(): void;
|
51
50
|
static renderPages(outputDir: any, taxaColumns: any): void;
|
52
51
|
}
|
53
52
|
export class Files {
|
@@ -75,7 +74,6 @@ export class Genera {
|
|
75
74
|
static addTaxon(taxon: any): void;
|
76
75
|
static getGenus(genusName: any): Genus;
|
77
76
|
static getFamily(genusName: any): any;
|
78
|
-
static init(dataDir: any): void;
|
79
77
|
}
|
80
78
|
declare class Genus {
|
81
79
|
constructor(data: any);
|
@@ -170,19 +168,15 @@ export class RarePlants {
|
|
170
168
|
}
|
171
169
|
export const FLOWER_COLOR_NAMES: string[];
|
172
170
|
export class Taxa {
|
173
|
-
static "__#11@#taxa": {};
|
174
|
-
static "__#11@#flower_colors": {};
|
175
|
-
static "__#11@#sortedTaxa": any;
|
176
171
|
static getHTMLTable(taxa: any, columns?: {
|
177
172
|
title: string;
|
178
173
|
data: (t: any) => any;
|
179
174
|
}[]): string;
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
static "__#11@#loadTaxa"(taxaCSV: any, inclusionList: any, taxaMeta: any, taxonClass: any): void;
|
175
|
+
constructor(inclusionList: any, taxaMeta?: {}, taxonClass?: typeof Taxon, extraTaxa?: any[], extraSynonyms?: any[]);
|
176
|
+
getFlowerColor(name: any): any;
|
177
|
+
getTaxa(): any[];
|
178
|
+
getTaxon(name: any): any;
|
179
|
+
#private;
|
186
180
|
}
|
187
181
|
export namespace TAXA_LIST_COLS {
|
188
182
|
namespace CESA {
|
package/lib/pagerenderer.js
CHANGED
@@ -11,37 +11,37 @@ const RPI_COLUMNS = [ TAXA_LIST_COLS.SPECIES_BARE, TAXA_LIST_COLS.COMMON_NAME, T
|
|
11
11
|
|
12
12
|
class PageRenderer extends BasePageRenderer {
|
13
13
|
|
14
|
-
static render( outputDir ) {
|
14
|
+
static render( outputDir, taxa ) {
|
15
15
|
|
16
|
-
super.render( outputDir,
|
16
|
+
super.render( outputDir, taxa );
|
17
17
|
|
18
|
-
this.renderLists( outputDir );
|
18
|
+
this.renderLists( outputDir, taxa );
|
19
19
|
|
20
|
-
const
|
21
|
-
for ( const taxon of
|
20
|
+
const taxonList = taxa.getTaxa();
|
21
|
+
for ( const taxon of taxonList ) {
|
22
22
|
new PageTaxon( outputDir, taxon ).render();
|
23
23
|
}
|
24
24
|
|
25
25
|
}
|
26
26
|
|
27
|
-
static renderLists( outputDir ) {
|
27
|
+
static renderLists( outputDir, taxa ) {
|
28
28
|
|
29
29
|
function getListArray( listInfo, attributes = {}, columns ) {
|
30
30
|
|
31
31
|
const listArray = [];
|
32
32
|
for ( const list of listInfo ) {
|
33
|
-
const
|
33
|
+
const listTaxa = [];
|
34
34
|
const calfloraTaxa = [];
|
35
35
|
const iNatTaxa = [];
|
36
|
-
for ( const taxon of
|
36
|
+
for ( const taxon of taxa.getTaxa() ) {
|
37
37
|
if ( list.include( taxon ) ) {
|
38
|
-
|
38
|
+
listTaxa.push( taxon );
|
39
39
|
calfloraTaxa.push( taxon.getCalfloraName() );
|
40
40
|
iNatTaxa.push( taxon.getINatName() );
|
41
41
|
}
|
42
42
|
}
|
43
43
|
|
44
|
-
if (
|
44
|
+
if ( listTaxa.length === 0 ) {
|
45
45
|
continue;
|
46
46
|
}
|
47
47
|
|
@@ -49,12 +49,12 @@ class PageRenderer extends BasePageRenderer {
|
|
49
49
|
Files.write( outputDir + "/inat_" + list.filename + ".txt", iNatTaxa.join( "\n" ) );
|
50
50
|
|
51
51
|
const cols = columns ? columns : list.columns;
|
52
|
-
new PageTaxonList( outputDir, list.name, list.filename ).render(
|
52
|
+
new PageTaxonList( outputDir, list.name, list.filename ).render( listTaxa, cols );
|
53
53
|
|
54
54
|
// Check for sublists.
|
55
55
|
const subListHTML = list.listInfo ? getListArray( list.listInfo, { class: "indent" }, cols ) : "";
|
56
56
|
|
57
|
-
listArray.push( HTML.getLink( "./" + list.filename + ".html", list.name ) + " (" +
|
57
|
+
listArray.push( HTML.getLink( "./" + list.filename + ".html", list.name ) + " (" + listTaxa.length + ")" + subListHTML );
|
58
58
|
}
|
59
59
|
|
60
60
|
return renderList( listArray, attributes );
|
package/lib/taxa.js
CHANGED
@@ -65,14 +65,34 @@ class FlowerColor {
|
|
65
65
|
|
66
66
|
class Taxa {
|
67
67
|
|
68
|
-
|
69
|
-
|
70
|
-
|
68
|
+
#taxa = {};
|
69
|
+
#flower_colors = {};
|
70
|
+
#sortedTaxa;
|
71
71
|
|
72
|
-
|
72
|
+
constructor( inclusionList, taxaMeta = {}, taxonClass = Taxon, extraTaxa = [], extraSynonyms = [] ) {
|
73
73
|
for ( const color of FLOWER_COLOR_NAMES ) {
|
74
74
|
this.#flower_colors[ color ] = new FlowerColor( color );
|
75
75
|
}
|
76
|
+
|
77
|
+
const dataDir = Config.getPackageDir() + "/data";
|
78
|
+
|
79
|
+
const taxaCSV = CSV.parseFile( dataDir, "taxa.csv" );
|
80
|
+
this.#loadTaxa( taxaCSV, inclusionList, taxaMeta, taxonClass );
|
81
|
+
this.#loadTaxa( extraTaxa, inclusionList, taxaMeta, taxonClass );
|
82
|
+
|
83
|
+
// Make sure everything in the inclusionList has been loaded.
|
84
|
+
for ( const name of Object.keys( inclusionList ) ) {
|
85
|
+
if ( !this.getTaxon( name ) ) {
|
86
|
+
ErrorLog.log( name, "not found in taxon list" );
|
87
|
+
}
|
88
|
+
}
|
89
|
+
|
90
|
+
this.#sortedTaxa = Object.values( this.#taxa ).sort( ( a, b ) => a.getName().localeCompare( b.getName() ) );
|
91
|
+
|
92
|
+
const synCSV = CSV.parseFile( dataDir, "synonyms.csv" );
|
93
|
+
this.#loadSyns( synCSV, inclusionList );
|
94
|
+
this.#loadSyns( extraSynonyms, inclusionList );
|
95
|
+
|
76
96
|
}
|
77
97
|
|
78
98
|
static getHTMLTable( taxa, columns = DEFAULT_COLUMNS ) {
|
@@ -103,42 +123,19 @@ class Taxa {
|
|
103
123
|
return html;
|
104
124
|
}
|
105
125
|
|
106
|
-
|
126
|
+
getFlowerColor( name ) {
|
107
127
|
return this.#flower_colors[ name ];
|
108
128
|
}
|
109
129
|
|
110
|
-
|
130
|
+
getTaxa() {
|
111
131
|
return this.#sortedTaxa;
|
112
132
|
}
|
113
133
|
|
114
|
-
|
134
|
+
getTaxon( name ) {
|
115
135
|
return this.#taxa[ name ];
|
116
136
|
}
|
117
137
|
|
118
|
-
|
119
|
-
|
120
|
-
const dataDir = Config.getPackageDir() + "/data";
|
121
|
-
|
122
|
-
const taxaCSV = CSV.parseFile( dataDir, "taxa.csv" );
|
123
|
-
this.#loadTaxa( taxaCSV, inclusionList, taxaMeta, taxonClass );
|
124
|
-
this.#loadTaxa( extraTaxa, inclusionList, taxaMeta, taxonClass );
|
125
|
-
|
126
|
-
// Make sure everything in the inclusionList has been loaded.
|
127
|
-
for ( const name of Object.keys( inclusionList ) ) {
|
128
|
-
if ( !this.getTaxon( name ) ) {
|
129
|
-
ErrorLog.log( name, "not found in taxon list" );
|
130
|
-
}
|
131
|
-
}
|
132
|
-
|
133
|
-
this.#sortedTaxa = Object.values( this.#taxa ).sort( ( a, b ) => a.getName().localeCompare( b.getName() ) );
|
134
|
-
|
135
|
-
const synCSV = CSV.parseFile( dataDir, "synonyms.csv" );
|
136
|
-
this.#loadSyns( synCSV, inclusionList );
|
137
|
-
this.#loadSyns( extraSynonyms, inclusionList );
|
138
|
-
|
139
|
-
}
|
140
|
-
|
141
|
-
static #loadSyns( synCSV, inclusionList ) {
|
138
|
+
#loadSyns( synCSV, inclusionList ) {
|
142
139
|
for ( const syn of synCSV ) {
|
143
140
|
const currName = syn[ "Current" ];
|
144
141
|
const taxon = this.getTaxon( currName );
|
@@ -153,7 +150,7 @@ class Taxa {
|
|
153
150
|
}
|
154
151
|
}
|
155
152
|
|
156
|
-
|
153
|
+
#loadTaxa( taxaCSV, inclusionList, taxaMeta, taxonClass ) {
|
157
154
|
for ( const row of taxaCSV ) {
|
158
155
|
|
159
156
|
const name = row[ "taxon_name" ];
|
package/package.json
CHANGED
package/scripts/build-ebook.js
CHANGED
@@ -6,7 +6,5 @@ import { DataLoader } from "../lib/dataloader.js";
|
|
6
6
|
|
7
7
|
const options = commandLineArgs( DataLoader.getOptionDefs() );
|
8
8
|
|
9
|
-
DataLoader.load( options );
|
10
|
-
|
11
|
-
const ebook = new PlantBook();
|
9
|
+
const ebook = new PlantBook( DataLoader.load( options ) );
|
12
10
|
await ebook.create();
|
package/scripts/build-site.js
CHANGED
@@ -9,7 +9,6 @@ const options = commandLineArgs( DataLoader.getOptionDefs() );
|
|
9
9
|
|
10
10
|
const OUTPUT_DIR = "./output";
|
11
11
|
|
12
|
-
DataLoader.load( options );
|
13
|
-
PageRenderer.render( OUTPUT_DIR );
|
12
|
+
PageRenderer.render( OUTPUT_DIR, DataLoader.load( options ) );
|
14
13
|
|
15
14
|
ErrorLog.write( OUTPUT_DIR + "/errors.tsv" );
|