@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/ebook/images.js
CHANGED
@@ -3,19 +3,24 @@ import path from "node:path";
|
|
3
3
|
|
4
4
|
import sharp from "sharp";
|
5
5
|
|
6
|
-
import { Image } from "./image.js";
|
7
6
|
import { EBook } from "./ebook.js";
|
8
|
-
import { Taxa } from "../taxa.js";
|
9
7
|
import { Config } from "../config.js";
|
10
8
|
import { CSV } from "../csv.js";
|
11
9
|
import { Files } from "../files.js";
|
10
|
+
import { TaxonImage } from "./taxonimage.js";
|
12
11
|
|
13
12
|
class Images {
|
14
13
|
#siteGenerator;
|
15
14
|
#contentDir;
|
16
15
|
#taxa;
|
16
|
+
/** @type {Object<string,TaxonImage[]>} */
|
17
17
|
#images = {};
|
18
18
|
|
19
|
+
/**
|
20
|
+
* @param {SiteGenerator} siteGenerator
|
21
|
+
* @param {string} contentDir
|
22
|
+
* @param {Taxa} taxa
|
23
|
+
*/
|
19
24
|
constructor(siteGenerator, contentDir, taxa) {
|
20
25
|
this.#siteGenerator = siteGenerator;
|
21
26
|
this.#contentDir = contentDir;
|
@@ -59,17 +64,17 @@ class Images {
|
|
59
64
|
await Files.fetch(src, srcFileName);
|
60
65
|
}
|
61
66
|
|
62
|
-
|
67
|
+
sharp(srcFileName)
|
63
68
|
.resize({ width: 300 })
|
64
69
|
.jpeg({ quality: 40 })
|
65
70
|
.toFile(targetFileName);
|
66
71
|
|
67
72
|
imageList.push(
|
68
|
-
new
|
73
|
+
new TaxonImage(imagePrefix + "/" + filename, row["credit"])
|
69
74
|
);
|
70
75
|
}
|
71
76
|
|
72
|
-
this.#siteGenerator.copyIllustrations(
|
77
|
+
this.#siteGenerator.copyIllustrations(this.#taxa.getFlowerColors());
|
73
78
|
}
|
74
79
|
|
75
80
|
getManifestEntries() {
|
@@ -91,6 +96,9 @@ class Images {
|
|
91
96
|
return entries.join("");
|
92
97
|
}
|
93
98
|
|
99
|
+
/**
|
100
|
+
* @param {string} name
|
101
|
+
*/
|
94
102
|
getTaxonImages(name) {
|
95
103
|
return this.#images[name];
|
96
104
|
}
|
@@ -2,25 +2,30 @@ import { EBookPage } from "../ebookpage.js";
|
|
2
2
|
import { XHTML } from "../xhtml.js";
|
3
3
|
|
4
4
|
class PageListFlowerColor extends EBookPage {
|
5
|
-
|
6
5
|
#color;
|
7
6
|
|
8
|
-
|
9
|
-
|
7
|
+
/**
|
8
|
+
* @param {string} outputDir
|
9
|
+
* @param {FlowerColor} color
|
10
|
+
*/
|
11
|
+
constructor(outputDir, color) {
|
12
|
+
super(
|
13
|
+
outputDir + "/" + color.getFileName(),
|
14
|
+
color.getColorName(true) + " Flowers"
|
15
|
+
);
|
10
16
|
this.#color = color;
|
11
17
|
}
|
12
18
|
|
13
19
|
renderPageBody() {
|
14
|
-
|
15
|
-
const html = XHTML.textElement( "h1", this.getTitle() );
|
20
|
+
const html = XHTML.textElement("h1", this.getTitle());
|
16
21
|
|
17
22
|
const links = [];
|
18
|
-
for (
|
19
|
-
links.push(
|
23
|
+
for (const taxon of this.#color.getTaxa()) {
|
24
|
+
links.push(XHTML.getLink(taxon.getFileName(), taxon.getName()));
|
20
25
|
}
|
21
26
|
|
22
|
-
return html + XHTML.wrap(
|
27
|
+
return html + XHTML.wrap("ol", XHTML.arrayToLI(links));
|
23
28
|
}
|
24
29
|
}
|
25
30
|
|
26
|
-
export { PageListFlowerColor };
|
31
|
+
export { PageListFlowerColor };
|
@@ -6,104 +6,122 @@ import { EBook } from "../ebook.js";
|
|
6
6
|
const FN_FLOWER_TIME_INDEX = "fm.html";
|
7
7
|
|
8
8
|
class PageListFlowers {
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
9
|
+
/**
|
10
|
+
* @param {string} contentDir
|
11
|
+
* @param {Taxa} taxa
|
12
|
+
*/
|
13
|
+
static createPages(contentDir, taxa) {
|
14
|
+
new PageListFlowerTimeIndex(contentDir).create();
|
15
|
+
for (let m1 = 1; m1 < 13; m1++) {
|
16
|
+
new PageListFlowerTime(contentDir, taxa, m1).create();
|
14
17
|
}
|
15
18
|
}
|
16
19
|
|
17
20
|
static getManifestEntries() {
|
18
|
-
|
19
21
|
const manifestEntries = [];
|
20
22
|
|
21
|
-
manifestEntries.push(
|
22
|
-
|
23
|
-
|
23
|
+
manifestEntries.push(
|
24
|
+
EBook.getManifestEntry("fm0", FN_FLOWER_TIME_INDEX)
|
25
|
+
);
|
26
|
+
for (let m1 = 1; m1 < 13; m1++) {
|
27
|
+
manifestEntries.push(
|
28
|
+
EBook.getManifestEntry(
|
29
|
+
"fm" + m1,
|
30
|
+
PageListFlowerTime.getFileNameBloomTime(m1)
|
31
|
+
)
|
32
|
+
);
|
24
33
|
}
|
25
34
|
|
26
|
-
return manifestEntries.join(
|
35
|
+
return manifestEntries.join("");
|
27
36
|
}
|
28
37
|
|
29
38
|
static getSpineEntries() {
|
30
|
-
|
31
39
|
const spineEntries = [];
|
32
40
|
|
33
|
-
spineEntries.push(
|
34
|
-
for (
|
35
|
-
spineEntries.push(
|
41
|
+
spineEntries.push(EBook.getSpineEntry("fm0"));
|
42
|
+
for (let m1 = 1; m1 < 13; m1++) {
|
43
|
+
spineEntries.push(EBook.getSpineEntry("fm" + m1));
|
36
44
|
}
|
37
45
|
|
38
|
-
return spineEntries.join(
|
39
|
-
|
46
|
+
return spineEntries.join("");
|
40
47
|
}
|
41
48
|
|
42
49
|
static renderMonthLinks() {
|
43
50
|
const links = [];
|
44
|
-
for (
|
51
|
+
for (let m1 = 1; m1 < 13; m1++) {
|
45
52
|
links.push(
|
46
53
|
XHTML.getLink(
|
47
|
-
PageListFlowerTime.getFileNameBloomTime(
|
48
|
-
DateUtils.getMonthName(
|
54
|
+
PageListFlowerTime.getFileNameBloomTime(m1),
|
55
|
+
DateUtils.getMonthName(m1) +
|
56
|
+
" - " +
|
57
|
+
DateUtils.getMonthName((m1 % 12) + 1)
|
49
58
|
)
|
50
59
|
);
|
51
60
|
}
|
52
|
-
return XHTML.wrap(
|
61
|
+
return XHTML.wrap("ol", XHTML.arrayToLI(links));
|
53
62
|
}
|
54
|
-
|
55
63
|
}
|
56
64
|
|
57
65
|
class PageListFlowerTimeIndex extends EBookPage {
|
58
|
-
|
59
|
-
|
60
|
-
|
66
|
+
/**
|
67
|
+
* @param {string} outputDir
|
68
|
+
*/
|
69
|
+
constructor(outputDir) {
|
70
|
+
super(outputDir + "/" + FN_FLOWER_TIME_INDEX, "Flowering Times");
|
61
71
|
}
|
62
72
|
|
63
73
|
renderPageBody() {
|
64
|
-
const html = XHTML.textElement(
|
74
|
+
const html = XHTML.textElement("h1", this.getTitle());
|
65
75
|
return html + PageListFlowers.renderMonthLinks();
|
66
76
|
}
|
67
|
-
|
68
77
|
}
|
69
78
|
|
70
79
|
class PageListFlowerTime extends EBookPage {
|
71
|
-
|
72
80
|
#taxa;
|
73
81
|
#m1;
|
74
82
|
#m2;
|
75
83
|
|
76
|
-
|
84
|
+
/**
|
85
|
+
* @param {string} outputDir
|
86
|
+
* @param {Taxa} taxa
|
87
|
+
* @param {number} month
|
88
|
+
*/
|
89
|
+
constructor(outputDir, taxa, month) {
|
77
90
|
super(
|
78
|
-
outputDir + "/" + PageListFlowerTime.getFileNameBloomTime(
|
79
|
-
"Flowering in " +
|
91
|
+
outputDir + "/" + PageListFlowerTime.getFileNameBloomTime(month),
|
92
|
+
"Flowering in " +
|
93
|
+
DateUtils.getMonthName(month) +
|
94
|
+
" - " +
|
95
|
+
DateUtils.getMonthName((month % 12) + 1)
|
80
96
|
);
|
81
97
|
this.#taxa = taxa;
|
82
98
|
this.#m1 = month;
|
83
|
-
this.#m2 = month % 12 + 1;
|
99
|
+
this.#m2 = (month % 12) + 1;
|
84
100
|
}
|
85
101
|
|
86
|
-
|
102
|
+
/**
|
103
|
+
* @param {number} m1
|
104
|
+
*/
|
105
|
+
static getFileNameBloomTime(m1) {
|
87
106
|
return "list_fm_" + m1 + ".html";
|
88
107
|
}
|
89
108
|
|
90
109
|
renderPageBody() {
|
110
|
+
const html = XHTML.textElement("h1", this.getTitle());
|
91
111
|
|
92
|
-
|
93
|
-
|
94
|
-
const range = [ this.#m1, this.#m2 ];
|
112
|
+
/** @type {[number,number]} */
|
113
|
+
const range = [this.#m1, this.#m2];
|
95
114
|
const links = [];
|
96
|
-
for (
|
115
|
+
for (const taxon of this.#taxa.getTaxonList()) {
|
97
116
|
const m1 = taxon.getBloomStart();
|
98
117
|
const m2 = taxon.getBloomEnd();
|
99
|
-
if (
|
100
|
-
links.push(
|
118
|
+
if (m1 && m2 && DateUtils.monthRangesOverlap(range, [m1, m2])) {
|
119
|
+
links.push(XHTML.getLink(taxon.getFileName(), taxon.getName()));
|
101
120
|
}
|
102
121
|
}
|
103
122
|
|
104
|
-
return html + XHTML.wrap(
|
123
|
+
return html + XHTML.wrap("ol", XHTML.arrayToLI(links));
|
105
124
|
}
|
106
|
-
|
107
125
|
}
|
108
126
|
|
109
|
-
export { PageListFlowers, PageListFlowerTime };
|
127
|
+
export { PageListFlowers, PageListFlowerTime };
|
@@ -14,7 +14,7 @@ class TaxonPage extends EBookPage {
|
|
14
14
|
/**
|
15
15
|
* @param {string} outputDir
|
16
16
|
* @param {Taxon} taxon
|
17
|
-
* @param {
|
17
|
+
* @param {TaxonImage[]} photos
|
18
18
|
*/
|
19
19
|
constructor(outputDir, taxon, photos) {
|
20
20
|
super(outputDir + "/" + taxon.getFileName(), taxon.getName());
|
@@ -1,26 +1,30 @@
|
|
1
|
-
import { Taxa } from "../../taxa.js";
|
2
1
|
import { EBookPage } from "../ebookpage.js";
|
3
2
|
import { XHTML } from "../xhtml.js";
|
4
3
|
import { PageListFlowers } from "./page_list_flowers.js";
|
5
4
|
|
6
5
|
class TOCPage extends EBookPage {
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
#taxa;
|
7
|
+
|
8
|
+
/**
|
9
|
+
* @param {string} outputDir
|
10
|
+
* @param {Taxa} taxa
|
11
|
+
*/
|
12
|
+
constructor(outputDir, taxa) {
|
13
|
+
super(outputDir + "/toc.xhtml", "Table of Contents");
|
14
|
+
this.#taxa = taxa;
|
10
15
|
}
|
11
16
|
|
12
17
|
renderPageBody() {
|
13
|
-
|
14
|
-
|
15
|
-
html += "<h1 epub:type=\"title\">Table of Contents</h1>";
|
18
|
+
let html = '<nav id="toc" role="doc-toc" epub:type="toc">';
|
19
|
+
html += '<h1 epub:type="title">Table of Contents</h1>';
|
16
20
|
|
17
21
|
const mainLinks = [];
|
18
|
-
mainLinks.push(
|
19
|
-
mainLinks.push(
|
20
|
-
mainLinks.push(
|
21
|
-
mainLinks.push(
|
22
|
-
mainLinks.push(
|
23
|
-
html += XHTML.wrap(
|
22
|
+
mainLinks.push(this.#getFlowerColorLinks());
|
23
|
+
mainLinks.push(this.#getFlowerTimeLinks());
|
24
|
+
mainLinks.push(XHTML.getLink("./list_families.html", "All Families"));
|
25
|
+
mainLinks.push(XHTML.getLink("./list_species.html", "All Species"));
|
26
|
+
mainLinks.push(XHTML.getLink("./glossary.html", "Glossary"));
|
27
|
+
html += XHTML.wrap("ol", XHTML.arrayToLI(mainLinks));
|
24
28
|
|
25
29
|
html += "</nav>";
|
26
30
|
|
@@ -28,19 +32,21 @@ class TOCPage extends EBookPage {
|
|
28
32
|
}
|
29
33
|
|
30
34
|
#getFlowerColorLinks() {
|
31
|
-
const html = XHTML.textElement(
|
35
|
+
const html = XHTML.textElement("span", "Flower Color");
|
32
36
|
const links = [];
|
33
|
-
for (
|
34
|
-
|
37
|
+
for (const color of this.#taxa.getFlowerColors()) {
|
38
|
+
const colorName = color.getColorName();
|
39
|
+
links.push(
|
40
|
+
XHTML.getLink("list_fc_" + colorName + ".html", colorName)
|
41
|
+
);
|
35
42
|
}
|
36
|
-
return html + XHTML.wrap(
|
43
|
+
return html + XHTML.wrap("ol", XHTML.arrayToLI(links));
|
37
44
|
}
|
38
45
|
|
39
46
|
#getFlowerTimeLinks() {
|
40
|
-
const html = XHTML.getLink(
|
47
|
+
const html = XHTML.getLink("fm.html", "Flowering Times");
|
41
48
|
return html + PageListFlowers.renderMonthLinks();
|
42
49
|
}
|
43
|
-
|
44
50
|
}
|
45
51
|
|
46
|
-
export { TOCPage };
|
52
|
+
export { TOCPage };
|
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 { Taxa } from "../taxa.js";
|
12
11
|
|
13
12
|
class PlantBook extends EBook {
|
14
13
|
#taxa;
|
@@ -16,9 +15,8 @@ class PlantBook extends EBook {
|
|
16
15
|
#images;
|
17
16
|
|
18
17
|
/**
|
19
|
-
*
|
20
18
|
* @param {string} outputDir
|
21
|
-
* @param {
|
19
|
+
* @param {Config} config
|
22
20
|
* @param {Taxa} taxa
|
23
21
|
*/
|
24
22
|
constructor(outputDir, config, taxa) {
|
@@ -52,11 +50,8 @@ class PlantBook extends EBook {
|
|
52
50
|
}
|
53
51
|
|
54
52
|
// Create lists.
|
55
|
-
for (const
|
56
|
-
new PageListFlowerColor(
|
57
|
-
contentDir,
|
58
|
-
this.#taxa.getFlowerColor(colorName)
|
59
|
-
).create();
|
53
|
+
for (const color of this.#taxa.getFlowerColors()) {
|
54
|
+
new PageListFlowerColor(contentDir, color).create();
|
60
55
|
}
|
61
56
|
|
62
57
|
PageListFlowers.createPages(contentDir, this.#taxa);
|
@@ -84,7 +79,7 @@ class PlantBook extends EBook {
|
|
84
79
|
|
85
80
|
this.#glossary.renderPages();
|
86
81
|
|
87
|
-
new TOCPage(contentDir).create();
|
82
|
+
new TOCPage(contentDir, this.#taxa).create();
|
88
83
|
}
|
89
84
|
|
90
85
|
renderManifestEntries() {
|
@@ -95,8 +90,7 @@ class PlantBook extends EBook {
|
|
95
90
|
'<item id="lspecies" href="list_species.html" media-type="application/xhtml+xml" />';
|
96
91
|
xml +=
|
97
92
|
'<item id="lfamilies" href="list_families.html" media-type="application/xhtml+xml" />';
|
98
|
-
for (const
|
99
|
-
const color = this.#taxa.getFlowerColor(colorName);
|
93
|
+
for (const color of this.#taxa.getFlowerColors()) {
|
100
94
|
xml +=
|
101
95
|
'<item id="l' +
|
102
96
|
color.getColorName() +
|
@@ -142,8 +136,7 @@ class PlantBook extends EBook {
|
|
142
136
|
let xml = "";
|
143
137
|
|
144
138
|
// Add lists.
|
145
|
-
for (const
|
146
|
-
const color = this.#taxa.getFlowerColor(colorName);
|
139
|
+
for (const color of this.#taxa.getFlowerColors()) {
|
147
140
|
xml += '<itemref idref="l' + color.getColorName() + '"/>';
|
148
141
|
}
|
149
142
|
xml += PageListFlowers.getSpineEntries();
|
package/lib/exceptions.js
CHANGED
@@ -2,55 +2,71 @@ import { Config } from "./config.js";
|
|
2
2
|
import { Files } from "./files.js";
|
3
3
|
|
4
4
|
class Exceptions {
|
5
|
-
|
5
|
+
/** @type {Object<string,Object<string,Object<string,{}>>>} */
|
6
6
|
#exceptions = {};
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
/**
|
9
|
+
* @param {string} dir
|
10
|
+
*/
|
11
|
+
constructor(dir) {
|
12
|
+
/**
|
13
|
+
* @param {string} fileName
|
14
|
+
*/
|
15
|
+
function readConfig(fileName) {
|
16
|
+
return JSON.parse(Files.read(fileName));
|
12
17
|
}
|
13
18
|
|
14
19
|
// Read default configuration.
|
15
|
-
this.#exceptions = readConfig(
|
20
|
+
this.#exceptions = readConfig(
|
21
|
+
Config.getPackageDir() + "/data/exceptions.json"
|
22
|
+
);
|
16
23
|
|
17
24
|
// Add/overwrite with local configuration.
|
18
|
-
const localExceptions = readConfig(
|
19
|
-
for (
|
20
|
-
this.#exceptions[
|
25
|
+
const localExceptions = readConfig(dir + "/exceptions.json");
|
26
|
+
for (const [k, v] of Object.entries(localExceptions)) {
|
27
|
+
this.#exceptions[k] = v;
|
21
28
|
// Tag as a local exception so we can distinguish between global and local.
|
22
29
|
v.local = true;
|
23
30
|
}
|
24
|
-
|
25
31
|
}
|
26
32
|
|
27
33
|
getExceptions() {
|
28
|
-
return Object.entries(
|
34
|
+
return Object.entries(this.#exceptions);
|
29
35
|
}
|
30
36
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
37
|
+
/**
|
38
|
+
* @param {string} name
|
39
|
+
* @param {string} cat
|
40
|
+
* @param {string} subcat
|
41
|
+
* @param {string} defaultValue
|
42
|
+
*/
|
43
|
+
getValue(name, cat, subcat, defaultValue) {
|
44
|
+
const taxonData = this.#exceptions[name];
|
45
|
+
if (taxonData) {
|
46
|
+
const catData = taxonData[cat];
|
47
|
+
if (catData) {
|
48
|
+
const val = catData[subcat];
|
49
|
+
return val === undefined ? defaultValue : val;
|
38
50
|
}
|
39
51
|
}
|
40
52
|
return defaultValue;
|
41
53
|
}
|
42
54
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
55
|
+
/**
|
56
|
+
* @param {string} name
|
57
|
+
* @param {string} cat
|
58
|
+
* @param {string} subcat
|
59
|
+
*/
|
60
|
+
hasException(name, cat, subcat) {
|
61
|
+
const taxonData = this.#exceptions[name];
|
62
|
+
if (taxonData) {
|
63
|
+
const catData = taxonData[cat];
|
64
|
+
if (catData) {
|
65
|
+
return catData[subcat] !== undefined;
|
49
66
|
}
|
50
67
|
}
|
51
68
|
return false;
|
52
69
|
}
|
53
|
-
|
54
70
|
}
|
55
71
|
|
56
|
-
export { Exceptions };
|
72
|
+
export { Exceptions };
|
package/lib/externalsites.js
CHANGED
@@ -1,4 +1,7 @@
|
|
1
1
|
class ExternalSites {
|
2
|
+
/**
|
3
|
+
* @param {InatObsOptions} options
|
4
|
+
*/
|
2
5
|
static getInatObsLink(options) {
|
3
6
|
const url = new URL(
|
4
7
|
"https://www.inaturalist.org/observations?subview=map"
|
@@ -9,10 +12,14 @@ class ExternalSites {
|
|
9
12
|
case "coords": {
|
10
13
|
const delta = 0.1;
|
11
14
|
const params = url.searchParams;
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
15
|
+
/** @type {number} */
|
16
|
+
const lat = v[1];
|
17
|
+
/** @type {number} */
|
18
|
+
const lng = v[0];
|
19
|
+
params.set("nelat", (lat + delta).toString());
|
20
|
+
params.set("swlat", (lat - delta).toString());
|
21
|
+
params.set("nelng", (lng + delta).toString());
|
22
|
+
params.set("swlng", (lng - delta).toString());
|
16
23
|
break;
|
17
24
|
}
|
18
25
|
case "created_d1":
|
package/lib/families.js
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
import { GenericPage } from "./genericpage.js";
|
2
2
|
import { HTML } from "./html.js";
|
3
3
|
import { Jepson } from "./jepson.js";
|
4
|
-
import { Taxa } from "./taxa.js";
|
5
4
|
import { Files } from "./files.js";
|
6
5
|
import { Config } from "./config.js";
|
6
|
+
import { HTMLTaxon } from "./htmltaxon.js";
|
7
7
|
|
8
8
|
class Family {
|
9
9
|
#name;
|
@@ -81,7 +81,7 @@ class Families {
|
|
81
81
|
|
82
82
|
/**
|
83
83
|
* @param {string} outputDir
|
84
|
-
* @param {
|
84
|
+
* @param {TaxaCol[]} taxaColumns
|
85
85
|
*/
|
86
86
|
renderPages(outputDir, taxaColumns) {
|
87
87
|
new PageFamilyList(outputDir, this.#families).render(taxaColumns);
|
@@ -109,7 +109,7 @@ class PageFamilyList extends GenericPage {
|
|
109
109
|
}
|
110
110
|
|
111
111
|
/**
|
112
|
-
* @param {
|
112
|
+
* @param {TaxaCol[]} taxaColumns
|
113
113
|
*/
|
114
114
|
render(taxaColumns) {
|
115
115
|
let html = this.getDefaultIntro();
|
@@ -176,8 +176,7 @@ class PageFamily extends GenericPage {
|
|
176
176
|
}
|
177
177
|
|
178
178
|
/**
|
179
|
-
*
|
180
|
-
* @param {import("./index.js").TaxaCol[]} columns
|
179
|
+
* @param {TaxaCol[]} columns
|
181
180
|
*/
|
182
181
|
render(columns) {
|
183
182
|
let html = this.getDefaultIntro();
|
@@ -188,7 +187,7 @@ class PageFamily extends GenericPage {
|
|
188
187
|
{ class: "section" }
|
189
188
|
);
|
190
189
|
|
191
|
-
html +=
|
190
|
+
html += HTMLTaxon.getTaxaTable(this.#family.getTaxa(), columns);
|
192
191
|
|
193
192
|
this.writeFile(html);
|
194
193
|
}
|
@@ -207,17 +206,20 @@ class PageSection extends GenericPage {
|
|
207
206
|
this.#taxa = taxa;
|
208
207
|
}
|
209
208
|
|
209
|
+
/**
|
210
|
+
* @param {TaxaCol[]} [columns]
|
211
|
+
*/
|
210
212
|
render(columns) {
|
211
213
|
let html = this.getDefaultIntro();
|
212
214
|
|
213
|
-
html +=
|
215
|
+
html += HTMLTaxon.getTaxaTable(this.#taxa, columns);
|
214
216
|
|
215
217
|
this.writeFile(html);
|
216
218
|
}
|
217
219
|
}
|
218
220
|
|
219
221
|
class Sections {
|
220
|
-
/** @type {Object<string,Taxon[]} */
|
222
|
+
/** @type {Object<string,Taxon[]>} */
|
221
223
|
static #sections = {};
|
222
224
|
|
223
225
|
/**
|
@@ -0,0 +1,42 @@
|
|
1
|
+
import { TextUtils } from "./textutils.js";
|
2
|
+
|
3
|
+
class FlowerColor {
|
4
|
+
#colorName;
|
5
|
+
#colorCode;
|
6
|
+
/** @type {Taxon[]} */
|
7
|
+
#taxa = [];
|
8
|
+
|
9
|
+
/**
|
10
|
+
* @param {string} colorName
|
11
|
+
* @param {string} [colorCode]
|
12
|
+
*/
|
13
|
+
constructor(colorName, colorCode) {
|
14
|
+
this.#colorName = colorName;
|
15
|
+
this.#colorCode = colorCode ? colorCode : colorName;
|
16
|
+
}
|
17
|
+
|
18
|
+
/**
|
19
|
+
* @param {Taxon} taxon
|
20
|
+
*/
|
21
|
+
addTaxon(taxon) {
|
22
|
+
this.#taxa.push(taxon);
|
23
|
+
}
|
24
|
+
|
25
|
+
getColorCode() {
|
26
|
+
return this.#colorCode;
|
27
|
+
}
|
28
|
+
|
29
|
+
getColorName(uc = false) {
|
30
|
+
return uc ? TextUtils.ucFirst(this.#colorName) : this.#colorName;
|
31
|
+
}
|
32
|
+
|
33
|
+
getFileName() {
|
34
|
+
return "list_fc_" + this.#colorName + ".html";
|
35
|
+
}
|
36
|
+
|
37
|
+
getTaxa() {
|
38
|
+
return this.#taxa;
|
39
|
+
}
|
40
|
+
}
|
41
|
+
|
42
|
+
export { FlowerColor };
|