@ca-plant-list/ca-plant-list 0.3.7 → 0.4.1

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.
Files changed (75) hide show
  1. package/.vscode/settings.json +7 -1
  2. package/data/synonyms.csv +95 -2
  3. package/data/taxa.csv +53 -22
  4. package/data/text/Antennaria-media.md +1 -0
  5. package/data/text/Antennaria-rosea-subsp-rosea.md +1 -0
  6. package/data/text/Camassia-leichtlinii-subsp-suksdorfii.md +1 -0
  7. package/data/text/Camassia-quamash-subsp-breviflora.md +1 -0
  8. package/data/text/Delphinium-glaucum.md +1 -0
  9. package/data/text/Delphinium-nuttallianum.md +1 -0
  10. package/data/text/Drymocallis-glandulosa-var-glandulosa.md +1 -0
  11. package/data/text/Drymocallis-lactea-var-austiniae.md +1 -0
  12. package/data/text/Erigeron-compositus.md +1 -0
  13. package/data/text/Erigeron-glacialis-var-glacialis.md +1 -0
  14. package/data/text/Eriogonum-incanum.md +1 -0
  15. package/data/text/Eriogonum-lobbii.md +1 -0
  16. package/data/text/Eriogonum-ovalifolium-var-nivale.md +1 -0
  17. package/data/text/Erythranthe-breweri.md +1 -0
  18. package/data/text/Erythranthe-erubescens.md +1 -0
  19. package/data/text/Navarretia-leptalea-subsp-bicolor.md +1 -0
  20. package/data/text/Navarretia-leptalea-subsp-leptalea.md +1 -0
  21. package/data/text/Polemonium-californicum.md +1 -0
  22. package/data/text/Polemonium-pulcherrimum-var-pulcherrimum.md +1 -0
  23. package/data/text/Primula-jeffreyi.md +1 -0
  24. package/data/text/Primula-tetrandra.md +1 -0
  25. package/data/text/Silene-douglasii-var-douglasii.md +1 -0
  26. package/data/text/Silene-lemmonii.md +1 -0
  27. package/data/text/Silene-sargentii.md +1 -0
  28. package/lib/basepagerenderer.js +3 -4
  29. package/lib/config.js +42 -19
  30. package/lib/csv.js +54 -36
  31. package/lib/ebook/ebook.js +84 -57
  32. package/lib/ebook/ebookpage.js +22 -11
  33. package/lib/ebook/ebooksitegenerator.js +36 -14
  34. package/lib/ebook/glossarypages.js +20 -17
  35. package/lib/ebook/images.js +13 -5
  36. package/lib/ebook/pages/page_list_families.js +0 -2
  37. package/lib/ebook/pages/page_list_flower_color.js +14 -9
  38. package/lib/ebook/pages/page_list_flowers.js +59 -41
  39. package/lib/ebook/pages/taxonpage.js +1 -1
  40. package/lib/ebook/pages/tocpage.js +26 -20
  41. package/lib/ebook/plantbook.js +6 -13
  42. package/lib/ebook/{image.js → taxonimage.js} +2 -2
  43. package/lib/exceptions.js +42 -26
  44. package/lib/externalsites.js +11 -4
  45. package/lib/families.js +10 -8
  46. package/lib/flowercolor.js +42 -0
  47. package/lib/genera.js +13 -21
  48. package/lib/genericpage.js +12 -0
  49. package/lib/html.js +11 -23
  50. package/lib/htmltaxon.js +89 -6
  51. package/lib/index.d.ts +54 -0
  52. package/lib/index.js +2 -30
  53. package/lib/jekyll.js +49 -21
  54. package/lib/jepson.js +7 -8
  55. package/lib/markdown.js +6 -0
  56. package/lib/pagerenderer.js +43 -8
  57. package/lib/plants/glossary.js +5 -0
  58. package/lib/program.js +47 -0
  59. package/lib/rareplants.js +44 -30
  60. package/lib/sitegenerator.js +41 -24
  61. package/lib/taxa.js +20 -134
  62. package/lib/taxon.js +1 -1
  63. package/lib/web/glossarypages.js +6 -0
  64. package/lib/web/pagetaxon.js +1 -5
  65. package/package.json +8 -7
  66. package/schemas/exceptions.schema.json +57 -0
  67. package/scripts/build-ebook.js +38 -47
  68. package/scripts/build-site.js +25 -14
  69. package/types/classes.d.ts +136 -8
  70. package/lib/commandandtaxaprocessor.js +0 -25
  71. package/lib/commandprocessor.js +0 -108
  72. package/lib/generictaxaloader.js +0 -48
  73. package/lib/taxaloader.js +0 -50
  74. package/lib/taxaprocessor.js +0 -34
  75. /package/data/text/{Calyptridium-ubellatum.md → Calyptridium-umbellatum.md} +0 -0
