@ca-plant-list/ca-plant-list 0.4.3 → 0.4.4

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.
@@ -10,158 +10,166 @@ import { TaxonPage } from "./pages/taxonpage.js";
10
10
  import { TOCPage } from "./pages/tocpage.js";
11
11
 
12
12
  class PlantBook extends EBook {
13
- #taxa;
14
- #glossary;
15
- #images;
16
-
17
- /**
18
- * @param {string} outputDir
19
- * @param {Config} config
20
- * @param {Taxa} taxa
21
- */
22
- constructor(outputDir, config, taxa) {
23
- super(
24
- outputDir,
25
- config.getConfigValue("ebook", "filename"),
26
- config.getConfigValue("ebook", "pub_id"),
27
- config.getConfigValue("ebook", "title")
28
- );
29
-
30
- this.#taxa = taxa;
31
- const generator = new EBookSiteGenerator(this.getContentDir());
32
- this.#glossary = new GlossaryPages(generator);
33
- this.#images = new Images(generator, this.getContentDir(), taxa);
13
+ #taxa;
14
+ #glossary;
15
+ #images;
16
+
17
+ /**
18
+ * @param {string} outputDir
19
+ * @param {Config} config
20
+ * @param {Taxa} taxa
21
+ */
22
+ constructor(outputDir, config, taxa) {
23
+ super(
24
+ outputDir,
25
+ getRequiredConfigValue(config, "filename"),
26
+ getRequiredConfigValue(config, "pub_id"),
27
+ getRequiredConfigValue(config, "title")
28
+ );
29
+
30
+ this.#taxa = taxa;
31
+ const generator = new EBookSiteGenerator(this.getContentDir());
32
+ this.#glossary = new GlossaryPages(generator);
33
+ this.#images = new Images(generator, this.getContentDir(), taxa);
34
+ }
35
+
36
+ async createPages() {
37
+ const contentDir = this.getContentDir();
38
+
39
+ await this.#images.createImages();
40
+
41
+ console.log("creating taxon pages");
42
+ const taxonList = this.#taxa.getTaxonList();
43
+ for (const taxon of taxonList) {
44
+ const name = taxon.getName();
45
+ new TaxonPage(
46
+ contentDir,
47
+ taxon,
48
+ this.#images.getTaxonImages(name)
49
+ ).create();
34
50
  }
35
51
 
36
- async createPages() {
37
- const contentDir = this.getContentDir();
38
-
39
- await this.#images.createImages();
40
-
41
- console.log("creating taxon pages");
42
- const taxonList = this.#taxa.getTaxonList();
43
- for (const taxon of taxonList) {
44
- const name = taxon.getName();
45
- new TaxonPage(
46
- contentDir,
47
- taxon,
48
- this.#images.getTaxonImages(name)
49
- ).create();
50
- }
51
-
52
- // Create lists.
53
- for (const color of this.#taxa.getFlowerColors()) {
54
- new PageListFlowerColor(contentDir, color).create();
55
- }
56
-
57
- PageListFlowers.createPages(contentDir, this.#taxa);
58
-
59
- new PageListFamilies(contentDir, this.#taxa.getFamilies()).create();
60
- for (const family of this.#taxa.getFamilies().getFamilies()) {
61
- const taxa = family.getTaxa();
62
- if (!taxa) {
63
- continue;
64
- }
65
- const name = family.getName();
66
- new PageListSpecies(
67
- contentDir,
68
- taxa,
69
- name + ".html",
70
- name
71
- ).create();
72
- }
73
- new PageListSpecies(
74
- contentDir,
75
- taxonList,
76
- "list_species.html",
77
- "All Species"
78
- ).create();
79
-
80
- this.#glossary.renderPages();
81
-
82
- new TOCPage(contentDir, this.#taxa).create();
52
+ // Create lists.
53
+ for (const color of this.#taxa.getFlowerColors()) {
54
+ new PageListFlowerColor(contentDir, color).create();
83
55
  }
84
56
 
85
- renderManifestEntries() {
86
- let xml = "";
87
-
88
- // Add lists.
89
- xml +=
90
- '<item id="lspecies" href="list_species.html" media-type="application/xhtml+xml" />';
91
- xml +=
92
- '<item id="lfamilies" href="list_families.html" media-type="application/xhtml+xml" />';
93
- for (const color of this.#taxa.getFlowerColors()) {
94
- xml +=
95
- '<item id="l' +
96
- color.getColorName() +
97
- '" href="' +
98
- color.getFileName() +
99
- '" media-type="application/xhtml+xml" />';
100
- }
101
-
102
- // Add family pages.
103
- for (const family of this.#taxa.getFamilies().getFamilies()) {
104
- const taxa = family.getTaxa();
105
- if (!taxa) {
106
- continue;
107
- }
108
- xml +=
109
- '<item id="fam' +
110
- family.getName() +
111
- '" href="' +
112
- family.getFileName() +
113
- '" media-type="application/xhtml+xml" />';
114
- }
115
-
116
- // Add taxon pages.
117
- const taxa = this.#taxa.getTaxonList();
118
- for (let index = 0; index < taxa.length; index++) {
119
- const taxon = taxa[index];
120
- xml +=
121
- '<item id="t' +
122
- index +
123
- '" href="' +
124
- taxon.getFileName() +
125
- '" media-type="application/xhtml+xml" />';
126
- }
127
-
128
- xml += PageListFlowers.getManifestEntries();
129
- xml += this.#glossary.getManifestEntries();
130
- xml += this.#images.getManifestEntries();
131
-
132
- return xml;
57
+ PageListFlowers.createPages(contentDir, this.#taxa);
58
+
59
+ new PageListFamilies(contentDir, this.#taxa.getFamilies()).create();
60
+ for (const family of this.#taxa.getFamilies().getFamilies()) {
61
+ const taxa = family.getTaxa();
62
+ if (!taxa) {
63
+ continue;
64
+ }
65
+ const name = family.getName();
66
+ new PageListSpecies(contentDir, taxa, name + ".html", name).create();
67
+ }
68
+ new PageListSpecies(
69
+ contentDir,
70
+ taxonList,
71
+ "list_species.html",
72
+ "All Species"
73
+ ).create();
74
+
75
+ this.#glossary.renderPages();
76
+
77
+ new TOCPage(contentDir, this.#taxa).create();
78
+ }
79
+
80
+ renderManifestEntries() {
81
+ let xml = "";
82
+
83
+ // Add lists.
84
+ xml +=
85
+ '<item id="lspecies" href="list_species.html" media-type="application/xhtml+xml" />';
86
+ xml +=
87
+ '<item id="lfamilies" href="list_families.html" media-type="application/xhtml+xml" />';
88
+ for (const color of this.#taxa.getFlowerColors()) {
89
+ xml +=
90
+ '<item id="l' +
91
+ color.getColorName() +
92
+ '" href="' +
93
+ color.getFileName() +
94
+ '" media-type="application/xhtml+xml" />';
133
95
  }
134
96
 
135
- renderSpineElements() {
136
- let xml = "";
97
+ // Add family pages.
98
+ for (const family of this.#taxa.getFamilies().getFamilies()) {
99
+ const taxa = family.getTaxa();
100
+ if (!taxa) {
101
+ continue;
102
+ }
103
+ xml +=
104
+ '<item id="fam' +
105
+ family.getName() +
106
+ '" href="' +
107
+ family.getFileName() +
108
+ '" media-type="application/xhtml+xml" />';
109
+ }
137
110
 
138
- // Add lists.
139
- for (const color of this.#taxa.getFlowerColors()) {
140
- xml += '<itemref idref="l' + color.getColorName() + '"/>';
141
- }
142
- xml += PageListFlowers.getSpineEntries();
111
+ // Add taxon pages.
112
+ const taxa = this.#taxa.getTaxonList();
113
+ for (let index = 0; index < taxa.length; index++) {
114
+ const taxon = taxa[index];
115
+ xml +=
116
+ '<item id="t' +
117
+ index +
118
+ '" href="' +
119
+ taxon.getFileName() +
120
+ '" media-type="application/xhtml+xml" />';
121
+ }
143
122
 
144
- xml += '<itemref idref="lfamilies"/>';
145
- xml += '<itemref idref="lspecies"/>';
123
+ xml += PageListFlowers.getManifestEntries();
124
+ xml += this.#glossary.getManifestEntries();
125
+ xml += this.#images.getManifestEntries();
146
126
 
147
- // Add families.
148
- for (const family of this.#taxa.getFamilies().getFamilies()) {
149
- const taxa = family.getTaxa();
150
- if (!taxa) {
151
- continue;
152
- }
153
- xml += '<itemref idref="fam' + family.getName() + '"/>';
154
- }
127
+ return xml;
128
+ }
155
129
 
156
- // Add taxa.
157
- for (let index = 0; index < this.#taxa.getTaxonList().length; index++) {
158
- xml += '<itemref idref="t' + index + '"/>';
159
- }
130
+ renderSpineElements() {
131
+ let xml = "";
160
132
 
161
- xml += this.#glossary.getSpineEntries();
133
+ // Add lists.
134
+ for (const color of this.#taxa.getFlowerColors()) {
135
+ xml += '<itemref idref="l' + color.getColorName() + '"/>';
136
+ }
137
+ xml += PageListFlowers.getSpineEntries();
138
+
139
+ xml += '<itemref idref="lfamilies"/>';
140
+ xml += '<itemref idref="lspecies"/>';
141
+
142
+ // Add families.
143
+ for (const family of this.#taxa.getFamilies().getFamilies()) {
144
+ const taxa = family.getTaxa();
145
+ if (!taxa) {
146
+ continue;
147
+ }
148
+ xml += '<itemref idref="fam' + family.getName() + '"/>';
149
+ }
162
150
 
163
- return xml;
151
+ // Add taxa.
152
+ for (let index = 0; index < this.#taxa.getTaxonList().length; index++) {
153
+ xml += '<itemref idref="t' + index + '"/>';
164
154
  }
155
+
156
+ xml += this.#glossary.getSpineEntries();
157
+
158
+ return xml;
159
+ }
160
+ }
161
+
162
+ /**
163
+ * @param {Config} config
164
+ * @param {string} name
165
+ * @returns {string}
166
+ */
167
+ function getRequiredConfigValue(config, name) {
168
+ const value = config.getConfigValue("ebook", name);
169
+ if (value === undefined) {
170
+ throw new Error();
171
+ }
172
+ return value;
165
173
  }
166
174
 
167
175
  export { PlantBook };
@@ -50,10 +50,9 @@ class GenericPage {
50
50
  // Include package markdown.
51
51
  const mdPath =
52
52
  Config.getPackageDir() + "/data/text/" + this.#baseFileName + ".md";
53
- if (Files.exists(mdPath)) {
54
- html += HTML.wrap("div", Markdown.fileToHTML(mdPath), {
55
- class: "section",
56
- });
53
+ const markdownHTML = Markdown.fileToHTML(mdPath);
54
+ if (markdownHTML) {
55
+ html += HTML.wrap("div", markdownHTML, { class: "section" });
57
56
  }
58
57
 
59
58
  return html;
package/lib/htmltaxon.js CHANGED
@@ -4,149 +4,144 @@ import { RarePlants } from "./rareplants.js";
4
4
  import { TextUtils } from "./textutils.js";
5
5
 
6
6
  /**
7
- * @type {Object<string,{title:string,data:function (Taxon):string}>}
7
+ * @type {Record<string,{title:string,data:function (Taxon):string}>}
8
8
  */
9
9
  const TAXA_LIST_COLS = {
10
- CESA: {
11
- title: "California",
12
- data: (t) => RarePlants.getCESADescription(t.getCESA()),
13
- },
14
- COMMON_NAME: {
15
- title: "Common Name",
16
- data: (t) => t.getCommonNames().join(", "),
17
- },
18
- CNPS_RANK: {
19
- title: "CNPS Rank",
20
- data: (t) =>
21
- HTML.getToolTip(
22
- HTML.textElement("span", t.getRPIRankAndThreat()),
23
- t.getRPIRankAndThreatTooltip()
24
- ),
25
- },
26
- FESA: {
27
- title: "Federal",
28
- data: (t) => RarePlants.getFESADescription(t.getFESA()),
29
- },
30
- SPECIES: {
31
- title: "Species",
32
- data: (t) => t.getHTMLLink(true, true),
33
- },
34
- SPECIES_BARE: {
35
- title: "Species",
36
- data: (t) => t.getHTMLLink(true, false),
37
- },
10
+ CESA: {
11
+ title: "California",
12
+ data: (t) => RarePlants.getCESADescription(t.getCESA()),
13
+ },
14
+ COMMON_NAME: {
15
+ title: "Common Name",
16
+ data: (t) => t.getCommonNames().join(", "),
17
+ },
18
+ CNPS_RANK: {
19
+ title: "CNPS Rank",
20
+ data: (t) =>
21
+ HTML.getToolTip(
22
+ HTML.textElement("span", t.getRPIRankAndThreat()),
23
+ t.getRPIRankAndThreatTooltip()
24
+ ),
25
+ },
26
+ FESA: {
27
+ title: "Federal",
28
+ data: (t) => RarePlants.getFESADescription(t.getFESA()),
29
+ },
30
+ SPECIES: {
31
+ title: "Species",
32
+ data: (t) => t.getHTMLLink(true, true),
33
+ },
34
+ SPECIES_BARE: {
35
+ title: "Species",
36
+ data: (t) => t.getHTMLLink(true, false),
37
+ },
38
38
  };
39
39
 
40
40
  const DEFAULT_TAXA_COLUMNS = [
41
- TAXA_LIST_COLS.SPECIES,
42
- TAXA_LIST_COLS.COMMON_NAME,
41
+ TAXA_LIST_COLS.SPECIES,
42
+ TAXA_LIST_COLS.COMMON_NAME,
43
43
  ];
44
44
 
45
45
  class HTMLTaxon {
46
- /**
47
- * @param {string[]|undefined} colors
48
- */
49
- static getFlowerColors(colors, includeColorLink = true) {
50
- let html = "";
51
- if (colors) {
52
- for (const color of colors) {
53
- const img = HTML.textElement("img", "", {
54
- src: "./i/f-" + color + ".svg",
55
- alt: color + " flowers",
56
- title: color,
57
- class: "flr-color",
58
- });
59
- if (includeColorLink) {
60
- html += HTML.wrap("a", img, {
61
- href: "./list_fc_" + color + ".html",
62
- });
63
- } else {
64
- html += img;
65
- }
66
- }
46
+ /**
47
+ * @param {string[]|undefined} colors
48
+ */
49
+ static getFlowerColors(colors, includeColorLink = true) {
50
+ let html = "";
51
+ if (colors) {
52
+ for (const color of colors) {
53
+ const img = HTML.textElement("img", "", {
54
+ src: "./i/f-" + color + ".svg",
55
+ alt: color + " flowers",
56
+ title: color,
57
+ class: "flr-color",
58
+ });
59
+ if (includeColorLink) {
60
+ html += HTML.wrap("a", img, {
61
+ href: "./list_fc_" + color + ".html",
62
+ });
63
+ } else {
64
+ html += img;
67
65
  }
68
- return html;
66
+ }
69
67
  }
68
+ return html;
69
+ }
70
70
 
71
- /**
72
- * @param {Taxon} taxon
73
- * @param {string} classNames
74
- * @param {boolean} [includeColorLink=true]
75
- */
76
- static getFlowerInfo(
77
- taxon,
78
- classNames = "section",
79
- includeColorLink = true
80
- ) {
81
- const lifeCycle = taxon.getLifeCycle();
82
- const colors = taxon.getFlowerColors();
83
- const monthStart = taxon.getBloomStart();
84
- const monthEnd = taxon.getBloomEnd();
71
+ /**
72
+ * @param {Taxon} taxon
73
+ * @param {string} classNames
74
+ * @param {boolean} [includeColorLink=true]
75
+ */
76
+ static getFlowerInfo(taxon, classNames = "section", includeColorLink = true) {
77
+ const lifeCycle = taxon.getLifeCycle();
78
+ const colors = taxon.getFlowerColors();
79
+ const monthStart = taxon.getBloomStart();
80
+ const monthEnd = taxon.getBloomEnd();
85
81
 
86
- const parts = [];
87
- if (lifeCycle) {
88
- const text =
89
- HTML.wrap("span", TextUtils.ucFirst(lifeCycle), "lc") + ".";
90
- parts.push(HTML.wrap("span", text, "lcs"));
91
- }
92
-
93
- if (colors || monthStart) {
94
- let html = "Flowers: ";
95
- html += this.getFlowerColors(colors, includeColorLink);
96
- if (monthStart && monthEnd) {
97
- html += HTML.wrap(
98
- "span",
99
- DateUtils.getMonthName(monthStart) +
100
- "-" +
101
- DateUtils.getMonthName(monthEnd),
102
- { class: "flr-time" }
103
- );
104
- }
105
- parts.push(HTML.wrap("span", html));
106
- }
107
- return HTML.wrap("div", parts.join(""), { class: classNames });
82
+ const parts = [];
83
+ if (lifeCycle) {
84
+ const text = HTML.wrap("span", TextUtils.ucFirst(lifeCycle), "lc") + ".";
85
+ parts.push(HTML.wrap("span", text, "lcs"));
108
86
  }
109
87
 
110
- /**
111
- * @param {Taxon} taxon
112
- */
113
- static getLink(taxon) {
114
- return (
115
- HTML.getLink(taxon.getFileName(), taxon.getName()) +
116
- this.getFlowerColors(taxon.getFlowerColors())
88
+ if (colors || monthStart) {
89
+ let html = "Flowers: ";
90
+ html += this.getFlowerColors(colors, includeColorLink);
91
+ if (monthStart && monthEnd) {
92
+ html += HTML.wrap(
93
+ "span",
94
+ DateUtils.getMonthName(monthStart) +
95
+ "-" +
96
+ DateUtils.getMonthName(monthEnd),
97
+ { class: "flr-time" }
117
98
  );
99
+ }
100
+ parts.push(HTML.wrap("span", html));
118
101
  }
102
+ return HTML.wrap("div", parts.join(""), { class: classNames });
103
+ }
119
104
 
120
- /**
121
- * @param {Taxon[]} taxa
122
- * @param {TaxaCol[]} [columns]
123
- */
124
- static getTaxaTable(taxa, columns = DEFAULT_TAXA_COLUMNS) {
125
- let html = "<table><thead>";
126
- for (const col of columns) {
127
- const className = col.class;
128
- const atts = className !== undefined ? className : {};
129
- html += HTML.textElement("th", col.title, atts);
130
- }
131
- html += "</thead>";
132
- html += "<tbody>";
105
+ /**
106
+ * @param {Taxon} taxon
107
+ */
108
+ static getLink(taxon) {
109
+ return (
110
+ HTML.getLink(taxon.getFileName(), taxon.getName()) +
111
+ this.getFlowerColors(taxon.getFlowerColors())
112
+ );
113
+ }
133
114
 
134
- for (const taxon of taxa) {
135
- html += "<tr>";
136
- for (const col of columns) {
137
- const data = col.data(taxon);
138
- const className = col.class;
139
- const atts = className !== undefined ? className : {};
140
- html += HTML.wrap("td", data, atts);
141
- }
142
- html += "</tr>";
143
- }
144
-
145
- html += "</tbody>";
146
- html += "</table>";
115
+ /**
116
+ * @param {Taxon[]} taxa
117
+ * @param {TaxaCol[]} [columns]
118
+ */
119
+ static getTaxaTable(taxa, columns = DEFAULT_TAXA_COLUMNS) {
120
+ let html = "<table><thead>";
121
+ for (const col of columns) {
122
+ const className = col.class;
123
+ const atts = className !== undefined ? className : {};
124
+ html += HTML.textElement("th", col.title, atts);
125
+ }
126
+ html += "</thead>";
127
+ html += "<tbody>";
147
128
 
148
- return html;
129
+ for (const taxon of taxa) {
130
+ html += "<tr>";
131
+ for (const col of columns) {
132
+ const data = col.data(taxon);
133
+ const className = col.class;
134
+ const atts = className !== undefined ? className : {};
135
+ html += HTML.wrap("td", data, atts);
136
+ }
137
+ html += "</tr>";
149
138
  }
139
+
140
+ html += "</tbody>";
141
+ html += "</table>";
142
+
143
+ return html;
144
+ }
150
145
  }
151
146
 
152
147
  export { HTMLTaxon, TAXA_LIST_COLS };
package/lib/index.d.ts CHANGED
@@ -13,26 +13,29 @@ export class Config {
13
13
  }
14
14
 
15
15
  export class CSV {
16
- static parseFile(dir: string, fileName: string);
16
+ static parseFile(dir: string, fileName: string): void;
17
17
  }
18
18
 
19
19
  export class ErrorLog {
20
20
  constructor(fileName: string, echo?: boolean);
21
- log(...msg: string[]);
21
+ log(...msg: string[]): void;
22
22
  write(): void;
23
23
  }
24
24
 
25
25
  export class Exceptions {
26
26
  constructor(dataDir: string);
27
- hasException(name: string, cat: string, subcat: string);
27
+ hasException(name: string, cat: string, subcat: string): boolean;
28
28
  }
29
29
 
30
30
  export class Files {
31
31
  static exists(fileName: string): boolean;
32
- static async fetch(url: string | URL, targetFileName: string | undefined);
33
- static mkdir(dir: string);
34
- static rmDir(dir: string);
35
- static write(fileName: string, data: string, overwrite: boolean);
32
+ static fetch(
33
+ url: string | URL,
34
+ targetFileName: string | undefined
35
+ ): Promise<Headers>;
36
+ static mkdir(dir: string): void;
37
+ static rmDir(dir: string): void;
38
+ static write(fileName: string, data: string, overwrite: boolean): void;
36
39
  }
37
40
 
38
41
  export class Program {
@@ -42,13 +45,13 @@ export class Program {
42
45
 
43
46
  export class Taxa {
44
47
  constructor(
45
- inclusionList: Object<string, TaxonData> | true,
48
+ inclusionList: Record<string, TaxonData> | true,
46
49
  errorLog: ErrorLog,
47
50
  showFlowerErrors: boolean,
48
51
  taxonFactory?: (td: TaxonData, g: Genera) => Taxon,
49
52
  extraTaxa?: TaxonData[],
50
53
  extraSynonyms?: SynonymData[]
51
54
  );
52
- getTaxon(string): Taxon;
55
+ getTaxon(name: string): Taxon;
53
56
  getTaxonList(): Taxon[];
54
57
  }
package/lib/markdown.js CHANGED
@@ -6,8 +6,12 @@ class Markdown {
6
6
 
7
7
  /**
8
8
  * @param {string} filePath
9
+ * @returns {string|undefined}
9
10
  */
10
11
  static fileToHTML(filePath) {
12
+ if (!Files.exists(filePath)) {
13
+ return;
14
+ }
11
15
  return this.strToHTML(Files.read(filePath));
12
16
  }
13
17