@ca-plant-list/ca-plant-list 0.0.1 → 0.1.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/LICENSE +21 -0
- package/README.md +1 -1
- package/build-site.js +12 -8
- package/jekyll/_includes/menu_extra.html +0 -0
- package/jekyll/_layouts/html.html +1 -0
- package/jekyll/assets/css/main.css +23 -2
- package/lib/config.js +7 -0
- package/lib/dataloader.js +9 -3
- package/lib/exceptions.js +28 -0
- package/lib/html.js +4 -1
- package/lib/pagerenderer.js +108 -23
- package/lib/pagetaxon.js +14 -10
- package/lib/rpi.js +30 -0
- package/lib/taxa.js +10 -2
- package/lib/taxon.js +31 -5
- package/package.json +21 -1
package/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2022 ca-plant-list
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
@@ -1 +1 @@
|
|
1
|
-
This module contains tools for producing Jekyll files to create a set of static HTML pages with information about plants growing in the
|
1
|
+
This module contains tools for producing Jekyll files to create a set of static HTML pages with information about plants growing in the wild in areas of California.
|
package/build-site.js
CHANGED
@@ -1,19 +1,23 @@
|
|
1
1
|
#!/usr/bin/env node
|
2
2
|
|
3
|
-
import * as path from "node:path";
|
4
|
-
import * as url from "node:url";
|
5
3
|
import { Config } from "./lib/config.js";
|
6
4
|
import { DataLoader } from "./lib/dataloader.js";
|
7
5
|
import { ErrorLog } from "./lib/errorlog.js";
|
8
6
|
import { PageRenderer } from "./lib/pagerenderer.js";
|
7
|
+
import commandLineArgs from "command-line-args";
|
9
8
|
|
10
|
-
const
|
11
|
-
|
12
|
-
|
9
|
+
const OPTION_DEFS = [
|
10
|
+
{ name: "data", type: String, defaultValue: "./data" },
|
11
|
+
];
|
12
|
+
|
13
|
+
const options = commandLineArgs( OPTION_DEFS );
|
14
|
+
|
15
|
+
const TAXA_DATA_DIR = options.data;
|
16
|
+
const CONFIG_DATA_DIR = "./data";
|
13
17
|
const OUTPUT_DIR = "./output";
|
14
18
|
|
15
|
-
Config.init(
|
16
|
-
DataLoader.load(
|
17
|
-
PageRenderer.render(
|
19
|
+
Config.init( CONFIG_DATA_DIR );
|
20
|
+
DataLoader.load( TAXA_DATA_DIR );
|
21
|
+
PageRenderer.render( OUTPUT_DIR );
|
18
22
|
|
19
23
|
ErrorLog.write( OUTPUT_DIR + "/errors.txt" );
|
File without changes
|
@@ -13,9 +13,19 @@
|
|
13
13
|
--bs-navbar-color: white;
|
14
14
|
--bs-navbar-brand-hover-color: rgba(255, 255, 255, .5);
|
15
15
|
--bs-navbar-brand-color: white;
|
16
|
+
--bs-navbar-nav-link-padding-x: 1rem;
|
16
17
|
background-color: #3D550C;
|
17
18
|
}
|
18
19
|
|
20
|
+
span[title] {
|
21
|
+
text-decoration: underline dotted;
|
22
|
+
}
|
23
|
+
|
24
|
+
span.label {
|
25
|
+
font-weight: 600;
|
26
|
+
padding-right: .5rem;
|
27
|
+
}
|
28
|
+
|
19
29
|
td {
|
20
30
|
border: solid 1px;
|
21
31
|
vertical-align: top;
|
@@ -27,9 +37,16 @@ th {
|
|
27
37
|
|
28
38
|
/* Lists */
|
29
39
|
|
30
|
-
|
40
|
+
span.native {
|
31
41
|
font-weight: bold;
|
32
|
-
|
42
|
+
}
|
43
|
+
|
44
|
+
span.rare {
|
45
|
+
font-weight: bold;
|
46
|
+
}
|
47
|
+
|
48
|
+
span.rare::before {
|
49
|
+
content: "\2606";
|
33
50
|
}
|
34
51
|
|
35
52
|
/* Taxon Page */
|
@@ -61,4 +78,8 @@ div.section ul {
|
|
61
78
|
|
62
79
|
div.section li {
|
63
80
|
display: block;
|
81
|
+
}
|
82
|
+
|
83
|
+
div.section ul.indent {
|
84
|
+
padding-left: 1rem;
|
64
85
|
}
|
package/lib/config.js
CHANGED
@@ -1,8 +1,11 @@
|
|
1
|
+
import * as path from "node:path";
|
2
|
+
import * as url from "node:url";
|
1
3
|
import * as fs from "node:fs";
|
2
4
|
|
3
5
|
class Config {
|
4
6
|
|
5
7
|
static #config = {};
|
8
|
+
static #packageDir = path.dirname( path.dirname( url.fileURLToPath( import.meta.url ) ) );
|
6
9
|
|
7
10
|
static getConfigValue( prefix, name, dflt ) {
|
8
11
|
const obj = this.#config[ prefix ];
|
@@ -18,6 +21,10 @@ class Config {
|
|
18
21
|
return this.getConfigValue( "labels", name, dflt );
|
19
22
|
}
|
20
23
|
|
24
|
+
static getPackageDir() {
|
25
|
+
return this.#packageDir;
|
26
|
+
}
|
27
|
+
|
21
28
|
static init( dir ) {
|
22
29
|
try {
|
23
30
|
this.#config = JSON.parse( fs.readFileSync( dir + "/config.json" ) );
|
package/lib/dataloader.js
CHANGED
@@ -1,15 +1,21 @@
|
|
1
1
|
import { Taxa } from "./taxa.js";
|
2
2
|
import { Genera } from "./genera.js";
|
3
3
|
import { Families } from "./families.js";
|
4
|
+
import { Config } from "./config.js";
|
5
|
+
import { Exceptions } from "./exceptions.js";
|
6
|
+
|
4
7
|
|
5
8
|
class DataLoader {
|
6
9
|
|
7
|
-
static load( taxaDir
|
10
|
+
static load( taxaDir ) {
|
11
|
+
|
12
|
+
const defaultDataDir = Config.getPackageDir() + "/data";
|
8
13
|
|
9
14
|
console.log( "loading data" );
|
10
15
|
|
11
|
-
|
12
|
-
|
16
|
+
Exceptions.init( taxaDir );
|
17
|
+
Families.init( defaultDataDir );
|
18
|
+
Genera.init( defaultDataDir );
|
13
19
|
Taxa.init( taxaDir );
|
14
20
|
|
15
21
|
}
|
@@ -0,0 +1,28 @@
|
|
1
|
+
import * as fs from "node:fs";
|
2
|
+
|
3
|
+
class Exceptions {
|
4
|
+
|
5
|
+
static #exceptions = {};
|
6
|
+
|
7
|
+
static hasException( name, cat, subcat ) {
|
8
|
+
const taxonData = this.#exceptions[ name ];
|
9
|
+
if ( taxonData ) {
|
10
|
+
const catData = taxonData[ cat ];
|
11
|
+
if ( catData ) {
|
12
|
+
return catData[ subcat ] !== undefined;
|
13
|
+
}
|
14
|
+
}
|
15
|
+
return false;
|
16
|
+
}
|
17
|
+
|
18
|
+
static init( dir ) {
|
19
|
+
try {
|
20
|
+
this.#exceptions = JSON.parse( fs.readFileSync( dir + "/exceptions.json" ) );
|
21
|
+
} catch ( e ) {
|
22
|
+
console.log( e );
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
26
|
+
}
|
27
|
+
|
28
|
+
export { Exceptions };
|
package/lib/html.js
CHANGED
@@ -29,7 +29,10 @@ class HTML {
|
|
29
29
|
}
|
30
30
|
|
31
31
|
static getLink( href, linkText, attributes = {}, options = 0 ) {
|
32
|
-
let html = "<a
|
32
|
+
let html = "<a";
|
33
|
+
if ( href !== undefined ) {
|
34
|
+
html += this.renderAttribute( "href", href );
|
35
|
+
}
|
33
36
|
html += this.renderAttributes( attributes );
|
34
37
|
if ( options & HTML_OPTIONS.OPEN_NEW ) {
|
35
38
|
html += this.renderAttribute( "target", "_blank" );
|
package/lib/pagerenderer.js
CHANGED
@@ -1,19 +1,20 @@
|
|
1
1
|
import * as fs from "node:fs";
|
2
2
|
import { Families } from "./families.js";
|
3
|
-
import { HTML } from "./html.js";
|
3
|
+
import { HTML, HTML_OPTIONS } from "./html.js";
|
4
4
|
import { Taxa } from "./taxa.js";
|
5
5
|
import { HTMLPage } from "./htmlpage.js";
|
6
6
|
import { PageTaxon } from "./pagetaxon.js";
|
7
7
|
import { Config } from "./config.js";
|
8
|
+
import { RPI } from "./rpi.js";
|
8
9
|
|
9
10
|
class PageRenderer {
|
10
11
|
|
11
|
-
static render(
|
12
|
+
static render( outputDir ) {
|
12
13
|
|
13
14
|
// Copy static files
|
14
15
|
fs.rmSync( outputDir, { force: true, recursive: true } );
|
15
16
|
// First copy default Jekyll files from package.
|
16
|
-
fs.cpSync(
|
17
|
+
fs.cpSync( Config.getPackageDir() + "/jekyll", outputDir, { recursive: true } );
|
17
18
|
// Then copy Jekyll files from current dir (which may override default files).
|
18
19
|
fs.cpSync( "jekyll", outputDir, { recursive: true } );
|
19
20
|
|
@@ -31,34 +32,118 @@ class PageRenderer {
|
|
31
32
|
|
32
33
|
static renderLists( outputDir ) {
|
33
34
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
35
|
+
function getListArray( listInfo, attributes = {} ) {
|
36
|
+
const listArray = [];
|
37
|
+
for ( const list of listInfo ) {
|
38
|
+
const taxa = [];
|
39
|
+
const calfloraTaxa = [];
|
40
|
+
const iNatTaxa = [];
|
41
|
+
for ( const taxon of Taxa.getTaxa() ) {
|
42
|
+
if ( list.include( taxon ) ) {
|
43
|
+
taxa.push( taxon );
|
44
|
+
calfloraTaxa.push( taxon.getCalfloraName() );
|
45
|
+
iNatTaxa.push( taxon.getINatName() );
|
46
|
+
}
|
47
|
+
}
|
39
48
|
|
40
|
-
|
41
|
-
|
42
|
-
const taxa = [];
|
43
|
-
const calfloraTaxa = [];
|
44
|
-
const iNatTaxa = [];
|
45
|
-
for ( const taxon of Taxa.getTaxa() ) {
|
46
|
-
if ( list.include( taxon ) ) {
|
47
|
-
taxa.push( taxon );
|
48
|
-
calfloraTaxa.push( taxon.getCalfloraName() );
|
49
|
-
iNatTaxa.push( taxon.getINatName() );
|
49
|
+
if ( taxa.length === 0 ) {
|
50
|
+
continue;
|
50
51
|
}
|
52
|
+
|
53
|
+
fs.writeFileSync( outputDir + "/calflora_" + list.filename + ".txt", calfloraTaxa.join( "\n" ) );
|
54
|
+
fs.writeFileSync( outputDir + "/inat_" + list.filename + ".txt", iNatTaxa.join( "\n" ) );
|
55
|
+
|
56
|
+
new PageTaxonList().render( outputDir, taxa, list.filename, list.name );
|
57
|
+
|
58
|
+
// Check for sublists.
|
59
|
+
const subListHTML = list.listInfo ? getListArray( list.listInfo, { class: "indent" } ) : "";
|
60
|
+
|
61
|
+
listArray.push( HTML.getLink( "./" + list.filename + ".html", list.name ) + " (" + taxa.length + ")" + subListHTML );
|
51
62
|
}
|
63
|
+
return renderList( listArray, attributes );
|
64
|
+
}
|
65
|
+
|
66
|
+
function renderList( listsHTML, attributes = {} ) {
|
67
|
+
return HTML.getElement( "ul", HTML.arrayToLI( listsHTML ), attributes, HTML_OPTIONS.NO_ESCAPE );
|
68
|
+
}
|
52
69
|
|
53
|
-
|
54
|
-
|
70
|
+
function renderSection( title, listsHTML ) {
|
71
|
+
let html = "<div class=\"section\">";
|
72
|
+
html += HTML.getElement( "h2", title );
|
73
|
+
html += listsHTML;
|
74
|
+
html += "</div>";
|
75
|
+
return html;
|
76
|
+
}
|
77
|
+
|
78
|
+
const sections = [
|
79
|
+
{
|
80
|
+
title: "All Species",
|
81
|
+
listInfo: [
|
82
|
+
{ name: Config.getLabel( "native", "Native" ), filename: "list_native", include: ( t ) => t.isNative() },
|
83
|
+
{ name: Config.getLabel( "introduced", "Introduced" ), filename: "list_introduced", include: ( t ) => !t.isNative() },
|
84
|
+
{ name: "All Plants", filename: "list_all", include: () => true },
|
85
|
+
]
|
86
|
+
},
|
87
|
+
{
|
88
|
+
title: "Rare Plants",
|
89
|
+
listInfo: [
|
90
|
+
{
|
91
|
+
name: "CNPS Ranked Plants",
|
92
|
+
filename: "list_rpi",
|
93
|
+
include: ( t ) => t.getRPIRank() !== undefined,
|
94
|
+
listInfo: [
|
95
|
+
{
|
96
|
+
name: RPI.getRankDescription( "1A" ),
|
97
|
+
filename: "list_rpi_1a",
|
98
|
+
include: ( t ) => t.getRPIRank() === "1A",
|
99
|
+
},
|
100
|
+
{
|
101
|
+
name: RPI.getRankDescription( "1B" ),
|
102
|
+
filename: "list_rpi_1b",
|
103
|
+
include: ( t ) => t.getRPIRank() === "1B",
|
104
|
+
},
|
105
|
+
{
|
106
|
+
name: RPI.getRankDescription( "2A" ),
|
107
|
+
filename: "list_rpi_2a",
|
108
|
+
include: ( t ) => t.getRPIRank() === "2A",
|
109
|
+
},
|
110
|
+
{
|
111
|
+
name: RPI.getRankDescription( "2B" ),
|
112
|
+
filename: "list_rpi_2b",
|
113
|
+
include: ( t ) => t.getRPIRank() === "2B",
|
114
|
+
},
|
115
|
+
{
|
116
|
+
name: RPI.getRankDescription( "3" ),
|
117
|
+
filename: "list_rpi_3",
|
118
|
+
include: ( t ) => t.getRPIRank() === "3",
|
119
|
+
},
|
120
|
+
{
|
121
|
+
name: RPI.getRankDescription( "4" ),
|
122
|
+
filename: "list_rpi_4",
|
123
|
+
include: ( t ) => t.getRPIRank() === "4",
|
124
|
+
},
|
125
|
+
]
|
126
|
+
},
|
127
|
+
]
|
128
|
+
},
|
129
|
+
];
|
130
|
+
|
131
|
+
let html = "<div class=\"wrapper\">";
|
132
|
+
for ( const section of sections ) {
|
133
|
+
|
134
|
+
const listHTML = getListArray( section.listInfo );
|
135
|
+
|
136
|
+
if ( listHTML.length > 0 ) {
|
137
|
+
html += renderSection( section.title, listHTML );
|
138
|
+
}
|
55
139
|
|
56
|
-
new PageTaxonList().render( outputDir, taxa, list.filename, list.name );
|
57
|
-
listsHTML.push( HTML.getLink( "./" + list.filename + ".html", list.name ) + " (" + taxa.length + ")" );
|
58
140
|
}
|
141
|
+
html += renderSection( "Taxonomy", renderList( [ HTML.getLink( "./list_families.html", "Plant Families" ) ] ) );
|
142
|
+
|
143
|
+
html += "</div>";
|
59
144
|
|
60
145
|
// Write lists to includes directory so it can be inserted into pages.
|
61
|
-
fs.writeFileSync( outputDir + "/_includes/plantlists.html",
|
146
|
+
fs.writeFileSync( outputDir + "/_includes/plantlists.html", html );
|
62
147
|
|
63
148
|
}
|
64
149
|
|
package/lib/pagetaxon.js
CHANGED
@@ -3,6 +3,7 @@ import { HTML, HTML_OPTIONS } from "./html.js";
|
|
3
3
|
import { Jepson } from "./jepson.js";
|
4
4
|
import { HTMLPage } from "./htmlpage.js";
|
5
5
|
import { Config } from "./config.js";
|
6
|
+
import { RPI } from "./rpi.js";
|
6
7
|
|
7
8
|
class PageTaxon extends HTMLPage {
|
8
9
|
|
@@ -91,15 +92,7 @@ class PageTaxon extends HTMLPage {
|
|
91
92
|
if ( genus ) {
|
92
93
|
const taxa = genus.getTaxa();
|
93
94
|
for ( const taxon of taxa ) {
|
94
|
-
|
95
|
-
links.push(
|
96
|
-
HTML.getLink(
|
97
|
-
"./" + taxon.getFileName(),
|
98
|
-
taxon.getName(),
|
99
|
-
{ class: taxon.getHTMLClassName() }
|
100
|
-
)
|
101
|
-
);
|
102
|
-
}
|
95
|
+
links.push( taxon.getHTMLLink( taxon.getName() !== this.#taxon.getName() ) );
|
103
96
|
}
|
104
97
|
}
|
105
98
|
return links;
|
@@ -126,11 +119,22 @@ class PageTaxon extends HTMLPage {
|
|
126
119
|
const family = this.#taxon.getFamily();
|
127
120
|
html += HTML.getElement(
|
128
121
|
"div",
|
129
|
-
"Family: " + HTML.getLink( "./" + family.getFileName(), family.getName() ),
|
122
|
+
HTML.getElement( "span", "Family:", { class: "label" } ) + HTML.getLink( "./" + family.getFileName(), family.getName() ),
|
130
123
|
{ class: "section" },
|
131
124
|
HTML_OPTIONS.NO_ESCAPE
|
132
125
|
);
|
133
126
|
|
127
|
+
const cnpsRank = this.#taxon.getRPIRankAndThreat();
|
128
|
+
if ( cnpsRank ) {
|
129
|
+
html += HTML.getElement(
|
130
|
+
"div",
|
131
|
+
HTML.getElement( "span", "CNPS Rare Plant Rank:", { class: "label" } )
|
132
|
+
+ HTML.getElement( "span", cnpsRank, { title: RPI.getRankAndThreatDescriptions( cnpsRank ).join( "\n" ) } ),
|
133
|
+
{ class: "section" },
|
134
|
+
HTML_OPTIONS.NO_ESCAPE
|
135
|
+
);
|
136
|
+
}
|
137
|
+
|
134
138
|
html += "</div>";
|
135
139
|
|
136
140
|
const introName = "intros/" + this.#taxon.getFileName( "md" );
|
package/lib/rpi.js
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
const RANK_DESCRIPS = {
|
2
|
+
"1A": "Presumed Extirpated or Extinct",
|
3
|
+
"1B": "Rare or Endangered",
|
4
|
+
"2A": "Extirpated in California",
|
5
|
+
"2B": "Rare or Endangered in California",
|
6
|
+
"3": "Needs Review",
|
7
|
+
"4": "Uncommon in California",
|
8
|
+
};
|
9
|
+
|
10
|
+
const THREAT_DESCRIPS = {
|
11
|
+
"1": "Seriously threatened in California",
|
12
|
+
"2": "Moderately threatened in California",
|
13
|
+
"3": "Not very threatened in California",
|
14
|
+
};
|
15
|
+
|
16
|
+
class RPI {
|
17
|
+
|
18
|
+
static getRankDescription( rank ) {
|
19
|
+
const pieces = rank.split( "." );
|
20
|
+
return RANK_DESCRIPS[ pieces[ 0 ] ];
|
21
|
+
}
|
22
|
+
|
23
|
+
static getRankAndThreatDescriptions( rank ) {
|
24
|
+
const pieces = rank.split( "." );
|
25
|
+
return [ RANK_DESCRIPS[ pieces[ 0 ] ], THREAT_DESCRIPS[ pieces[ 1 ] ] ];
|
26
|
+
}
|
27
|
+
|
28
|
+
}
|
29
|
+
|
30
|
+
export { RPI };
|
package/lib/taxa.js
CHANGED
@@ -19,7 +19,7 @@ class Taxa {
|
|
19
19
|
html += "<tr>";
|
20
20
|
html += HTML.getElement(
|
21
21
|
"td",
|
22
|
-
|
22
|
+
taxon.getHTMLLink(),
|
23
23
|
undefined,
|
24
24
|
HTML_OPTIONS.NO_ESCAPE
|
25
25
|
);
|
@@ -55,7 +55,15 @@ class Taxa {
|
|
55
55
|
ErrorLog.log( name, "has multiple entries" );
|
56
56
|
}
|
57
57
|
const commonName = row[ "common name" ];
|
58
|
-
this.#taxa[ name ] = new Taxon(
|
58
|
+
this.#taxa[ name ] = new Taxon(
|
59
|
+
name,
|
60
|
+
commonName,
|
61
|
+
status,
|
62
|
+
jepsonID,
|
63
|
+
row[ "calrecnum" ],
|
64
|
+
row[ "inat id" ],
|
65
|
+
row[ "CRPR" ]
|
66
|
+
);
|
59
67
|
if ( !jepsonID ) {
|
60
68
|
ErrorLog.log( name, "has no Jepson ID" );
|
61
69
|
}
|
package/lib/taxon.js
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
import { Config } from "./config.js";
|
2
2
|
import { ErrorLog } from "./errorlog.js";
|
3
3
|
import { Genera } from "./genera.js";
|
4
|
+
import { RPI } from "./rpi.js";
|
5
|
+
import { HTML, HTML_OPTIONS } from "./html.js";
|
4
6
|
|
5
7
|
class Taxon {
|
6
8
|
|
@@ -12,9 +14,10 @@ class Taxon {
|
|
12
14
|
#calRecNum;
|
13
15
|
#iNatID;
|
14
16
|
#iNatName;
|
17
|
+
#rankRPI;
|
15
18
|
#synonyms = [];
|
16
19
|
|
17
|
-
constructor( name, commonNames, status, jepsonID, calRecNum, iNatID ) {
|
20
|
+
constructor( name, commonNames, status, jepsonID, calRecNum, iNatID, rankRPI ) {
|
18
21
|
this.#name = name;
|
19
22
|
this.#genus = name.split( " " )[ 0 ];
|
20
23
|
this.#commonNames = commonNames ? commonNames.split( "," ).map( t => t.trim() ) : [];
|
@@ -22,6 +25,7 @@ class Taxon {
|
|
22
25
|
this.#jepsonID = jepsonID;
|
23
26
|
this.#calRecNum = calRecNum;
|
24
27
|
this.#iNatID = iNatID;
|
28
|
+
this.#rankRPI = rankRPI;
|
25
29
|
Genera.addTaxon( this );
|
26
30
|
if ( !calRecNum ) {
|
27
31
|
ErrorLog.log( this.getName(), "has no Calflora ID" );
|
@@ -63,14 +67,20 @@ class Taxon {
|
|
63
67
|
return Genera.getGenus( this.#genus );
|
64
68
|
}
|
65
69
|
|
66
|
-
getHTMLClassName() {
|
67
|
-
return this.isNative() ? "native" : "non-native";
|
68
|
-
}
|
69
|
-
|
70
70
|
getGenusName() {
|
71
71
|
return this.#genus;
|
72
72
|
}
|
73
73
|
|
74
|
+
getHTMLLink( href = true ) {
|
75
|
+
href = href ? ( "./" + this.getFileName() ) : undefined;
|
76
|
+
const className = this.isNative() ? ( this.isRare() ? "rare" : "native" ) : "non-native";
|
77
|
+
const attributes = { class: className };
|
78
|
+
if ( className === "rare" ) {
|
79
|
+
attributes[ "title" ] = RPI.getRankAndThreatDescriptions( this.getRPIRankAndThreat() ).join( "\n" );
|
80
|
+
}
|
81
|
+
return HTML.getElement( "span", HTML.getLink( href, this.getName() ), attributes, HTML_OPTIONS.NO_ESCAPE );
|
82
|
+
}
|
83
|
+
|
74
84
|
getINatID() {
|
75
85
|
return this.#iNatID;
|
76
86
|
}
|
@@ -88,6 +98,17 @@ class Taxon {
|
|
88
98
|
return this.#name;
|
89
99
|
}
|
90
100
|
|
101
|
+
getRPIRank() {
|
102
|
+
if ( !this.#rankRPI ) {
|
103
|
+
return this.#rankRPI;
|
104
|
+
}
|
105
|
+
return this.#rankRPI.split( "." )[ 0 ];
|
106
|
+
}
|
107
|
+
|
108
|
+
getRPIRankAndThreat() {
|
109
|
+
return this.#rankRPI;
|
110
|
+
}
|
111
|
+
|
91
112
|
getStatus() {
|
92
113
|
return this.#status;
|
93
114
|
}
|
@@ -103,6 +124,7 @@ class Taxon {
|
|
103
124
|
}
|
104
125
|
throw new Error( this.#status );
|
105
126
|
}
|
127
|
+
|
106
128
|
getSynonyms() {
|
107
129
|
return this.#synonyms;
|
108
130
|
}
|
@@ -111,6 +133,10 @@ class Taxon {
|
|
111
133
|
return this.#status === "N";
|
112
134
|
}
|
113
135
|
|
136
|
+
isRare() {
|
137
|
+
return this.getRPIRank() !== undefined;
|
138
|
+
}
|
139
|
+
|
114
140
|
}
|
115
141
|
|
116
142
|
export { Taxon };
|
package/package.json
CHANGED
@@ -1,13 +1,33 @@
|
|
1
1
|
{
|
2
2
|
"name": "@ca-plant-list/ca-plant-list",
|
3
|
-
"version": "0.0
|
3
|
+
"version": "0.1.0",
|
4
4
|
"description": "Tools to create Jekyll files for a website listing plants in an area of California.",
|
5
5
|
"license": "MIT",
|
6
|
+
"repository": {
|
7
|
+
"type": "git",
|
8
|
+
"url": "https://github.com/ca-plants/ca-plant-list.git"
|
9
|
+
},
|
10
|
+
"homepage": "https://github.com/ca-plants/ca-plant-list",
|
6
11
|
"type": "module",
|
12
|
+
"exports": {
|
13
|
+
"./CSV": {
|
14
|
+
"import": "./lib/csv.js"
|
15
|
+
},
|
16
|
+
"./DataLoader": {
|
17
|
+
"import": "./lib/dataloader.js"
|
18
|
+
},
|
19
|
+
"./Exceptions": {
|
20
|
+
"import": "./lib/exceptions.js"
|
21
|
+
},
|
22
|
+
"./Taxa": {
|
23
|
+
"import": "./lib/taxa.js"
|
24
|
+
}
|
25
|
+
},
|
7
26
|
"bin": {
|
8
27
|
"ca-plant-list": "build-site.js"
|
9
28
|
},
|
10
29
|
"dependencies": {
|
30
|
+
"command-line-args": "^5.2.1",
|
11
31
|
"csv-parse": "^5.3.1"
|
12
32
|
},
|
13
33
|
"devDependencies": {
|