@@ -2,33 +2,55 @@ import { Files } from "../files.js";
2
2
  import { SiteGenerator } from "../sitegenerator.js";
3
3
 
4
4
  class EBookSiteGenerator extends SiteGenerator {
5
-
6
- constructor( baseDir ) {
7
- super( baseDir );
5
+ /**
6
+ * @param {string} baseDir
7
+ */
8
+ constructor(baseDir) {
9
+ super(baseDir);
8
10
  }
9
11
 
10
12
  #pageEnd() {
11
13
  return "</body></html>";
12
14
  }
13
15
 
14
- #pageStart( depth, attributes ) {
15
- let html = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
16
- html += "<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:epub=\"http://www.idpf.org/2007/ops\">";
16
+ /**
17
+ * @param {number} depth
18
+ * @param {{title:string}} attributes
19
+ */
20
+ #pageStart(depth, attributes) {
21
+ let html = '<?xml version="1.0" encoding="utf-8"?>\n';
22
+ html +=
23
+ '<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">';
17
24
  html += "<head><title>" + attributes.title + "</title>";
18
- html += "<link href=\"" + "../".repeat( depth ) + "css/main.css\" rel=\"stylesheet\" />";
25
+ html +=
26
+ '<link href="' +
27
+ "../".repeat(depth) +
28
+ 'css/main.css" rel="stylesheet" />';
19
29
  html += "</head><body>";
20
30
  return html;
21
31
  }
22
32
 
23
- #wrap( depth, content, attributes ) {
24
- return this.#pageStart( depth, attributes ) + content + this.#pageEnd();
33
+ /**
34
+ * @param {number} depth
35
+ * @param {string} content
36
+ * @param {{title:string}} attributes
37
+ */
38
+ #wrap(depth, content, attributes) {
39
+ return this.#pageStart(depth, attributes) + content + this.#pageEnd();
25
40
  }
26
41
 
