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

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 (54) hide show
  1. package/data/synonyms.csv +24 -1
  2. package/data/taxa.csv +117 -99
  3. package/data/text/Antirrhinum-thompsonii.md +1 -0
  4. package/data/text/Calyptridium-monospermum.md +1 -0
  5. package/data/text/Calyptridium-ubellatum.md +1 -0
  6. package/data/text/Clarkia-affinis.md +1 -0
  7. package/data/text/Clarkia-breweri.md +1 -0
  8. package/data/text/Clarkia-concinna-subsp-automixa.md +1 -0
  9. package/data/text/Clarkia-modesta.md +1 -0
  10. package/data/text/Clarkia-purpurea-subsp-quadrivulnera.md +1 -0
  11. package/data/text/Clarkia-rubicunda.md +1 -0
  12. package/data/text/Delphinium-californicum-subsp-californicum.md +1 -1
  13. package/data/text/Delphinium-californicum-subsp-interius.md +1 -0
  14. package/data/text/Delphinium-hesperium-subsp-hesperium.md +1 -1
  15. package/data/text/Delphinium-hesperium-subsp-pallescens.md +1 -0
  16. package/data/text/Delphinium-parryi-subsp-parryi.md +1 -0
  17. package/data/text/Delphinium-variegatum-subsp-variegatum.md +1 -0
  18. package/data/text/Erythranthe-moschata.md +1 -0
  19. package/data/text/Erythranthe-primuloides.md +1 -0
  20. package/data/text/Erythranthe-tilingii.md +1 -0
  21. package/data/text/Fritillaria-affinis.md +1 -0
  22. package/data/text/Fritillaria-agrestis.md +1 -0
  23. package/data/text/Fritillaria-liliacea.md +1 -0
  24. package/data/text/Lilium-pardalinum-subsp-shastense.md +1 -0
  25. package/data/text/Logfia-filaginoides.md +1 -0
  26. package/data/text/Logfia-gallica.md +1 -0
  27. package/data/text/Malacothamnus-arcuatus-var-elmeri.md +1 -0
  28. package/data/text/Malacothamnus-fremontii-var-fremontii.md +1 -0
  29. package/data/text/Trifolium-obtusiflorum.md +1 -0
  30. package/data/text/Trifolium-willdenovii.md +1 -0
  31. package/ebook/css/main.css +4 -0
  32. package/jekyll/assets/css/main.css +4 -0
  33. package/lib/ebook/images.js +49 -40
  34. package/lib/ebook/pages/page_list_species.js +15 -9
  35. package/lib/ebook/pages/taxonpage.js +3 -6
  36. package/lib/ebook/xhtml.js +3 -5
  37. package/lib/externalsites.js +14 -21
  38. package/lib/families.js +0 -2
  39. package/lib/genera.js +1 -3
  40. package/lib/genericpage.js +26 -18
  41. package/lib/generictaxaloader.js +1 -1
  42. package/lib/htmltaxon.js +35 -17
  43. package/lib/markdown.js +7 -9
  44. package/lib/pagerenderer.js +127 -82
  45. package/lib/plants/glossary.js +9 -14
  46. package/lib/taxa.js +14 -15
  47. package/lib/taxaloader.js +3 -1
  48. package/lib/taxon.js +2 -4
  49. package/lib/web/glossarypages.js +31 -18
  50. package/lib/web/pagetaxon.js +0 -10
  51. package/package.json +2 -3
  52. package/scripts/build-ebook.js +1 -1
  53. package/scripts/build-site.js +34 -24
  54. package/types/classes.d.ts +26 -0
@@ -0,0 +1 @@
1
+ Similar to _T. obtusiflorum_, but with shorter teeth on leaves, [calyx](./g/calyx.html) not hairy or bumpy.
@@ -22,6 +22,10 @@ span.lc {
22
22
  font-weight: bold;
23
23
  }
24
24
 
25
+ span.lcs {
26
+ margin-right: 1rem;
27
+ }
28
+
25
29
  /* Glossary */
