@ca-plant-list/ca-plant-list 0.4.22 → 0.4.23

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 (41) hide show
  1. package/lib/basepagerenderer.js +10 -4
  2. package/lib/ebook/images.js +3 -3
  3. package/lib/ebook/pages/{page_list_families.js → pageListFamilies.js} +1 -1
  4. package/lib/ebook/pages/{page_list_flowers.js → pageListFlowers.js} +2 -2
  5. package/lib/ebook/pages/page_list_species.js +1 -1
  6. package/lib/ebook/pages/taxonpage.js +1 -1
  7. package/lib/ebook/pages/tocpage.js +2 -2
  8. package/lib/ebook/plantbook.js +3 -3
  9. package/lib/externalsites.js +86 -37
  10. package/lib/flowercolor.js +2 -2
  11. package/lib/genera.js +4 -4
  12. package/lib/html.js +7 -8
  13. package/lib/htmltaxon.js +106 -27
  14. package/lib/index.d.ts +51 -16
  15. package/lib/index.js +3 -3
  16. package/lib/pagerenderer.js +6 -6
  17. package/lib/taxonomy/families.js +104 -0
  18. package/lib/{taxa.js → taxonomy/taxa.js} +18 -18
  19. package/lib/{taxon.js → taxonomy/taxon.js} +9 -108
  20. package/lib/taxonomy/taxonomy.js +17 -0
  21. package/lib/tools/calflora.js +2 -2
  22. package/lib/tools/calscape.js +3 -3
  23. package/lib/tools/cch2.js +3 -3
  24. package/lib/tools/fna.js +2 -2
  25. package/lib/tools/inat.js +3 -3
  26. package/lib/tools/jepsoneflora.js +1 -1
  27. package/lib/tools/rpi.js +3 -3
  28. package/lib/tools/supplementaltext.js +1 -1
  29. package/lib/types.js +10 -0
  30. package/lib/utils/inat-tools.js +2 -2
  31. package/lib/web/pageFamily.js +146 -0
  32. package/lib/web/pagetaxon.js +20 -56
  33. package/package.json +1 -1
  34. package/scripts/build-ebook.js +4 -4
  35. package/scripts/build-site.js +3 -3
  36. package/scripts/cpl-photos.js +1 -1
  37. package/scripts/cpl-tools.js +1 -1
  38. package/scripts/inatobsphotos.js +2 -2
  39. package/scripts/inattaxonphotos.js +2 -2
  40. package/lib/families.js +0 -243
  41. package/lib/jepson.js +0 -17
