@ca-plant-list/ca-plant-list 0.3.6 → 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 +109 -3
- package/data/taxa.csv +65 -29
- package/data/text/Antennaria-media.md +1 -0
- package/data/text/Antennaria-rosea-subsp-rosea.md +1 -0
- package/data/text/Antirrhinum-thompsonii.md +1 -0
- package/data/text/Calyptridium-monospermum.md +1 -0
- package/data/text/Calyptridium-umbellatum.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/Clarkia-affinis.md +1 -0
- package/data/text/Clarkia-breweri.md +1 -0
- package/data/text/Clarkia-concinna-subsp-automixa.md +1 -0
- package/data/text/Clarkia-modesta.md +1 -0
- package/data/text/Clarkia-purpurea-subsp-quadrivulnera.md +1 -0
- package/data/text/Clarkia-rubicunda.md +1 -0
- package/data/text/Delphinium-californicum-subsp-californicum.md +1 -1
- package/data/text/Delphinium-californicum-subsp-interius.md +1 -0
- package/data/text/Delphinium-glaucum.md +1 -0
- package/data/text/Delphinium-hesperium-subsp-hesperium.md +1 -1
- package/data/text/Delphinium-hesperium-subsp-pallescens.md +1 -0
- package/data/text/Delphinium-nuttallianum.md +1 -0
- package/data/text/Delphinium-parryi-subsp-parryi.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/Erythranthe-moschata.md +1 -0
- package/data/text/Erythranthe-primuloides.md +1 -0
- package/data/text/Erythranthe-tilingii.md +1 -0
- package/data/text/Lilium-pardalinum-subsp-shastense.md +1 -0
- package/data/text/Logfia-filaginoides.md +1 -0
- package/data/text/Logfia-gallica.md +1 -0
- package/data/text/Malacothamnus-arcuatus-var-elmeri.md +1 -0
- package/data/text/Malacothamnus-fremontii-var-fremontii.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/data/text/Trifolium-obtusiflorum.md +1 -0
- package/data/text/Trifolium-willdenovii.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 +59 -42
- 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/page_list_species.js +15 -9
- package/lib/ebook/pages/taxonpage.js +3 -6
- 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/ebook/xhtml.js +3 -5
- package/lib/exceptions.js +42 -26
- package/lib/externalsites.js +11 -4
- package/lib/families.js +10 -10
- package/lib/flowercolor.js +42 -0
- package/lib/genera.js +13 -23
- package/lib/genericpage.js +38 -18
- package/lib/html.js +11 -23
- package/lib/htmltaxon.js +114 -14
- 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 +13 -9
- package/lib/pagerenderer.js +162 -82
- package/lib/plants/glossary.js +14 -14
- package/lib/program.js +47 -0
- package/lib/rareplants.js +44 -30
- package/lib/sitegenerator.js +41 -24
- package/lib/taxa.js +25 -142
- package/lib/taxon.js +3 -5
- package/lib/web/glossarypages.js +37 -18
- package/lib/web/pagetaxon.js +1 -5
- package/package.json +5 -3
- package/schemas/exceptions.schema.json +57 -0
- package/scripts/build-ebook.js +39 -48
- package/scripts/build-site.js +49 -28
- package/types/classes.d.ts +154 -0
- package/lib/commandandtaxaprocessor.js +0 -25
- package/lib/commandprocessor.js +0 -108
- package/lib/generictaxaloader.js +0 -48
- package/lib/taxaloader.js +0 -48
- package/lib/taxaprocessor.js +0 -34
package/lib/ebook/images.js
CHANGED
@@ -3,88 +3,105 @@ import path from "node:path";
|
|
3
3
|
|
4
4
|
import sharp from "sharp";
|
5
5
|
|
6
|
-
import { Config, CSV, Files } from "@ca-plant-list/ca-plant-list";
|
7
|
-
|
8
|
-
import { Image } from "./image.js";
|
9
6
|
import { EBook } from "./ebook.js";
|
10
|
-
import {
|
7
|
+
import { Config } from "../config.js";
|
8
|
+
import { CSV } from "../csv.js";
|
9
|
+
import { Files } from "../files.js";
|
10
|
+
import { TaxonImage } from "./taxonimage.js";
|
11
11
|
|
12
12
|
class Images {
|
13
|
-
|
14
13
|
#siteGenerator;
|
15
14
|
#contentDir;
|
16
15
|
#taxa;
|
16
|
+
/** @type {Object<string,TaxonImage[]>} */
|
17
17
|
#images = {};
|
18
18
|
|
19
|
-
|
19
|
+
/**
|
20
|
+
* @param {SiteGenerator} siteGenerator
|
21
|
+
* @param {string} contentDir
|
22
|
+
* @param {Taxa} taxa
|
23
|
+
*/
|
24
|
+
constructor(siteGenerator, contentDir, taxa) {
|
20
25
|
this.#siteGenerator = siteGenerator;
|
21
26
|
this.#contentDir = contentDir;
|
22
27
|
this.#taxa = taxa;
|
23
28
|
}
|
24
29
|
|
25
30
|
async createImages() {
|
26
|
-
|
27
31
|
const photoDirSrc = "external_data/photos";
|
28
32
|
const imagePrefix = "i";
|
29
33
|
const photoDirTarget = this.#contentDir + "/" + imagePrefix;
|
30
|
-
fs.mkdirSync(
|
31
|
-
fs.mkdirSync(
|
32
|
-
|
33
|
-
const rows = CSV.parseFile(
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
34
|
+
fs.mkdirSync(photoDirSrc, { recursive: true });
|
35
|
+
fs.mkdirSync(photoDirTarget, { recursive: true });
|
36
|
+
|
37
|
+
const rows = CSV.parseFile(
|
38
|
+
Config.getPackageDir() + "/data",
|
39
|
+
"photos.csv"
|
40
|
+
);
|
41
|
+
for (const row of rows) {
|
42
|
+
const name = row["taxon_name"];
|
43
|
+
const taxon = this.#taxa.getTaxon(name);
|
44
|
+
if (!taxon) {
|
39
45
|
continue;
|
40
46
|
}
|
41
47
|
|
42
|
-
let imageList = this.#images[
|
43
|
-
if (
|
48
|
+
let imageList = this.#images[name];
|
49
|
+
if (!imageList) {
|
44
50
|
imageList = [];
|
45
|
-
this.#images[
|
51
|
+
this.#images[name] = imageList;
|
46
52
|
}
|
47
53
|
|
48
|
-
const src = new URL(
|
49
|
-
const parts = path.parse(
|
50
|
-
const prefix = src.host.includes(
|
51
|
-
const filename = prefix + parts.slice(
|
54
|
+
const src = new URL(row["source"]);
|
55
|
+
const parts = path.parse(src.pathname).dir.split("/");
|
56
|
+
const prefix = src.host.includes("calflora") ? "cf-" : "inat-";
|
57
|
+
const filename = prefix + parts.slice(-1)[0] + ".jpg";
|
52
58
|
const srcFileName = photoDirSrc + "/" + filename;
|
53
59
|
const targetFileName = photoDirTarget + "/" + filename;
|
54
60
|
|
55
|
-
if (
|
61
|
+
if (!fs.existsSync(srcFileName)) {
|
56
62
|
// File is not there; retrieve it.
|
57
|
-
console.log(
|
58
|
-
await Files.fetch(
|
63
|
+
console.log("retrieving " + srcFileName);
|
64
|
+
await Files.fetch(src, srcFileName);
|
59
65
|
}
|
60
66
|
|
61
|
-
|
62
|
-
|
63
|
-
|
67
|
+
sharp(srcFileName)
|
68
|
+
.resize({ width: 300 })
|
69
|
+
.jpeg({ quality: 40 })
|
70
|
+
.toFile(targetFileName);
|
64
71
|
|
72
|
+
imageList.push(
|
73
|
+
new TaxonImage(imagePrefix + "/" + filename, row["credit"])
|
74
|
+
);
|
65
75
|
}
|
66
76
|
|
67
|
-
this.#siteGenerator.copyIllustrations(
|
68
|
-
|
77
|
+
this.#siteGenerator.copyIllustrations(this.#taxa.getFlowerColors());
|
69
78
|
}
|
70
79
|
|
71
80
|
getManifestEntries() {
|
72
|
-
|
73
81
|
const entries = [];
|
74
|
-
const images = Files.getDirEntries(
|
75
|
-
|
76
|
-
for (
|
77
|
-
const fileName = images[
|
78
|
-
const ext = fileName.split(
|
79
|
-
entries.push(
|
82
|
+
const images = Files.getDirEntries(this.#contentDir + "/i").sort();
|
83
|
+
|
84
|
+
for (let index = 0; index < images.length; index++) {
|
85
|
+
const fileName = images[index];
|
86
|
+
const ext = fileName.split(".")[1];
|
87
|
+
entries.push(
|
88
|
+
EBook.getManifestEntry(
|
89
|
+
"i" + index,
|
90
|
+
"i/" + fileName,
|
91
|
+
EBook.getMediaTypeForExt(ext)
|
92
|
+
)
|
93
|
+
);
|
80
94
|
}
|
81
95
|
|
82
|
-
return entries.join(
|
96
|
+
return entries.join("");
|
83
97
|
}
|
84
98
|
|
85
|
-
|
86
|
-
|
99
|
+
/**
|
100
|
+
* @param {string} name
|
101
|
+
*/
|
102
|
+
getTaxonImages(name) {
|
103
|
+
return this.#images[name];
|
87
104
|
}
|
88
105
|
}
|
89
106
|
|
90
|
-
export { Images };
|
107
|
+
export { Images };
|
@@ -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 };
|
@@ -1,26 +1,32 @@
|
|
1
|
+
import { HTMLTaxon } from "../../htmltaxon.js";
|
1
2
|
import { EBookPage } from "../ebookpage.js";
|
2
3
|
import { XHTML } from "../xhtml.js";
|
3
4
|
|
4
5
|
class PageListSpecies extends EBookPage {
|
5
|
-
|
6
6
|
#taxa;
|
7
7
|
|
8
|
-
|
9
|
-
|
8
|
+
/**
|
9
|
+
*
|
10
|
+
* @param {string} outputDir
|
11
|
+
* @param {Taxon[]} taxa
|
12
|
+
* @param {string} filename
|
13
|
+
* @param {string} title
|
14
|
+
*/
|
15
|
+
constructor(outputDir, taxa, filename, title) {
|
16
|
+
super(outputDir + "/" + filename, title);
|
10
17
|
this.#taxa = taxa;
|
11
18
|
}
|
12
19
|
|
13
20
|
renderPageBody() {
|
14
|
-
|
15
|
-
const html = XHTML.textElement( "h1", this.getTitle() );
|
21
|
+
const html = XHTML.textElement("h1", this.getTitle());
|
16
22
|
|
17
23
|
const links = [];
|
18
|
-
for (
|
19
|
-
links.push(
|
24
|
+
for (const taxon of this.#taxa) {
|
25
|
+
links.push(HTMLTaxon.getLink(taxon));
|
20
26
|
}
|
21
27
|
|
22
|
-
return html + XHTML.wrap(
|
28
|
+
return html + XHTML.wrap("ol", XHTML.arrayToLI(links));
|
23
29
|
}
|
24
30
|
}
|
25
31
|
|
26
|
-
export { PageListSpecies };
|
32
|
+
export { PageListSpecies };
|
@@ -1,13 +1,10 @@
|
|
1
1
|
import imageSize from "image-size";
|
2
|
-
import { Config, Files } from "@ca-plant-list/ca-plant-list";
|
3
2
|
import { EBookPage } from "../ebookpage.js";
|
4
3
|
import { XHTML } from "../xhtml.js";
|
5
4
|
import { Markdown } from "../../markdown.js";
|
6
|
-
// eslint-disable-next-line no-unused-vars
|
7
|
-
import { Taxon } from "../../taxon.js";
|
8
|
-
// eslint-disable-next-line no-unused-vars
|
9
|
-
import { Image } from "../image.js";
|
10
5
|
import { HTMLTaxon } from "../../htmltaxon.js";
|
6
|
+
import { Config } from "../../config.js";
|
7
|
+
import { Files } from "../../files.js";
|
11
8
|
|
12
9
|
class TaxonPage extends EBookPage {
|
13
10
|
#outputDir;
|
@@ -17,7 +14,7 @@ class TaxonPage extends EBookPage {
|
|
17
14
|
/**
|
18
15
|
* @param {string} outputDir
|
19
16
|
* @param {Taxon} taxon
|
20
|
-
* @param {
|
17
|
+
* @param {TaxonImage[]} photos
|
21
18
|
*/
|
22
19
|
constructor(outputDir, taxon, photos) {
|
23
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/ebook/xhtml.js
CHANGED