@ca-plant-list/ca-plant-list 0.3.7 → 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 +85 -2
- package/data/taxa.csv +38 -16
- package/data/text/Antennaria-media.md +1 -0
- package/data/text/Antennaria-rosea-subsp-rosea.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/Delphinium-glaucum.md +1 -0
- package/data/text/Delphinium-nuttallianum.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/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/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 +13 -5
- 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/taxonpage.js +1 -1
- 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/exceptions.js +42 -26
- package/lib/externalsites.js +11 -4
- package/lib/families.js +10 -8
- package/lib/flowercolor.js +42 -0
- package/lib/genera.js +13 -21
- package/lib/genericpage.js +12 -0
- package/lib/html.js +11 -23
- package/lib/htmltaxon.js +89 -6
- 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 +6 -0
- package/lib/pagerenderer.js +43 -8
- package/lib/plants/glossary.js +5 -0
- package/lib/program.js +47 -0
- package/lib/rareplants.js +44 -30
- package/lib/sitegenerator.js +41 -24
- package/lib/taxa.js +20 -134
- package/lib/taxon.js +1 -1
- package/lib/web/glossarypages.js +6 -0
- package/lib/web/pagetaxon.js +1 -5
- package/package.json +6 -3
- package/schemas/exceptions.schema.json +57 -0
- package/scripts/build-ebook.js +38 -47
- package/scripts/build-site.js +25 -14
- package/types/classes.d.ts +136 -8
- package/lib/commandandtaxaprocessor.js +0 -25
- package/lib/commandprocessor.js +0 -108
- package/lib/generictaxaloader.js +0 -48
- package/lib/taxaloader.js +0 -50
- package/lib/taxaprocessor.js +0 -34
- /package/data/text/{Calyptridium-ubellatum.md → Calyptridium-umbellatum.md} +0 -0
package/lib/genera.js
CHANGED
@@ -6,7 +6,6 @@ class Genera {
|
|
6
6
|
#genera;
|
7
7
|
|
8
8
|
/**
|
9
|
-
*
|
10
9
|
* @param {Families} families
|
11
10
|
*/
|
12
11
|
constructor(families) {
|
@@ -22,21 +21,17 @@ class Genera {
|
|
22
21
|
const genusName = taxon.getGenusName();
|
23
22
|
const genusData = this.#genera[genusName];
|
24
23
|
if (!genusData) {
|
25
|
-
|
26
|
-
return;
|
24
|
+
throw new Error(taxon.getName() + " genus not found");
|
27
25
|
}
|
28
26
|
|
29
|
-
if (genusData.
|
27
|
+
if (genusData.familyObj === undefined) {
|
28
|
+
// Initialize genus data.
|
29
|
+
genusData.familyObj = this.#families.getFamily(genusData.family);
|
30
30
|
genusData.taxa = [];
|
31
31
|
}
|
32
|
-
genusData.
|
32
|
+
genusData.familyObj.addTaxon(taxon);
|
33
33
|
|
34
|
-
|
35
|
-
if (!family) {
|
36
|
-
console.log(taxon.getName() + " family not found");
|
37
|
-
return;
|
38
|
-
}
|
39
|
-
family.addTaxon(taxon);
|
34
|
+
genusData.taxa.push(taxon);
|
40
35
|
}
|
41
36
|
|
42
37
|
/**
|
@@ -45,25 +40,22 @@ class Genera {
|
|
45
40
|
getGenus(genusName) {
|
46
41
|
return new Genus(this.#genera[genusName]);
|
47
42
|
}
|
48
|
-
|
49
|
-
/**
|
50
|
-
* @param {string} genusName
|
51
|
-
*/
|
52
|
-
getFamily(genusName) {
|
53
|
-
const genus = this.#genera[genusName];
|
54
|
-
if (genus) {
|
55
|
-
return this.#families.getFamily(genus.family);
|
56
|
-
}
|
57
|
-
}
|
58
43
|
}
|
59
44
|
|
60
45
|
class Genus {
|
61
46
|
#data;
|
62
47
|
|
48
|
+
/**
|
49
|
+
* @param {{family:string,familyObj:Family,taxa:Taxon[]}} data
|
50
|
+
*/
|
63
51
|
constructor(data) {
|
64
52
|
this.#data = data;
|
65
53
|
}
|
66
54
|
|
55
|
+
getFamily() {
|
56
|
+
return this.#data.familyObj;
|
57
|
+
}
|
58
|
+
|
67
59
|
getTaxa() {
|
68
60
|
return this.#data.taxa.sort((a, b) =>
|
69
61
|
a.getName().localeCompare(b.getName())
|
package/lib/genericpage.js
CHANGED
@@ -10,6 +10,12 @@ class GenericPage {
|
|
10
10
|
#baseFileName;
|
11
11
|
#js;
|
12
12
|
|
13
|
+
/**
|
14
|
+
* @param {string} outputDir
|
15
|
+
* @param {string} title
|
16
|
+
* @param {string} baseFileName
|
17
|
+
* @param {string} [js]
|
18
|
+
*/
|
13
19
|
constructor(outputDir, title, baseFileName, js) {
|
14
20
|
this.#outputDir = outputDir;
|
15
21
|
this.#title = title;
|
@@ -53,6 +59,9 @@ class GenericPage {
|
|
53
59
|
return html;
|
54
60
|
}
|
55
61
|
|
62
|
+
/**
|
63
|
+
* @param {string} path
|
64
|
+
*/
|
56
65
|
#getMarkdown(path) {
|
57
66
|
const textPath = path + "/" + this.#baseFileName + ".md";
|
58
67
|
if (!Jekyll.hasInclude(this.#outputDir, textPath)) {
|
@@ -69,6 +78,9 @@ class GenericPage {
|
|
69
78
|
return this.#title;
|
70
79
|
}
|
71
80
|
|
81
|
+
/**
|
82
|
+
* @param {string} html
|
83
|
+
*/
|
72
84
|
writeFile(html) {
|
73
85
|
Files.write(this.#outputDir + "/" + this.#baseFileName + ".html", html);
|
74
86
|
}
|
package/lib/html.js
CHANGED
@@ -1,11 +1,3 @@
|
|
1
|
-
/**
|
2
|
-
* @deprecated
|
3
|
-
*/
|
4
|
-
export const HTML_OPTIONS = {
|
5
|
-
OPEN_NEW: 1,
|
6
|
-
NO_ESCAPE: 2,
|
7
|
-
};
|
8
|
-
|
9
1
|
/** HTML utility functions. */
|
10
2
|
export class HTML {
|
11
3
|
/**
|
@@ -35,19 +27,6 @@ export class HTML {
|
|
35
27
|
.replaceAll(">", ">");
|
36
28
|
}
|
37
29
|
|
38
|
-
/**
|
39
|
-
* @deprecated
|
40
|
-
*/
|
41
|
-
static getElement(elName, text, attributes = {}, options = 0) {
|
42
|
-
let html = "<" + elName;
|
43
|
-
html += this.renderAttributes(attributes);
|
44
|
-
if (!(options & HTML_OPTIONS.NO_ESCAPE)) {
|
45
|
-
text = this.escapeText(text);
|
46
|
-
}
|
47
|
-
html += ">" + text + "</" + elName + ">";
|
48
|
-
return html;
|
49
|
-
}
|
50
|
-
|
51
30
|
/**
|
52
31
|
* @param {string} elName
|
53
32
|
* @param {string} text
|
@@ -71,7 +50,7 @@ export class HTML {
|
|
71
50
|
* Generate HTML for an <a> element.
|
72
51
|
* @param {string|undefined} href
|
73
52
|
* @param {string} linkText
|
74
|
-
* @param {Object} [attributes]
|
53
|
+
* @param {string|Object<string,string>} [attributes]
|
75
54
|
* @param {boolean} [openInNewWindow] true if the link should open in a new window.
|
76
55
|
* @returns {string} an HTML <a> element.
|
77
56
|
*/
|
@@ -92,7 +71,7 @@ export class HTML {
|
|
92
71
|
* @param {string} text - The text or HTML that should trigger the tooltip on hover.
|
93
72
|
* @param {string} tooltip - The tooltip text or HTML.
|
94
73
|
* @param {Object} options
|
95
|
-
* @param {boolean} options.icon [true] display an icon after the text
|
74
|
+
* @param {boolean} [options.icon] [true] display an icon after the text
|
96
75
|
* @returns {string} A <span> element to be used as a Bootstrap tooltip.
|
97
76
|
*/
|
98
77
|
static getToolTip(text, tooltip, options = {}) {
|
@@ -103,6 +82,10 @@ export class HTML {
|
|
103
82
|
return func("span", text, { "data-bs-html": "true", title: tooltip });
|
104
83
|
}
|
105
84
|
|
85
|
+
/**
|
86
|
+
* @param {string} n
|
87
|
+
* @param {string} v
|
88
|
+
*/
|
106
89
|
static renderAttribute(n, v) {
|
107
90
|
return " " + n + '="' + this.escapeAttribute(v) + '"';
|
108
91
|
}
|
@@ -121,6 +104,11 @@ export class HTML {
|
|
121
104
|
return html;
|
122
105
|
}
|
123
106
|
|
107
|
+
/**
|
108
|
+
* @param {string} elName
|
109
|
+
* @param {string} text
|
110
|
+
* @param {Object<string,string>} attributes
|
111
|
+
*/
|
124
112
|
static textElement(elName, text, attributes = {}) {
|
125
113
|
return HTML.#getElement(elName, text, attributes, true);
|
126
114
|
}
|
package/lib/htmltaxon.js
CHANGED
@@ -1,21 +1,68 @@
|
|
1
1
|
import { DateUtils } from "./dateutils.js";
|
2
2
|
import { HTML } from "./html.js";
|
3
|
+
import { RarePlants } from "./rareplants.js";
|
3
4
|
import { TextUtils } from "./textutils.js";
|
4
5
|
|
6
|
+
/**
|
7
|
+
* @type {Object<string,{title:string,data:function (Taxon):string}>}
|
8
|
+
*/
|
9
|
+
const TAXA_LIST_COLS = {
|
10
|
+
CESA: {
|
11
|
+
title: "California",
|
12
|
+
data: (t) => RarePlants.getCESADescription(t.getCESA()),
|
13
|
+
},
|
14
|
+
COMMON_NAME: {
|
15
|
+
title: "Common Name",
|
16
|
+
data: (t) => t.getCommonNames().join(", "),
|
17
|
+
},
|
18
|
+
CNPS_RANK: {
|
19
|
+
title: "CNPS Rank",
|
20
|
+
data: (t) =>
|
21
|
+
HTML.getToolTip(
|
22
|
+
HTML.textElement("span", t.getRPIRankAndThreat()),
|
23
|
+
t.getRPIRankAndThreatTooltip()
|
24
|
+
),
|
25
|
+
},
|
26
|
+
FESA: {
|
27
|
+
title: "Federal",
|
28
|
+
data: (t) => RarePlants.getFESADescription(t.getFESA()),
|
29
|
+
},
|
30
|
+
SPECIES: {
|
31
|
+
title: "Species",
|
32
|
+
data: (t) => t.getHTMLLink(true, true),
|
33
|
+
},
|
34
|
+
SPECIES_BARE: {
|
35
|
+
title: "Species",
|
36
|
+
data: (t) => t.getHTMLLink(true, false),
|
37
|
+
},
|
38
|
+
};
|
39
|
+
|
40
|
+
const DEFAULT_TAXA_COLUMNS = [
|
41
|
+
TAXA_LIST_COLS.SPECIES,
|
42
|
+
TAXA_LIST_COLS.COMMON_NAME,
|
43
|
+
];
|
44
|
+
|
5
45
|
class HTMLTaxon {
|
6
46
|
/**
|
7
|
-
* @param {string[]} colors
|
47
|
+
* @param {string[]|undefined} colors
|
8
48
|
*/
|
9
|
-
static getFlowerColors(colors) {
|
49
|
+
static getFlowerColors(colors, includeColorLink = true) {
|
10
50
|
let html = "";
|
11
51
|
if (colors) {
|
12
52
|
for (const color of colors) {
|
13
|
-
|
53
|
+
const img = HTML.textElement("img", "", {
|
14
54
|
src: "./i/f-" + color + ".svg",
|
15
55
|
alt: color + " flowers",
|
16
56
|
title: color,
|
17
57
|
class: "flr-color",
|
18
58
|
});
|
59
|
+
if (includeColorLink) {
|
60
|
+
html += HTML.wrap("a", img, {
|
61
|
+
href: "./list_fc_" + color + ".html",
|
62
|
+
});
|
63
|
+
} else {
|
64
|
+
html += img;
|
65
|
+
}
|
19
66
|
}
|
20
67
|
}
|
21
68
|
return html;
|
@@ -24,8 +71,13 @@ class HTMLTaxon {
|
|
24
71
|
/**
|
25
72
|
* @param {Taxon} taxon
|
26
73
|
* @param {string} classNames
|
74
|
+
* @param {boolean} [includeColorLink=true]
|
27
75
|
*/
|
28
|
-
static getFlowerInfo(
|
76
|
+
static getFlowerInfo(
|
77
|
+
taxon,
|
78
|
+
classNames = "section",
|
79
|
+
includeColorLink = true
|
80
|
+
) {
|
29
81
|
const lifeCycle = taxon.getLifeCycle();
|
30
82
|
const colors = taxon.getFlowerColors();
|
31
83
|
const monthStart = taxon.getBloomStart();
|
@@ -40,7 +92,7 @@ class HTMLTaxon {
|
|
40
92
|
|
41
93
|
if (colors || monthStart) {
|
42
94
|
let html = "Flowers: ";
|
43
|
-
html += this.getFlowerColors(colors);
|
95
|
+
html += this.getFlowerColors(colors, includeColorLink);
|
44
96
|
if (monthStart && monthEnd) {
|
45
97
|
html += HTML.wrap(
|
46
98
|
"span",
|
@@ -64,6 +116,37 @@ class HTMLTaxon {
|
|
64
116
|
this.getFlowerColors(taxon.getFlowerColors())
|
65
117
|
);
|
66
118
|
}
|
119
|
+
|
120
|
+
/**
|
121
|
+
* @param {Taxon[]} taxa
|
122
|
+
* @param {TaxaCol[]} [columns]
|
123
|
+
*/
|
124
|
+
static getTaxaTable(taxa, columns = DEFAULT_TAXA_COLUMNS) {
|
125
|
+
let html = "<table><thead>";
|
126
|
+
for (const col of columns) {
|
127
|
+
const className = col.class;
|
128
|
+
const atts = className !== undefined ? className : {};
|
129
|
+
html += HTML.textElement("th", col.title, atts);
|
130
|
+
}
|
131
|
+
html += "</thead>";
|
132
|
+
html += "<tbody>";
|
133
|
+
|
134
|
+
for (const taxon of taxa) {
|
135
|
+
html += "<tr>";
|
136
|
+
for (const col of columns) {
|
137
|
+
const data = col.data(taxon);
|
138
|
+
const className = col.class;
|
139
|
+
const atts = className !== undefined ? className : {};
|
140
|
+
html += HTML.wrap("td", data, atts);
|
141
|
+
}
|
142
|
+
html += "</tr>";
|
143
|
+
}
|
144
|
+
|
145
|
+
html += "</tbody>";
|
146
|
+
html += "</table>";
|
147
|
+
|
148
|
+
return html;
|
149
|
+
}
|
67
150
|
}
|
68
151
|
|
69
|
-
export { HTMLTaxon };
|
152
|
+
export { HTMLTaxon, TAXA_LIST_COLS };
|
package/lib/index.d.ts
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
import { Command } from "commander";
|
2
|
+
|
3
|
+
export class Config {
|
4
|
+
constructor(dataDir: string);
|
5
|
+
getConfigValue(
|
6
|
+
prefix: string,
|
7
|
+
name: string,
|
8
|
+
subcategory?: string,
|
9
|
+
defaultValue?: string
|
10
|
+
): string;
|
11
|
+
getCountyCodes(): string[];
|
12
|
+
getLabel(name: string, dflt: string): string;
|
13
|
+
}
|
14
|
+
|
15
|
+
export class CSV {
|
16
|
+
static parseFile(dir: string, fileName: string);
|
17
|
+
}
|
18
|
+
|
19
|
+
export class ErrorLog {
|
20
|
+
constructor(fileName: string, echo?: boolean);
|
21
|
+
log(...msg: string[]);
|
22
|
+
write(): void;
|
23
|
+
}
|
24
|
+
|
25
|
+
export class Exceptions {
|
26
|
+
constructor(dataDir: string);
|
27
|
+
hasException(name: string, cat: string, subcat: string);
|
28
|
+
}
|
29
|
+
|
30
|
+
export class Files {
|
31
|
+
static exists(fileName: string): boolean;
|
32
|
+
static async fetch(url: string | URL, targetFileName: string | undefined);
|
33
|
+
static mkdir(dir: string);
|
34
|
+
static rmDir(dir: string);
|
35
|
+
static write(fileName: string, data: string, overwrite: boolean);
|
36
|
+
}
|
37
|
+
|
38
|
+
export class Program {
|
39
|
+
static getIncludeList(dataDir: string): string[];
|
40
|
+
static getProgram(): Command;
|
41
|
+
}
|
42
|
+
|
43
|
+
export class Taxa {
|
44
|
+
constructor(
|
45
|
+
inclusionList: Object<string, TaxonData> | true,
|
46
|
+
errorLog: ErrorLog,
|
47
|
+
showFlowerErrors: boolean,
|
48
|
+
taxonFactory?: (td: TaxonData, g: Genera) => Taxon,
|
49
|
+
extraTaxa?: TaxonData[],
|
50
|
+
extraSynonyms?: SynonymData[]
|
51
|
+
);
|
52
|
+
getTaxon(string): Taxon;
|
53
|
+
getTaxonList(): Taxon[];
|
54
|
+
}
|
package/lib/index.js
CHANGED
@@ -1,58 +1,30 @@
|
|
1
|
-
/**
|
2
|
-
* @typedef {{
|
3
|
-
* bloom_end:string;
|
4
|
-
* bloom_start:string;
|
5
|
-
* calrecnum:string;
|
6
|
-
* CESA:string;
|
7
|
-
* CRPR:string;
|
8
|
-
* "common name":string;
|
9
|
-
* FESA:string;
|
10
|
-
* flower_color:string;
|
11
|
-
* GRank:string;
|
12
|
-
* "inat id":string;
|
13
|
-
* "jepson id":string;
|
14
|
-
* life_cycle:"annual"|"perennial"|undefined
|
15
|
-
* SRank:string;
|
16
|
-
* status:string;
|
17
|
-
* "RPI ID":string;
|
18
|
-
* taxon_name:string}} TaxonData
|
19
|
-
*/
|
20
|
-
|
21
1
|
import { BasePageRenderer } from "./basepagerenderer.js";
|
22
|
-
import { CommandProcessor } from "./commandprocessor.js";
|
23
|
-
import { CommandAndTaxaProcessor } from "./commandandtaxaprocessor.js";
|
24
2
|
import { Config } from "./config.js";
|
25
3
|
import { CSV } from "./csv.js";
|
26
4
|
import { ErrorLog } from "./errorlog.js";
|
27
5
|
import { Exceptions } from "./exceptions.js";
|
28
6
|
import { Families } from "./families.js";
|
29
7
|
import { Files } from "./files.js";
|
30
|
-
import { GenericTaxaLoader } from "./generictaxaloader.js";
|
31
8
|
import { HTML } from "./html.js";
|
32
9
|
import { Jekyll } from "./jekyll.js";
|
33
10
|
import { PlantBook } from "./ebook/plantbook.js";
|
11
|
+
import { Program } from "./program.js";
|
34
12
|
import { Taxa } from "./taxa.js";
|
35
|
-
import { TaxaLoader } from "./taxaloader.js";
|
36
|
-
import { TaxaProcessor } from "./taxaprocessor.js";
|
37
13
|
import { Taxon, TAXA_COLNAMES } from "./taxon.js";
|
38
14
|
|
39
15
|
export {
|
40
16
|
BasePageRenderer,
|
41
|
-
CommandProcessor,
|
42
|
-
CommandAndTaxaProcessor,
|
43
17
|
Config,
|
44
18
|
CSV,
|
45
19
|
ErrorLog,
|
46
20
|
Exceptions,
|
47
21
|
Families,
|
48
22
|
Files,
|
49
|
-
GenericTaxaLoader,
|
50
23
|
HTML,
|
51
24
|
Jekyll,
|
52
25
|
PlantBook,
|
26
|
+
Program,
|
53
27
|
Taxa,
|
54
|
-
TaxaLoader,
|
55
|
-
TaxaProcessor,
|
56
28
|
TAXA_COLNAMES,
|
57
29
|
Taxon,
|
58
30
|
};
|
package/lib/jekyll.js
CHANGED
@@ -4,40 +4,68 @@ import { SiteGenerator } from "./sitegenerator.js";
|
|
4
4
|
const FRONT_DELIM = "---";
|
5
5
|
|
6
6
|
class Jekyll extends SiteGenerator {
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
/**
|
8
|
+
* @param {string} baseDir
|
9
|
+
*/
|
10
|
+
constructor(baseDir) {
|
11
|
+
super(baseDir);
|
10
12
|
}
|
11
13
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
14
|
+
/**
|
15
|
+
* @param {Object<string,string>} atts
|
16
|
+
*/
|
17
|
+
static getFrontMatter(atts) {
|
18
|
+
const lines = [FRONT_DELIM];
|
19
|
+
for (const [k, v] of Object.entries(atts)) {
|
20
|
+
lines.push(k + ': "' + v + '"');
|
16
21
|
}
|
17
|
-
if (
|
18
|
-
lines.push(
|
22
|
+
if (!atts.layout) {
|
23
|
+
lines.push("layout: default");
|
19
24
|
}
|
20
|
-
lines.push(
|
21
|
-
return lines.join(
|
25
|
+
lines.push(FRONT_DELIM);
|
26
|
+
return lines.join("\n") + "\n";
|
22
27
|
}
|
23
28
|
|
24
|
-
|
25
|
-
|
29
|
+
/**
|
30
|
+
* @param {string} baseDir
|
31
|
+
* @param {string} path
|
32
|
+
*/
|
33
|
+
static hasInclude(baseDir, path) {
|
34
|
+
return Files.exists(baseDir + "/_includes/" + path);
|
26
35
|
}
|
27
36
|
|
28
|
-
|
37
|
+
/**
|
38
|
+
* @param {string} path
|
39
|
+
*/
|
40
|
+
static include(path) {
|
29
41
|
// This works for .md includes; should have conditional logic to detect other types.
|
30
|
-
return
|
42
|
+
return (
|
43
|
+
"{% capture my_include %}{% include " +
|
44
|
+
path +
|
45
|
+
" %}{% endcapture %}{{ my_include | markdownify }}"
|
46
|
+
);
|
31
47
|
}
|
32
48
|
|
33
|
-
|
34
|
-
|
49
|
+
/**
|
50
|
+
* @param {string} baseDir
|
51
|
+
* @param {string} path
|
52
|
+
* @param {string} data
|
53
|
+
*/
|
54
|
+
static writeInclude(baseDir, path, data) {
|
55
|
+
Files.write(baseDir + "/_includes/" + path, data);
|
35
56
|
}
|
36
57
|
|
37
|
-
|
38
|
-
|
58
|
+
/**
|
59
|
+
* @param {string} content
|
60
|
+
* @param {Object<string,string>} attributes
|
61
|
+
* @param {string} filename
|
62
|
+
*/
|
63
|
+
writeTemplate(content, attributes, filename) {
|
64
|
+
Files.write(
|
65
|
+
Files.join(this.getBaseDir(), filename),
|
66
|
+
Jekyll.getFrontMatter(attributes) + content
|
67
|
+
);
|
39
68
|
}
|
40
|
-
|
41
69
|
}
|
42
70
|
|
43
|
-
export { Jekyll };
|
71
|
+
export { Jekyll };
|
package/lib/jepson.js
CHANGED
@@ -1,18 +1,17 @@
|
|
1
|
-
import { HTML
|
1
|
+
import { HTML } from "./html.js";
|
2
2
|
|
3
3
|
class Jepson {
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
/**
|
5
|
+
* @param {string} id
|
6
|
+
*/
|
7
|
+
static getEFloraLink(id) {
|
7
8
|
return HTML.getLink(
|
8
9
|
"https://ucjeps.berkeley.edu/eflora/eflora_display.php?tid=" + id,
|
9
10
|
"Jepson eFlora",
|
10
11
|
{},
|
11
|
-
|
12
|
+
true
|
12
13
|
);
|
13
|
-
|
14
14
|
}
|
15
|
-
|
16
15
|
}
|
17
16
|
|
18
|
-
export { Jepson };
|
17
|
+
export { Jepson };
|
package/lib/markdown.js
CHANGED
@@ -4,10 +4,16 @@ import { Files } from "./files.js";
|
|
4
4
|
class Markdown {
|
5
5
|
static #md = new markdownIt({ xhtmlOut: true });
|
6
6
|
|
7
|
+
/**
|
8
|
+
* @param {string} filePath
|
9
|
+
*/
|
7
10
|
static fileToHTML(filePath) {
|
8
11
|
return this.strToHTML(Files.read(filePath));
|
9
12
|
}
|
10
13
|
|
14
|
+
/**
|
15
|
+
* @param {string} str
|
16
|
+
*/
|
11
17
|
static strToHTML(str) {
|
12
18
|
return this.#md.render(str);
|
13
19
|
}
|
package/lib/pagerenderer.js
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
import { Taxa, TAXA_LIST_COLS } from "./taxa.js";
|
2
1
|
import { PageTaxon } from "./web/pagetaxon.js";
|
3
2
|
import { RarePlants } from "./rareplants.js";
|
4
3
|
import { BasePageRenderer } from "./basepagerenderer.js";
|
5
4
|
import { GenericPage } from "./genericpage.js";
|
6
5
|
import { Files } from "./files.js";
|
7
6
|
import { HTML } from "./html.js";
|
7
|
+
import { HTMLTaxon, TAXA_LIST_COLS } from "./htmltaxon.js";
|
8
8
|
|
9
9
|
const ENDANGERED_COLS = [
|
10
10
|
TAXA_LIST_COLS.SPECIES,
|
@@ -19,8 +19,13 @@ const RPI_COLUMNS = [
|
|
19
19
|
];
|
20
20
|
|
21
21
|
class PageRenderer extends BasePageRenderer {
|
22
|
+
/**
|
23
|
+
* @param {string} outputDir
|
24
|
+
* @param {Config} config
|
25
|
+
* @param {Taxa} taxa
|
26
|
+
*/
|
22
27
|
static render(outputDir, config, taxa) {
|
23
|
-
super.
|
28
|
+
super.renderBasePages(outputDir, taxa);
|
24
29
|
|
25
30
|
this.renderLists(outputDir, config, taxa);
|
26
31
|
|
@@ -30,7 +35,18 @@ class PageRenderer extends BasePageRenderer {
|
|
30
35
|
}
|
31
36
|
}
|
32
37
|
|
38
|
+
/**
|
39
|
+
* @param {string} outputDir
|
40
|
+
* @param {Config} config
|
41
|
+
* @param {Taxa} taxa
|
42
|
+
*/
|
33
43
|
static renderLists(outputDir, config, taxa) {
|
44
|
+
/**
|
45
|
+
* @param {ListInfo[]} listInfo
|
46
|
+
* @param {Object<string,string>} attributes
|
47
|
+
* @param {TaxaCol[]} [columns]
|
48
|
+
* @returns {string}
|
49
|
+
*/
|
34
50
|
function getListArray(listInfo, attributes = {}, columns) {
|
35
51
|
const listArray = [];
|
36
52
|
for (const list of listInfo) {
|
@@ -81,10 +97,18 @@ class PageRenderer extends BasePageRenderer {
|
|
81
97
|
return renderList(listArray, attributes);
|
82
98
|
}
|
83
99
|
|
100
|
+
/**
|
101
|
+
* @param {string[]} listsHTML
|
102
|
+
* @param {Object<string,string>} attributes
|
103
|
+
*/
|
84
104
|
function renderList(listsHTML, attributes = {}) {
|
85
105
|
return HTML.wrap("ul", HTML.arrayToLI(listsHTML), attributes);
|
86
106
|
}
|
87
107
|
|
108
|
+
/**
|
109
|
+
* @param {string} title
|
110
|
+
* @param {string} listsHTML
|
111
|
+
*/
|
88
112
|
function renderSection(title, listsHTML) {
|
89
113
|
let html = '<div class="section">';
|
90
114
|
html += HTML.textElement("h2", title);
|
@@ -93,6 +117,8 @@ class PageRenderer extends BasePageRenderer {
|
|
93
117
|
return html;
|
94
118
|
}
|
95
119
|
|
120
|
+
/** @typedef {{name:string,filename:string,include:function(Taxon):boolean,columns?:TaxaCol[],listInfo?:ListInfo[]}} ListInfo */
|
121
|
+
/** @type {{title:string,listInfo:ListInfo[]}[]} */
|
96
122
|
const sections = [
|
97
123
|
{
|
98
124
|
title: "All Species",
|
@@ -158,7 +184,9 @@ class PageRenderer extends BasePageRenderer {
|
|
158
184
|
{
|
159
185
|
name: "Endangered Species",
|
160
186
|
filename: "list_endangered",
|
161
|
-
include: (t) =>
|
187
|
+
include: (t) =>
|
188
|
+
t.getCESA() !== undefined ||
|
189
|
+
t.getFESA() !== undefined,
|
162
190
|
columns: ENDANGERED_COLS,
|
163
191
|
},
|
164
192
|
],
|
@@ -167,10 +195,7 @@ class PageRenderer extends BasePageRenderer {
|
|
167
195
|
|
168
196
|
let html = '<div class="wrapper">';
|
169
197
|
for (const section of sections) {
|
170
|
-
const listHTML = getListArray(
|
171
|
-
section.listInfo,
|
172
|
-
section.listInfo.columns
|
173
|
-
);
|
198
|
+
const listHTML = getListArray(section.listInfo);
|
174
199
|
|
175
200
|
if (listHTML.length > 0) {
|
176
201
|
html += renderSection(section.title, listHTML);
|
@@ -189,17 +214,27 @@ class PageRenderer extends BasePageRenderer {
|
|
189
214
|
}
|
190
215
|
|
191
216
|
class PageTaxonList extends GenericPage {
|
217
|
+
/**
|
218
|
+
* @param {string} outputDir
|
219
|
+
* @param {string} title
|
220
|
+
* @param {string} baseName
|
221
|
+
*/
|
192
222
|
constructor(outputDir, title, baseName) {
|
193
223
|
super(outputDir, title, baseName);
|
194
224
|
}
|
195
225
|
|
226
|
+
/**
|
227
|
+
*
|
228
|
+
* @param {Taxon[]} taxa
|
229
|
+
* @param {TaxaCol[]|undefined} columns
|
230
|
+
*/
|
196
231
|
render(taxa, columns) {
|
197
232
|
let html = this.getDefaultIntro();
|
198
233
|
|
199
234
|
html += '<div class="wrapper">';
|
200
235
|
|
201
236
|
html += '<div class="section">';
|
202
|
-
html +=
|
237
|
+
html += HTMLTaxon.getTaxaTable(taxa, columns);
|
203
238
|
html += "</div>";
|
204
239
|
|
205
240
|
html += '<div class="section">';
|