26
30
  div.glossary img {
27
31
  max-height: 300px;
@@ -142,6 +142,10 @@ span.lc {
142
142
  font-weight: bold;
143
143
  }
144
144
 
145
+ span.lcs {
146
+ margin-right: 1rem;
147
+ }
148
+
145
149
  /* Forms */
146
150
  input {
147
151
  margin-right: .5em;
@@ -3,88 +3,97 @@ 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
6
  import { Image } from "./image.js";
9
7
  import { EBook } from "./ebook.js";
10
8
  import { Taxa } from "../taxa.js";
9
+ import { Config } from "../config.js";
10
+ import { CSV } from "../csv.js";
11
+ import { Files } from "../files.js";
11
12
 
12
13
  class Images {
13
-
14
14
  #siteGenerator;
15
15
  #contentDir;
16
16
  #taxa;
17
17
  #images = {};
18
18
 
19
- constructor( siteGenerator, contentDir, taxa ) {
19
+ constructor(siteGenerator, contentDir, taxa) {
20
20
  this.#siteGenerator = siteGenerator;
21
21
  this.#contentDir = contentDir;
22
22
  this.#taxa = taxa;
23
23
  }
24
24
 
25
25
  async createImages() {
26
-
27
26
  const photoDirSrc = "external_data/photos";
28
27
  const imagePrefix = "i";
29
28
  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 ) {
29
+ fs.mkdirSync(photoDirSrc, { recursive: true });
30
+ fs.mkdirSync(photoDirTarget, { recursive: true });
31
+
32
+ const rows = CSV.parseFile(
33
+ Config.getPackageDir() + "/data",
34
+ "photos.csv"
35
+ );
36
+ for (const row of rows) {
37
+ const name = row["taxon_name"];
38
+ const taxon = this.#taxa.getTaxon(name);
39
+ if (!taxon) {
39
40
  continue;
40
41
  }
41
42
 
42
- let imageList = this.#images[ name ];
43
- if ( !imageList ) {
43
+ let imageList = this.#images[name];
44
+ if (!imageList) {
44
45
  imageList = [];
45
- this.#images[ name ] = imageList;
46
+ this.#images[name] = imageList;
46
47
  }
47
48
 
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";
49
+ const src = new URL(row["source"]);
50
+ const parts = path.parse(src.pathname).dir.split("/");
51
+ const prefix = src.host.includes("calflora") ? "cf-" : "inat-";
52
+ const filename = prefix + parts.slice(-1)[0] + ".jpg";
52
53
  const srcFileName = photoDirSrc + "/" + filename;
53
54
  const targetFileName = photoDirTarget + "/" + filename;
54
55
 
55
- if ( !fs.existsSync( srcFileName ) ) {
56
+ if (!fs.existsSync(srcFileName)) {
56
57
  // File is not there; retrieve it.
57
- console.log( "retrieving " + srcFileName );
58
- await Files.fetch( src, srcFileName );
58
+ console.log("retrieving " + srcFileName);
59
+ await Files.fetch(src, srcFileName);
59
60
  }
60
61
 
61
- await new sharp( srcFileName ).resize( { width: 300 } ).jpeg( { quality: 40 } ).toFile( targetFileName );
62
-
63
- imageList.push( new Image( imagePrefix + "/" + filename, row[ "credit" ] ) );
62
+ await new sharp(srcFileName)
63
+ .resize({ width: 300 })
64
+ .jpeg({ quality: 40 })
65
+ .toFile(targetFileName);
64
66
 
67
+ imageList.push(
68
+ new Image(imagePrefix + "/" + filename, row["credit"])
69
+ );
65
70
  }
66
71
 
67
- this.#siteGenerator.copyIllustrations( Taxa.getFlowerColors() );
68
-
72
+ this.#siteGenerator.copyIllustrations(Taxa.getFlowerColors());
69
73
  }
70
74
 
71
75
  getManifestEntries() {
72
-
73
76
  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 ) ) );
77
+ const images = Files.getDirEntries(this.#contentDir + "/i").sort();
78
+
79
+ for (let index = 0; index < images.length; index++) {
80
+ const fileName = images[index];
81
+ const ext = fileName.split(".")[1];
82
+ entries.push(
83
+ EBook.getManifestEntry(
84
+ "i" + index,
85
+ "i/" + fileName,
86
+ EBook.getMediaTypeForExt(ext)
87
+ )
88
+ );
80
89
  }
81
90
 
82
- return entries.join( "" );
91
+ return entries.join("");
83
92
  }
84
93
 
85
- getTaxonImages( name ) {
86
- return this.#images[ name ];
94
+ getTaxonImages(name) {
95
+ return this.#images[name];
87
96
  }
88
97
  }
89
98
 
90
- export { Images };
99
+ export { Images };
@@ -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;
@@ -58,7 +55,7 @@ class TaxonPage extends EBookPage {
58
55
  });
59
56
  }
60
57
 
61
- html += HTMLTaxon.getFlowerInfo(this.#taxon);
58
+ html += HTMLTaxon.getFlowerInfo(this.#taxon, "section flr");
62
59
 
63
60
  html += renderCustomText(this.#taxon.getBaseFileName());
64
61
 
@@ -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 };
@@ -1,23 +1,18 @@
1
1
  class ExternalSites {
2
+ static getInatObsLink(options) {
3
+ const url = new URL(
4
+ "https://www.inaturalist.org/observations?subview=map"
5
+ );
2
6
 
3
- static getCalscapeLink( taxonName ) {
4
- const url = new URL( "https://calscape.org/loc-California/" + taxonName.replace( "subsp.", "ssp." ) + " ()" );
5
- return url.toString();
6
- }
7
-
8
- static getInatObsLink( options ) {
9
-
10
- const url = new URL( "https://www.inaturalist.org/observations?subview=map" );
11
-
12
- for ( const [ k, v ] of Object.entries( options ) ) {
13
- switch ( k ) {
7
+ for (const [k, v] of Object.entries(options)) {
8
+ switch (k) {
14
9
  case "coords": {
15
- const delta = .1;
10
+ const delta = 0.1;
16
11
  const params = url.searchParams;
17
- params.set( "nelat", v[ 1 ] + delta );
18
- params.set( "swlat", v[ 1 ] - delta );
19
- params.set( "nelng", v[ 0 ] + delta );
20
- params.set( "swlng", v[ 0 ] - delta );
12
+ params.set("nelat", v[1] + delta);
13
+ params.set("swlat", v[1] - delta);
14
+ params.set("nelng", v[0] + delta);
15
+ params.set("swlng", v[0] - delta);
21
16
  break;
22
17
  }
23
18
  case "created_d1":
@@ -27,17 +22,15 @@ class ExternalSites {
27
22
  case "subview":
28
23
  case "taxon_id":
29
24
  case "taxon_name":
30
- if ( v ) {
31
- url.searchParams.set( k, v );
25
+ if (v) {
26
+ url.searchParams.set(k, v);
32
27
  }
33
28
  break;
34
29
  }
35
30
  }
36
31
 
37
32
  return url.toString();
38
-
39
33
  }
40
-
41
34
  }
42
35
 
43
- export { ExternalSites };
36
+ export { ExternalSites };
package/lib/families.js CHANGED
@@ -4,8 +4,6 @@ import { Jepson } from "./jepson.js";
4
4
  import { Taxa } from "./taxa.js";
5
5
  import { Files } from "./files.js";
6
6
  import { Config } from "./config.js";
7
- // eslint-disable-next-line no-unused-vars
8
- import { Taxon } from "./index.js";
9
7
 
10
8
  class Family {
11
9
  #name;
package/lib/genera.js CHANGED
@@ -1,14 +1,12 @@
1
1
  import { Config } from "./config.js";
2
- import { Families } from "./families.js";
3
2
  import { Files } from "./files.js";
4
- // eslint-disable-next-line no-unused-vars
5
- import { Taxon } from "./taxon.js";
6
3
 
7
4
  class Genera {
8
5
  #families;
9
6
  #genera;
10
7
 
11
8
  /**
9
+ *
12
10
  * @param {Families} families
13
11
  */
14
12
  constructor(families) {
@@ -1,14 +1,16 @@
1
- import { Config, Files, HTML, Jekyll } from "@ca-plant-list/ca-plant-list";
1
+ import { Config } from "./config.js";
2
+ import { Files } from "./files.js";
3
+ import { HTML } from "./html.js";
4
+ import { Jekyll } from "./jekyll.js";
2
5
  import { Markdown } from "./markdown.js";
3
6
 
4
7
  class GenericPage {
5
-
6
8
  #outputDir;
7
9
  #title;
8
10
  #baseFileName;
9
11
  #js;
10
12
 
11
- constructor( outputDir, title, baseFileName, js ) {
13
+ constructor(outputDir, title, baseFileName, js) {
12
14
  this.#outputDir = outputDir;
13
15
  this.#title = title;
14
16
  this.#baseFileName = baseFileName;
@@ -25,31 +27,38 @@ class GenericPage {
25
27
  }
26
28
 
27
29
  getFrontMatter() {
28
- return "---\n"
29
- + "title: \"" + this.#title + "\"\n"
30
- + ( this.#js ? ( "js: " + this.#js + "\n" ) : "" )
31
- + "---\n";
30
+ return (
31
+ "---\n" +
32
+ 'title: "' +
33
+ this.#title +
34
+ '"\n' +
35
+ (this.#js ? "js: " + this.#js + "\n" : "") +
36
+ "---\n"
37
+ );
32
38
  }
33
39
 
34
40
  getMarkdown() {
35
41
  // Include site-specific markdown.
36
- let html = this.#getMarkdown( "intros" );
42
+ let html = this.#getMarkdown("intros");
37
43
 
38
44
  // Include package markdown.
39
- const mdPath = Config.getPackageDir() + "/data/text/" + this.#baseFileName + ".md";
40
- if ( Files.exists( mdPath ) ) {
41
- html += HTML.wrap( "div", Markdown.fileToHTML( mdPath ), { class: "section" } );
45
+ const mdPath =
46
+ Config.getPackageDir() + "/data/text/" + this.#baseFileName + ".md";
47
+ if (Files.exists(mdPath)) {
48
+ html += HTML.wrap("div", Markdown.fileToHTML(mdPath), {
49
+ class: "section",
50
+ });
42
51
  }
43
52
 
44
53
  return html;
45
54
  }
46
55
 
47
- #getMarkdown( path ) {
56
+ #getMarkdown(path) {
48
57
  const textPath = path + "/" + this.#baseFileName + ".md";
49
- if ( !Jekyll.hasInclude( this.#outputDir, textPath ) ) {
58
+ if (!Jekyll.hasInclude(this.#outputDir, textPath)) {
50
59
  return "";
51
60
  }
52
- return HTML.wrap( "div", Jekyll.include( textPath ), { class: "section" } );
61
+ return HTML.wrap("div", Jekyll.include(textPath), { class: "section" });
53
62
  }
54
63
 
55
64
  getOutputDir() {
@@ -60,10 +69,9 @@ class GenericPage {
60
69
  return this.#title;
61
70
  }
62
71
 
63
- writeFile( html ) {
64
- Files.write( this.#outputDir + "/" + this.#baseFileName + ".html", html );
72
+ writeFile(html) {
73
+ Files.write(this.#outputDir + "/" + this.#baseFileName + ".html", html);
65
74
  }
66
-
67
75
  }
68
76
 
69
- export { GenericPage };
77
+ export { GenericPage };
@@ -1,4 +1,4 @@
1
- import { ErrorLog } from "./index.js";
1
+ import { ErrorLog } from "./errorlog.js";
2
2
 
3
3
  class GenericTaxaLoader {
4
4
  #options;
package/lib/htmltaxon.js CHANGED
@@ -1,14 +1,31 @@
1
1
  import { DateUtils } from "./dateutils.js";
2
2
  import { HTML } from "./html.js";
3
- // eslint-disable-next-line no-unused-vars
4
- import { Taxon } from "./taxon.js";
5
3
  import { TextUtils } from "./textutils.js";
6
4
 
7
5
  class HTMLTaxon {
6
+ /**
7
+ * @param {string[]} colors
8
+ */
9
+ static getFlowerColors(colors) {
10
+ let html = "";
11
+ if (colors) {
12
+ for (const color of colors) {
13
+ html += HTML.textElement("img", "", {
14
+ src: "./i/f-" + color + ".svg",
15
+ alt: color + " flowers",
16
+ title: color,
17
+ class: "flr-color",
18
+ });
19
+ }
20
+ }
21
+ return html;
22
+ }
23
+
8
24
  /**
9
25
  * @param {Taxon} taxon
26
+ * @param {string} classNames
10
27
  */
11
- static getFlowerInfo(taxon) {
28
+ static getFlowerInfo(taxon, classNames = "section") {
12
29
  const lifeCycle = taxon.getLifeCycle();
13
30
  const colors = taxon.getFlowerColors();
14
31
  const monthStart = taxon.getBloomStart();
@@ -16,23 +33,14 @@ class HTMLTaxon {
16
33
 
17
34
  const parts = [];
18
35
  if (lifeCycle) {
19
- parts.push(
20
- HTML.wrap("span", TextUtils.ucFirst(lifeCycle), "lc") + "."
21
- );
36
+ const text =
37
+ HTML.wrap("span", TextUtils.ucFirst(lifeCycle), "lc") + ".";
38
+ parts.push(HTML.wrap("span", text, "lcs"));
22
39
  }
23
40
 
24
41
  if (colors || monthStart) {
25
42
  let html = "Flowers: ";
26
- if (colors) {
27
- for (const color of colors) {
28
- html += HTML.textElement("img", "", {
29
- src: "./i/f-" + color + ".svg",
30
- alt: color + " flowers",
31
- title: color,
32
- class: "flr-color",
33
- });
34
- }
35
- }
43
+ html += this.getFlowerColors(colors);
36
44
  if (monthStart && monthEnd) {
37
45
  html += HTML.wrap(
38
46
  "span",
@@ -44,7 +52,17 @@ class HTMLTaxon {
44
52
  }
45
53
  parts.push(HTML.wrap("span", html));
46
54
  }
47
- return HTML.wrap("div", parts.join(" "), { class: "section" });
55
+ return HTML.wrap("div", parts.join(""), { class: classNames });
56
+ }
57
+
58
+ /**
59
+ * @param {Taxon} taxon
60
+ */
61
+ static getLink(taxon) {
62
+ return (
63
+ HTML.getLink(taxon.getFileName(), taxon.getName()) +
64
+ this.getFlowerColors(taxon.getFlowerColors())
65
+ );
48
66
  }
49
67
  }
50
68
 
package/lib/markdown.js CHANGED
@@ -1,18 +1,16 @@
1
1
  import markdownIt from "markdown-it";
2
- import { Files } from "@ca-plant-list/ca-plant-list";
2
+ import { Files } from "./files.js";
3
3
 
4
4
  class Markdown {
5
+ static #md = new markdownIt({ xhtmlOut: true });
5
6
 
6
- static #md = new markdownIt( { xhtmlOut: true } );
7
-
8
- static fileToHTML( filePath ) {
9
- return this.strToHTML( Files.read( filePath ) );
7
+ static fileToHTML(filePath) {
8
+ return this.strToHTML(Files.read(filePath));
10
9
  }
11
10
 
12
- static strToHTML( str ) {
13
- return this.#md.render( str );
11
+ static strToHTML(str) {
12
+ return this.#md.render(str);
14
13
  }
15
-
16
14
  }
17
15
 
18
- export { Markdown };
16
+ export { Markdown };