package/lib/tools/fna.js CHANGED
@@ -12,7 +12,7 @@ export class FNA {
12
12
  /**
13
13
  * @param {string} toolsDataDir
14
14
  * @param {string} dataDir
15
- * @param {import("../taxa.js").Taxa} taxa
15
+ * @param {import("../types.js").Taxa} taxa
16
16
  * @param {import("../errorlog.js").ErrorLog} errorLog
17
17
  * @param {boolean} update
18
18
  */
@@ -44,7 +44,7 @@ export class FNA {
44
44
  }
45
45
 
46
46
  /**
47
- * @param {import("../taxon.js").Taxon} taxon
47
+ * @param {import("../types.js").Taxon} taxon
48
48
  * @param {FNATaxa} fnaTaxa
49
49
  * @returns {string|undefined}
50
50
  */
package/lib/tools/inat.js CHANGED
@@ -21,7 +21,7 @@ export class INat {
21
21
  /**
22
22
  * @param {string} toolsDataDir
23
23
  * @param {string} dataDir
24
- * @param {import("../taxa.js").Taxa} taxa
24
+ * @param {import("../types.js").Taxa} taxa
25
25
  * @param {import("../exceptions.js").Exceptions} exceptions
26
26
  * @param {import("../errorlog.js").ErrorLog} errorLog
27
27
  * @param {string} csvFileName
@@ -115,7 +115,7 @@ export class INat {
115
115
 
116
116
  /**
117
117
  *
118
- * @param {import("../taxa.js").Taxa} taxa
118
+ * @param {import("../types.js").Taxa} taxa
119
119
  * @param {import("../exceptions.js").Exceptions} exceptions
120
120
  * @param {import("../errorlog.js").ErrorLog} errorLog
121
121
  */
@@ -168,7 +168,7 @@ export class INat {
168
168
 
169
169
  /**
170
170
  *
171
- * @param {import("../taxa.js").Taxa} taxa
171
+ * @param {import("../types.js").Taxa} taxa
172
172
  * @param {import("../exceptions.js").Exceptions} exceptions
173
173
  * @param {import("../errorlog.js").ErrorLog} errorLog
174
174
  * @param {string} name
@@ -54,7 +54,7 @@ export class JepsonEFlora {
54
54
 
55
55
  /**
56
56
  * @param {string} toolsDataDir
57
- * @param {import("../taxa.js").Taxa} taxa
57
+ * @param {import("../taxonomy/taxa.js").Taxa} taxa
58
58
  * @param {import("../errorlog.js").ErrorLog} errorLog
59
59
  */
60
60
  constructor(toolsDataDir, taxa, errorLog) {
package/lib/tools/rpi.js CHANGED
@@ -12,7 +12,7 @@ class RPI {
12
12
 
13
13
  /**
14
14
  * @param {string} toolsDataDir
15
- * @param {import("../taxa.js").Taxa} taxa
15
+ * @param {import("../types.js").Taxa} taxa
16
16
  * @param {import("../config.js").Config} config
17
17
  * @param {import("../exceptions.js").Exceptions} exceptions
18
18
  * @param {import("../errorlog.js").ErrorLog} errorLog
@@ -202,7 +202,7 @@ class RPI {
202
202
  }
203
203
 
204
204
  /**
205
- * @param {import("../taxa.js").Taxa} taxa
205
+ * @param {import("../types.js").Taxa} taxa
206
206
  * @param {import("../config.js").Config} config
207
207
  * @param {import("../exceptions.js").Exceptions} exceptions
208
208
  * @param {import("../errorlog.js").ErrorLog} errorLog
@@ -366,7 +366,7 @@ class RPI {
366
366
 
367
367
  /**
368
368
  * @param {string} toolsDataDir
369
- * @param {import("../taxa.js").Taxa} taxa
369
+ * @param {import("../types.js").Taxa} taxa
370
370
  * @param {import("../exceptions.js").Exceptions} exceptions
371
371
  * @param {import("../errorlog.js").ErrorLog} errorLog
372
372
  */
@@ -5,7 +5,7 @@ const VALID_EXTENSIONS = new Set(["md", "footer.md"]);
5
5
  export class SupplementalText {
6
6
  /**
7
7
  *
8
- * @param {import("../taxa.js").Taxa} taxa
8
+ * @param {import("../types.js").Taxa} taxa
9
9
  * @param {import("../errorlog.js").ErrorLog} errorLog
10
10
  */
11
11
  static analyze(taxa, errorLog) {
package/lib/types.js ADDED
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Classes
3
+ * @typedef {import("./config.js").Config} Config
4
+ * @typedef {import("./taxonomy/families.js").Families} Families
5
+ * @typedef {import("./taxonomy/families.js").Family} Family
6
+ * @typedef {import("./taxonomy/taxa.js").Taxa} Taxa
7
+ * @typedef {import("./index.js").TaxaColDef<import("./types.js").Taxon>} TaxaColDef
8
+ * @typedef {import("./taxonomy/taxon.js").Taxon} Taxon
9
+ * @typedef {import("./taxonomy/taxonomy.js").Taxonomy} Taxonomy
10
+ */
@@ -41,7 +41,7 @@ import { chunk, sleep } from "../util.js";
41
41
  const ALLOWED_LICENSE_CODES = ["cc0", "cc-by", "cc-by-nc"];
42
42
 
43
43
  /**
44
- * @param {import("../taxon.js").Taxon[]} taxa
44
+ * @param {import("../types.js").Taxon[]} taxa
45
45
  * @return {Promise<InatApiTaxon[]>}
46
46
  */
47
47
  async function fetchInatTaxa(taxa) {
@@ -57,7 +57,7 @@ async function fetchInatTaxa(taxa) {
57
57
  }
58
58
 
59
59
  /**
60
- * @param {import("../taxon.js").Taxon[]} taxaToUpdate
60
+ * @param {import("../types.js").Taxon[]} taxaToUpdate
61
61
  * @returns {Promise<Map<string,InatPhotoInfo[]>>}
62
62
  */
63
63
  export async function getTaxonPhotos(taxaToUpdate) {
@@ -0,0 +1,146 @@
1
+ import { ExternalSites } from "../externalsites.js";
2
+ import { GenericPage } from "../genericpage.js";
3
+ import { HTML } from "../html.js";
4
+ import { HTMLTaxon } from "../htmltaxon.js";
5
+ import { Sections } from "../taxonomy/families.js";
6
+
7
+ export class PageFamilyList extends GenericPage {
8
+ #families;
9
+
10
+ /**
11
+ * @param {string} outputDir
12
+ * @param {import("../types.js").Family[]} families
13
+ */
14
+ constructor(outputDir, families) {
15
+ super(outputDir, "Families", "list_families");
16
+ this.#families = families;
17
+ }
18
+
19
+ /**
20
+ * @param {import("../types.js").TaxaColDef[]} [taxaColumns]
21
+ */
22
+ render(taxaColumns) {
23
+ let html = this.getDefaultIntro();
24
+
25
+ const sections = Sections.getSections();
26
+ const sectionLinks = [];
27
+ for (const name of Object.keys(sections).sort()) {
28
+ const taxa = sections[name];
29
+
30
+ // Render the section page.
31
+ new PageSection(this.getOutputDir(), name, taxa).render(
32
+ taxaColumns,
33
+ );
34
+
35
+ // Render the link.
36
+ const href = "./" + name + ".html";
37
+ sectionLinks.push(
38
+ HTML.getLink(href, name) + " (" + taxa.length + ")",
39
+ );
40
+ }
41
+ html += HTML.wrap("ul", HTML.arrayToLI(sectionLinks), {
42
+ class: "listmenu",
43
+ });
44
+
45
+ html += "<table>";
46
+ html += "<thead>";
47
+ html += HTML.textElement("th", "Family");
48
+ html += HTML.textElement("th", "Number of Species", { class: "right" });
49
+ html += "</thead>";
50
+
51
+ html += "<tbody>";
52
+ for (const family of this.#families) {
53
+ const taxa = family.getTaxa();
54
+ if (!taxa) {
55
+ continue;
56
+ }
57
+ let cols = HTML.wrap(
58
+ "td",
59
+ HTML.getLink("./" + family.getFileName(), family.getName()),
60
+ );
61
+ cols += HTML.wrap("td", taxa.length, { class: "right" });
62
+ html += HTML.wrap("tr", cols);
63
+ }
64
+ html += "</tbody>";
65
+
66
+ html += "</table>";
67
+
68
+ this.writeFile(html);
69
+ }
70
+
71
+ /**
72
+ * @param {string} outputDir
73
+ * @param {import("../types.js").TaxaColDef[]} [taxaColumns]
74
+ */
75
+ renderPages(outputDir, taxaColumns) {
76
+ for (const family of this.#families) {
77
+ if (family.getTaxa()) {
78
+ new PageFamily(outputDir, family).render(taxaColumns);
79
+ }
80
+ }
81
+ }
82
+ }
83
+
84
+ class PageFamily extends GenericPage {
85
+ #family;
86
+
87
+ /**
88
+ * @param {string} outputDir
89
+ * @param {import("../types.js").Family} family
90
+ */
91
+ constructor(outputDir, family) {
92
+ super(outputDir, family.getName(), family.getBaseFileName());
93
+ this.#family = family;
94
+ }
95
+
96
+ /**
97
+ * @param {import("../types.js").TaxaColDef[]} [columns]
98
+ */
99
+ render(columns) {
100
+ let html = this.getDefaultIntro();
101
+
102
+ const jepsonLink = ExternalSites.getJepsonRefLink(this.#family);
103
+ if (jepsonLink) {
104
+ html += HTML.wrap(
105
+ "div",
106
+ HTML.getLink(jepsonLink, "Jepson eFlora", {}, true),
107
+ {
108
+ class: "section",
109
+ },
110
+ );
111
+ }
112
+
113
+ const taxa = this.#family.getTaxa();
114
+ if (!taxa) {
115
+ throw new Error();
116
+ }
117
+ html += HTMLTaxon.getTaxaTable(taxa, columns);
118
+
119
+ this.writeFile(html);
120
+ }
121
+ }
122
+
123
+ class PageSection extends GenericPage {
124
+ #taxa;
125
+
126
+ /**
127
+ * @param {string} outputDir
128
+ * @param {string} name
129
+ * @param {import("../types.js").Taxon[]} taxa
130
+ */
131
+ constructor(outputDir, name, taxa) {
132
+ super(outputDir, name, name);
133
+ this.#taxa = taxa;
134
+ }
135
+
136
+ /**
137
+ * @param {import("../types.js").TaxaColDef[]} [columns]
138
+ */
139
+ render(columns) {
140
+ let html = this.getDefaultIntro();
141
+
142
+ html += HTMLTaxon.getTaxaTable(this.#taxa, columns);
143
+
144
+ this.writeFile(html);
145
+ }
146
+ }
@@ -1,7 +1,5 @@
1
- import { Jepson } from "../jepson.js";
2
1
  import { RarePlants } from "../rareplants.js";
3
2
  import { GenericPage } from "../genericpage.js";
4
- import { ExternalSites } from "../externalsites.js";
5
3
  import { HTML } from "../html.js";
6
4
  import { HTMLTaxon } from "../htmltaxon.js";
7
5
 
@@ -12,7 +10,7 @@ export class PageTaxon extends GenericPage {
12
10
  /**
13
11
  * @param {string} outputDir
14
12
  * @param {import("../config.js").Config} config
15
- * @param {import("../taxon.js").Taxon} taxon
13
+ * @param {import("../types.js").Taxon} taxon
16
14
  */
17
15
  constructor(outputDir, config, taxon) {
18
16
  super(outputDir, taxon.getName(), taxon.getBaseFileName());
@@ -21,23 +19,19 @@ export class PageTaxon extends GenericPage {
21
19
  }
22
20
 
23
21
  #getInfoLinks() {
22
+ /** @type {string[]} */
24
23
  const links = [];
25
- const jepsonID = this.#taxon.getJepsonID();
26
- if (jepsonID) {
27
- links.push(Jepson.getEFloraLink(jepsonID));
28
- }
29
- const cfLink = this.#taxon.getCalfloraTaxonLink();
30
- if (cfLink) {
31
- links.push(cfLink);
32
- }
33
- const iNatLink = this.#taxon.getINatTaxonLink();
34
- if (iNatLink) {
35
- links.push(iNatLink);
36
- }
37
- const rpiLink = this.#taxon.getRPITaxonLink();
38
- if (rpiLink) {
39
- links.push(rpiLink);
40
- }
24
+ HTMLTaxon.addRefLink(links, this.#taxon, "jepson");
25
+ HTMLTaxon.addRefLink(links, this.#taxon, "calflora");
26
+ HTMLTaxon.addRefLink(
27
+ links,
28
+ this.#taxon,
29
+ "inat",
30
+ this.#taxon.getINatSyn()
31
+ ? " (" + this.#taxon.getINatSyn() + ")"
32
+ : "",
33
+ );
34
+ HTMLTaxon.addRefLink(links, this.#taxon, "rpi");
41
35
  HTMLTaxon.addRefLink(links, this.#taxon, "fna");
42
36
  HTMLTaxon.addRefLink(links, this.#taxon, "cch");
43
37
  HTMLTaxon.addRefLink(links, this.#taxon, "calscape");
@@ -45,42 +39,11 @@ export class PageTaxon extends GenericPage {
45
39
  }
46
40
 
47
41
  #getObsLinks() {
42
+ /** @type {string[]} */
48
43
  const links = [];
49
- links.push(
50
- HTML.getLink(
51
- "https://www.calflora.org/entry/observ.html?track=m#srch=t&grezc=5&cols=b&lpcli=t&cc=" +
52
- this.#config.getCountyCodes().join("!") +
53
- "&incobs=f&taxon=" +
54
- this.#taxon.getCalfloraName().replaceAll(" ", "+"),
55
- "Calflora",
56
- {},
57
- true,
58
- ),
59
- );
60
- const iNatID = this.#taxon.getINatID();
61
- if (iNatID) {
62
- links.push(
63
- HTML.getLink(
64
- ExternalSites.getInatObsLink({
65
- project_id: this.#config.getConfigValue(
66
- "inat",
67
- "project_id",
68
- ),
69
- subview: "map",
70
- taxon_id: iNatID,
71
- }),
72
- "iNaturalist",
73
- {},
74
- true,
75
- ),
76
- );
77
- }
78
- HTMLTaxon.addLink(
79
- links,
80
- ExternalSites.getCCH2ObsLink(this.#taxon, this.#config),
81
- "CCH2",
82
- );
83
-
44
+ HTMLTaxon.addObsLink(links, this.#taxon, this.#config, "inat");
45
+ HTMLTaxon.addObsLink(links, this.#taxon, this.#config, "calflora");
46
+ HTMLTaxon.addObsLink(links, this.#taxon, this.#config, "cch");
84
47
  return links;
85
48
  }
86
49
 
@@ -97,7 +60,7 @@ export class PageTaxon extends GenericPage {
97
60
  }) +
98
61
  HTML.getToolTip(
99
62
  cnpsRank,
100
- this.#taxon.getRPIRankAndThreatTooltip(),
63
+ HTMLTaxon.getRPIRankAndThreatTooltip(this.#taxon),
101
64
  ),
102
65
  );
103
66
  if (this.#taxon.getCESA()) {
@@ -120,7 +83,8 @@ export class PageTaxon extends GenericPage {
120
83
  if (taxa.length > 1) {
121
84
  for (const taxon of taxa) {
122
85
  links.push(
123
- taxon.getHTMLLink(
86
+ HTMLTaxon.getHTMLLink(
87
+ taxon,
124
88
  taxon.getName() !== this.#taxon.getName(),
125
89
  ),
126
90
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ca-plant-list/ca-plant-list",
3
- "version": "0.4.22",
3
+ "version": "0.4.23",
4
4
  "description": "Tools to create Jekyll files for a website listing plants in an area of California.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -5,7 +5,7 @@ import { ErrorLog } from "../lib/errorlog.js";
5
5
  import { Files } from "../lib/files.js";
6
6
  import { PlantBook } from "../lib/ebook/plantbook.js";
7
7
  import { Program } from "../lib/program.js";
8
- import { Taxa } from "../lib/taxa.js";
8
+ import { Taxa } from "../lib/taxonomy/taxa.js";
9
9
 
10
10
  const program = Program.getProgram();
11
11
  program
@@ -33,7 +33,7 @@ async function build(options) {
33
33
  await buildBook(
34
34
  outputBase + suffix,
35
35
  path,
36
- options.showFlowerErrors
36
+ options.showFlowerErrors,
37
37
  );
38
38
  }
39
39
  }
@@ -42,7 +42,7 @@ async function build(options) {
42
42
  await buildBook(
43
43
  options.outputdir,
44
44
  options.datadir,
45
- options.showFlowerErrors
45
+ options.showFlowerErrors,
46
46
  );
47
47
  }
48
48
  }
@@ -58,7 +58,7 @@ async function buildBook(outputDir, dataDir, showFlowerErrors) {
58
58
  const taxa = new Taxa(
59
59
  Program.getIncludeList(dataDir),
60
60
  errorLog,
61
- showFlowerErrors
61
+ showFlowerErrors,
62
62
  );
63
63
 
64
64
  const config = new Config(dataDir);
@@ -6,7 +6,7 @@ import { Config } from "../lib/config.js";
6
6
  import { PageRenderer } from "../lib/pagerenderer.js";
7
7
  import { Files } from "../lib/files.js";
8
8
  import { Program } from "../lib/program.js";
9
- import { Taxa } from "../lib/taxa.js";
9
+ import { Taxa } from "../lib/taxonomy/taxa.js";
10
10
  import { ErrorLog } from "../lib/errorlog.js";
11
11
 
12
12
  class JekyllRenderer {
@@ -45,7 +45,7 @@ class JekyllRenderer {
45
45
  options.push("--config", `"${configFiles.join()}"`);
46
46
 
47
47
  const result = child_process.execSync(
48
- "bundle exec jekyll build " + options.join(" ")
48
+ "bundle exec jekyll build " + options.join(" "),
49
49
  );
50
50
  console.log(result.toString());
51
51
  }
@@ -60,7 +60,7 @@ async function build(options) {
60
60
  const taxa = new Taxa(
61
61
  Program.getIncludeList(options.datadir),
62
62
  errorLog,
63
- options.showFlowerErrors
63
+ options.showFlowerErrors,
64
64
  );
65
65
  PageRenderer.render(options.outputdir, new Config(options.datadir), taxa);
66
66
  errorLog.write();
@@ -3,7 +3,7 @@
3
3
  import path from "path";
4
4
  import { ErrorLog } from "../lib/errorlog.js";
5
5
  import { Program } from "../lib/program.js";
6
- import { Taxa } from "../lib/taxa.js";
6
+ import { Taxa } from "../lib/taxonomy/taxa.js";
7
7
  import { getTaxonPhotos } from "../lib/utils/inat-tools.js";
8
8
  import { existsSync } from "fs";
9
9
  import { CSV } from "../lib/csv.js";
@@ -10,7 +10,7 @@ import { INat } from "../lib/tools/inat.js";
10
10
  import { JepsonEFlora } from "../lib/tools/jepsoneflora.js";
11
11
  import { RPI } from "../lib/tools/rpi.js";
12
12
  import { Config } from "../lib/config.js";
13
- import { Taxa } from "../lib/taxa.js";
13
+ import { Taxa } from "../lib/taxonomy/taxa.js";
14
14
  import { SupplementalText } from "../lib/tools/supplementaltext.js";
15
15
  import { JepsonFamilies } from "../lib/tools/jepsonfamilies.js";
16
16
  import { CCH2 } from "../lib/tools/cch2.js";
@@ -6,7 +6,7 @@ import { stringify } from "csv-stringify";
6
6
  import path from "path";
7
7
 
8
8
  import { Program } from "../lib/program.js";
9
- import { Taxa } from "../lib/taxa.js";
9
+ import { Taxa } from "../lib/taxonomy/taxa.js";
10
10
  import { sleep } from "../lib/util.js";
11
11
 
12
12
  /**
@@ -27,7 +27,7 @@ const ALLOWED_LICENSE_CODES = ["cc0", "cc-by", "cc-by-nc"];
27
27
  const DEFAULT_FILENAME = "inatobsphotos.csv";
28
28
 
29
29
  /**
30
- * @param {import("../lib/taxon.js").Taxon} taxon
30
+ * @param {import("../lib/types.js").Taxon} taxon
31
31
  * @param {InatObsPhotosCommandLineOptions} options
32
32
  * @return {Promise<InatApiObservation[]>}
33
33
  */
@@ -7,7 +7,7 @@ import path from "path";
7
7
 
8
8
  import { ErrorLog } from "../lib/errorlog.js";
9
9
  import { Program } from "../lib/program.js";
10
- import { Taxa } from "../lib/taxa.js";
10
+ import { Taxa } from "../lib/taxonomy/taxa.js";
11
11
  import { chunk, sleep } from "../lib/util.js";
12
12
 
13
13
  /**
@@ -23,7 +23,7 @@ const ALLOWED_LICENSE_CODES = ["cc0", "cc-by", "cc-by-nc"];
23
23
  const DEFAULT_FILENAME = "inattaxonphotos.csv";
24
24
 
25
25
  /**
26
- * @param {import("../lib/taxon.js").Taxon[]} taxa
26
+ * @param {import("../lib/types.js").Taxon[]} taxa
27
27
  * @return {Promise<import("../lib/utils/inat-tools.js").InatApiTaxon[]>}
28
28
  */
29
29
  async function fetchInatTaxa(taxa) {