@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.
Files changed (94) hide show
  1. package/.vscode/settings.json +7 -1
  2. package/data/synonyms.csv +109 -3
  3. package/data/taxa.csv +65 -29
  4. package/data/text/Antennaria-media.md +1 -0
  5. package/data/text/Antennaria-rosea-subsp-rosea.md +1 -0
  6. package/data/text/Antirrhinum-thompsonii.md +1 -0
  7. package/data/text/Calyptridium-monospermum.md +1 -0
  8. package/data/text/Calyptridium-umbellatum.md +1 -0
  9. package/data/text/Camassia-leichtlinii-subsp-suksdorfii.md +1 -0
  10. package/data/text/Camassia-quamash-subsp-breviflora.md +1 -0
  11. package/data/text/Clarkia-affinis.md +1 -0
  12. package/data/text/Clarkia-breweri.md +1 -0
  13. package/data/text/Clarkia-concinna-subsp-automixa.md +1 -0
  14. package/data/text/Clarkia-modesta.md +1 -0
  15. package/data/text/Clarkia-purpurea-subsp-quadrivulnera.md +1 -0
  16. package/data/text/Clarkia-rubicunda.md +1 -0
  17. package/data/text/Delphinium-californicum-subsp-californicum.md +1 -1
  18. package/data/text/Delphinium-californicum-subsp-interius.md +1 -0
  19. package/data/text/Delphinium-glaucum.md +1 -0
  20. package/data/text/Delphinium-hesperium-subsp-hesperium.md +1 -1
  21. package/data/text/Delphinium-hesperium-subsp-pallescens.md +1 -0
  22. package/data/text/Delphinium-nuttallianum.md +1 -0
  23. package/data/text/Delphinium-parryi-subsp-parryi.md +1 -0
  24. package/data/text/Drymocallis-glandulosa-var-glandulosa.md +1 -0
  25. package/data/text/Drymocallis-lactea-var-austiniae.md +1 -0
  26. package/data/text/Erigeron-compositus.md +1 -0
  27. package/data/text/Erigeron-glacialis-var-glacialis.md +1 -0
  28. package/data/text/Erythranthe-breweri.md +1 -0
  29. package/data/text/Erythranthe-erubescens.md +1 -0
  30. package/data/text/Erythranthe-moschata.md +1 -0
  31. package/data/text/Erythranthe-primuloides.md +1 -0
  32. package/data/text/Erythranthe-tilingii.md +1 -0
  33. package/data/text/Lilium-pardalinum-subsp-shastense.md +1 -0
  34. package/data/text/Logfia-filaginoides.md +1 -0
  35. package/data/text/Logfia-gallica.md +1 -0
  36. package/data/text/Malacothamnus-arcuatus-var-elmeri.md +1 -0
  37. package/data/text/Malacothamnus-fremontii-var-fremontii.md +1 -0
  38. package/data/text/Navarretia-leptalea-subsp-bicolor.md +1 -0
  39. package/data/text/Navarretia-leptalea-subsp-leptalea.md +1 -0
  40. package/data/text/Polemonium-californicum.md +1 -0
  41. package/data/text/Polemonium-pulcherrimum-var-pulcherrimum.md +1 -0
  42. package/data/text/Primula-jeffreyi.md +1 -0
  43. package/data/text/Primula-tetrandra.md +1 -0
  44. package/data/text/Trifolium-obtusiflorum.md +1 -0
  45. package/data/text/Trifolium-willdenovii.md +1 -0
  46. package/lib/basepagerenderer.js +3 -4
  47. package/lib/config.js +42 -19
  48. package/lib/csv.js +54 -36
  49. package/lib/ebook/ebook.js +84 -57
  50. package/lib/ebook/ebookpage.js +22 -11
  51. package/lib/ebook/ebooksitegenerator.js +36 -14
  52. package/lib/ebook/glossarypages.js +20 -17
  53. package/lib/ebook/images.js +59 -42
  54. package/lib/ebook/pages/page_list_families.js +0 -2
  55. package/lib/ebook/pages/page_list_flower_color.js +14 -9
  56. package/lib/ebook/pages/page_list_flowers.js +59 -41
  57. package/lib/ebook/pages/page_list_species.js +15 -9
  58. package/lib/ebook/pages/taxonpage.js +3 -6
  59. package/lib/ebook/pages/tocpage.js +26 -20
  60. package/lib/ebook/plantbook.js +6 -13
  61. package/lib/ebook/{image.js → taxonimage.js} +2 -2
  62. package/lib/ebook/xhtml.js +3 -5
  63. package/lib/exceptions.js +42 -26
  64. package/lib/externalsites.js +11 -4
  65. package/lib/families.js +10 -10
  66. package/lib/flowercolor.js +42 -0
  67. package/lib/genera.js +13 -23
  68. package/lib/genericpage.js +38 -18
  69. package/lib/html.js +11 -23
  70. package/lib/htmltaxon.js +114 -14
  71. package/lib/index.d.ts +54 -0
  72. package/lib/index.js +2 -30
  73. package/lib/jekyll.js +49 -21
  74. package/lib/jepson.js +7 -8
  75. package/lib/markdown.js +13 -9
  76. package/lib/pagerenderer.js +162 -82
  77. package/lib/plants/glossary.js +14 -14
  78. package/lib/program.js +47 -0
  79. package/lib/rareplants.js +44 -30
  80. package/lib/sitegenerator.js +41 -24
  81. package/lib/taxa.js +25 -142
  82. package/lib/taxon.js +3 -5
  83. package/lib/web/glossarypages.js +37 -18
  84. package/lib/web/pagetaxon.js +1 -5
  85. package/package.json +5 -3
  86. package/schemas/exceptions.schema.json +57 -0
  87. package/scripts/build-ebook.js +39 -48
  88. package/scripts/build-site.js +49 -28
  89. package/types/classes.d.ts +154 -0
  90. package/lib/commandandtaxaprocessor.js +0 -25
  91. package/lib/commandprocessor.js +0 -108
  92. package/lib/generictaxaloader.js +0 -48
  93. package/lib/taxaloader.js +0 -48
  94. package/lib/taxaprocessor.js +0 -34