27
- writeTemplate( content, attributes, filename ) {
28
- const depth = ( filename.match( /\//g ) || [] ).length;
29
- Files.write( Files.join( this.getBaseDir(), filename ), this.#wrap( depth, content, attributes ) );
42
+ /**
43
+ * @param {string} content
44
+ * @param {{title:string}} attributes
45
+ * @param {string} filename
46
+ */
47
+ writeTemplate(content, attributes, filename) {
48
+ const depth = (filename.match(/\//g) || []).length;
49
+ Files.write(
50
+ Files.join(this.getBaseDir(), filename),
51
+ this.#wrap(depth, content, attributes)
52
+ );
30
53
  }
31
-
32
54
  }
33
55
 
34
- export { EBookSiteGenerator };
56
+ export { EBookSiteGenerator };
@@ -2,39 +2,42 @@ import { GlossaryPages as BaseGlossaryPages } from "../web/glossarypages.js";
2
2
  import { EBook } from "./ebook.js";
3
3
 
4
4
  class GlossaryPages extends BaseGlossaryPages {
5
-
6
- constructor( siteGenerator ) {
7
- super( siteGenerator );
5
+ /**
6
+ * @param {SiteGenerator} siteGenerator
7
+ */
8
+ constructor(siteGenerator) {
9
+ super(siteGenerator);
8
10
  }
9
11
 
10
12
  getManifestEntries() {
11
-
12
13
  const glossaryEntries = this.getGlossary().getEntries();
13
14
  const manifestEntries = [];
14
15
 
15
- manifestEntries.push( EBook.getManifestEntry( "g", "glossary.html" ) );
16
- for ( let index = 0; index < glossaryEntries.length; index++ ) {
17
- const entry = glossaryEntries[ index ];
18
- manifestEntries.push( EBook.getManifestEntry( "g" + index, "g/" + entry.getHTMLFileName() ) );
16
+ manifestEntries.push(EBook.getManifestEntry("g", "glossary.html"));
17
+ for (let index = 0; index < glossaryEntries.length; index++) {
18
+ const entry = glossaryEntries[index];
19
+ manifestEntries.push(
20
+ EBook.getManifestEntry(
21
+ "g" + index,
22
+ "g/" + entry.getHTMLFileName()
23
+ )
24
+ );
19
25
  }
20
26
 
21
- return manifestEntries.join( "" );
27
+ return manifestEntries.join("");
22
28
  }
23
29
 
24
30
  getSpineEntries() {
25
-
26
31
  const glossaryEntries = this.getGlossary().getEntries();
27
32
  const spineEntries = [];
28
33
 
29
- spineEntries.push( EBook.getSpineEntry( "g", "glossary.html" ) );
30
- for ( let index = 0; index < glossaryEntries.length; index++ ) {
31
- spineEntries.push( EBook.getSpineEntry( "g" + index ) );
34
+ spineEntries.push(EBook.getSpineEntry("g"));
35
+ for (let index = 0; index < glossaryEntries.length; index++) {
36
+ spineEntries.push(EBook.getSpineEntry("g" + index));
32
37
  }
33
38
 
34
- return spineEntries.join( "" );
35
-
39
+ return spineEntries.join("");
36
40
  }
37
-
38
41
  }
39
42
 
40
- export { GlossaryPages };
43
+ export { GlossaryPages };
@@ -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
- await new sharp(srcFileName)
67
+ await sharp(srcFileName)
63
68
  .resize({ width: 300 })
64
69
  .jpeg({ quality: 40 })
65
70
  .toFile(targetFileName);
66
71
 
67
72
  imageList.push(
68
- new Image(imagePrefix + "/" + filename, row["credit"])
73
+ new TaxonImage(imagePrefix + "/" + filename, row["credit"])
69
74
  );
70
75
  }
71
76
 
72
- this.#siteGenerator.copyIllustrations(Taxa.getFlowerColors());
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
  }
@@ -1,7 +1,5 @@
1
1
  import { EBookPage } from "../ebookpage.js";
2
2
  import { XHTML } from "../xhtml.js";
3
- // eslint-disable-next-line no-unused-vars
4
- import { Families } from "../../families.js";
5
3
 
6
4
  class PageListFamilies extends EBookPage {
7
5
  #families;
@@ -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
- constructor( outputDir, color ) {
9
- super( outputDir + "/" + color.getFileName(), color.getColorName( true ) + " Flowers" );
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 ( const taxon of this.#color.getTaxa() ) {
19
- links.push( XHTML.getLink( taxon.getFileName(), taxon.getName() ) );
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( "ol", XHTML.arrayToLI( links ) );
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
- static createPages( contentDir, taxa ) {
11
- new PageListFlowerTimeIndex( contentDir ).create();
12
- for ( let m1 = 1; m1 < 13; m1++ ) {
13
- new PageListFlowerTime( contentDir, taxa, m1 ).create();
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( EBook.getManifestEntry( "fm0", FN_FLOWER_TIME_INDEX ) );
22
- for ( let m1 = 1; m1 < 13; m1++ ) {
23
- manifestEntries.push( EBook.getManifestEntry( "fm" + m1, PageListFlowerTime.getFileNameBloomTime( m1 ) ) );
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( EBook.getSpineEntry( "fm0" ) );
34
- for ( let m1 = 1; m1 < 13; m1++ ) {
35
- spineEntries.push( EBook.getSpineEntry( "fm" + m1 ) );
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 ( let m1 = 1; m1 < 13; m1++ ) {
51
+ for (let m1 = 1; m1 < 13; m1++) {
45
52
  links.push(
46
53
  XHTML.getLink(
47
- PageListFlowerTime.getFileNameBloomTime( m1 ),
48
- DateUtils.getMonthName( m1 ) + " - " + DateUtils.getMonthName( ( m1 ) % 12 + 1 )
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( "ol", XHTML.arrayToLI( links ) );
61
+ return XHTML.wrap("ol", XHTML.arrayToLI(links));
53
62
  }
54
-
55
63
  }
56
64
 
57
65
  class PageListFlowerTimeIndex extends EBookPage {
58
-
59
- constructor( outputDir ) {
60
- super( outputDir + "/" + FN_FLOWER_TIME_INDEX, "Flowering Times" );
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( "h1", this.getTitle() );
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
- constructor( outputDir, taxa, month ) {
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( month ),
79
- "Flowering in " + DateUtils.getMonthName( month ) + " - " + DateUtils.getMonthName( month % 12 + 1 )
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
- static getFileNameBloomTime( m1 ) {
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
- const html = XHTML.textElement( "h1", this.getTitle() );
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 ( const taxon of this.#taxa.getTaxonList() ) {
115
+ for (const taxon of this.#taxa.getTaxonList()) {
97
116
  const m1 = taxon.getBloomStart();
98
117
  const m2 = taxon.getBloomEnd();
99
- if ( m1 && DateUtils.monthRangesOverlap( range, [ m1, m2 ] ) ) {
100
- links.push( XHTML.getLink( taxon.getFileName(), taxon.getName() ) );
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( "ol", XHTML.arrayToLI( links ) );
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 {Image[]} photos
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
- constructor( outputDir ) {
9
- super( outputDir + "/toc.xhtml", "Table of Contents" );
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
- let html = "<nav id=\"toc\" role=\"doc-toc\" epub:type=\"toc\">";
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( this.#getFlowerColorLinks() );
19
- mainLinks.push( this.#getFlowerTimeLinks() );
20
- mainLinks.push( XHTML.getLink( "./list_families.html", "All Families" ) );
21
- mainLinks.push( XHTML.getLink( "./list_species.html", "All Species" ) );
22
- mainLinks.push( XHTML.getLink( "./glossary.html", "Glossary" ) );
23
- html += XHTML.wrap( "ol", XHTML.arrayToLI( mainLinks ) );
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( "span", "Flower Color" );
35
+ const html = XHTML.textElement("span", "Flower Color");
32
36
  const links = [];
33
- for ( const colorName of Taxa.getFlowerColorNames() ) {
34
- links.push( XHTML.getLink( "list_fc_" + colorName + ".html", colorName ) );
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( "ol", XHTML.arrayToLI( links ) );
43
+ return html + XHTML.wrap("ol", XHTML.arrayToLI(links));
37
44
  }
38
45
 
39
46
  #getFlowerTimeLinks() {
40
- const html = XHTML.getLink( "fm.html", "Flowering Times" );
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 };
@@ -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 {*} config
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 colorName of Taxa.getFlowerColorNames()) {
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 colorName of Taxa.getFlowerColorNames()) {
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 colorName of Taxa.getFlowerColorNames()) {
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();
@@ -1,4 +1,4 @@
1
- class Image {
1
+ class TaxonImage {
2
2
  #src;
3
3
  #credit;
4
4
 
@@ -20,4 +20,4 @@ class Image {
20
20
  }
21
21
  }
22
22
 
23
- export { Image };
23
+ export { TaxonImage };
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
- constructor( dir ) {
9
-
10
- function readConfig( fileName ) {
11
- return JSON.parse( Files.read( fileName ) );
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( Config.getPackageDir() + "/data/exceptions.json" );
20
+ this.#exceptions = readConfig(
21
+ Config.getPackageDir() + "/data/exceptions.json"
22
+ );
16
23
 
17
24
  // 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;
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( this.#exceptions );
34
+ return Object.entries(this.#exceptions);
29
35
  }
30
36
 
31
- getValue( name, cat, subcat, defaultValue ) {
32
- const taxonData = this.#exceptions[ name ];
33
- if ( taxonData ) {
34
- const catData = taxonData[ cat ];
35
- if ( catData ) {
36
- const val = catData[ subcat ];
37
- return ( val === undefined ) ? defaultValue : val;
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
- hasException( name, cat, subcat ) {
44
- const taxonData = this.#exceptions[ name ];
45
- if ( taxonData ) {
46
- const catData = taxonData[ cat ];
47
- if ( catData ) {
48
- return catData[ subcat ] !== undefined;
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 };