@@ -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 { Taxa } from "../taxa.js";
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
- constructor( siteGenerator, contentDir, taxa ) {
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( photoDirSrc, { recursive: true } );
31
- fs.mkdirSync( photoDirTarget, { recursive: true } );
32
-
33
- const rows = CSV.parseFile( Config.getPackageDir() + "/data", "photos.csv" );
34
- for ( const row of rows ) {
35
-
36
- const name = row[ "taxon_name" ];
37
- const taxon = this.#taxa.getTaxon( name );
38
- if ( !taxon ) {
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[ name ];
43
- if ( !imageList ) {
48
+ let imageList = this.#images[name];
49
+ if (!imageList) {
44
50
  imageList = [];
45
- this.#images[ name ] = imageList;
51
+ this.#images[name] = imageList;
46
52
  }
47
53
 
48
- const src = new URL( row[ "source" ] );
49
- const parts = path.parse( src.pathname ).dir.split( "/" );
50
- const prefix = src.host.includes( "calflora" ) ? "cf-" : "inat-";
51
- const filename = prefix + parts.slice( -1 )[ 0 ] + ".jpg";
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 ( !fs.existsSync( srcFileName ) ) {
61
+ if (!fs.existsSync(srcFileName)) {
56
62
  // File is not there; retrieve it.
57
- console.log( "retrieving " + srcFileName );
58
- await Files.fetch( src, srcFileName );
63
+ console.log("retrieving " + srcFileName);
64
+ await Files.fetch(src, srcFileName);
59
65
  }
60
66
 
61
- await new sharp( srcFileName ).resize( { width: 300 } ).jpeg( { quality: 40 } ).toFile( targetFileName );
62
-
63
- imageList.push( new Image( imagePrefix + "/" + filename, row[ "credit" ] ) );
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( Taxa.getFlowerColors() );
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( this.#contentDir + "/i" ).sort();
75
-
76
- for ( let index = 0; index < images.length; index++ ) {
77
- const fileName = images[ index ];
78
- const ext = fileName.split( "." )[ 1 ];
79
- entries.push( EBook.getManifestEntry( "i" + index, "i/" + fileName, EBook.getMediaTypeForExt( ext ) ) );
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
- getTaxonImages( name ) {
86
- return this.#images[ name ];
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 };
@@ -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 };
@@ -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
- constructor( outputDir, taxa, filename, title ) {
9
- super( outputDir + "/" + filename, title );
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 ( const taxon of this.#taxa ) {
19
- links.push( XHTML.getLink( taxon.getFileName(), taxon.getName() ) );
24
+ for (const taxon of this.#taxa) {
25
+ links.push(HTMLTaxon.getLink(taxon));
20
26
  }
21
27
 
22
- return html + XHTML.wrap( "ol", XHTML.arrayToLI( links ) );
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 {Image[]} photos
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
- 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 };
@@ -1,7 +1,5 @@
1
- import { HTML } from "@ca-plant-list/ca-plant-list";
1
+ import { HTML } from "../html.js";
2
2
 
3
- class XHTML extends HTML {
3
+ class XHTML extends HTML {}
4
4
 
5
- }
6
-
7
- export { XHTML };
5
+ export { XHTML };