@ca-plant-list/ca-plant-list 0.2.0 → 0.2.2
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.
- package/data/exceptions.json +43 -1
- package/data/photos.csv +7 -0
- package/data/taxa.csv +184 -184
- package/data/text/Bromus-catharticus-var-catharticus.md +1 -0
- package/data/text/Bromus-catharticus-var-elatus.md +1 -0
- package/data/text/Bromus-sitchensis-var-carinatus.md +1 -0
- package/data/text/Bromus-sitchensis-var-marginatus.md +1 -0
- package/data/text/Castilleja-foliolosa.md +1 -0
- package/data/text/Grindelia-camporum.md +1 -0
- package/data/text/Grindelia-hirsutula.md +1 -0
- package/data/text/Layia-chrysanthemoides.md +1 -0
- package/data/text/Layia-gaillardioides.md +1 -0
- package/data/text/Layia-hieracioides.md +1 -0
- package/data/text/Layia-platyglossa.md +1 -0
- package/data/text/Leptosiphon-bicolor.md +1 -0
- package/data/text/Leptosiphon-ciliatus.md +1 -0
- package/data/text/Leptosiphon-grandiflorus.md +1 -0
- package/data/text/Lithophragma-affine.md +1 -0
- package/data/text/Lithophragma-heterophyllum.md +1 -0
- package/data/text/Lithophragma-parviflorum-var-parviflorum.md +1 -0
- package/data/text/Lupinus-bicolor.md +1 -0
- package/data/text/Lupinus-formosus-var-formosus.md +1 -0
- package/data/text/Lupinus-latifolius-var-latifolius.md +1 -0
- package/data/text/Lupinus-microcarpus-var-densiflorus.md +1 -0
- package/data/text/Lupinus-microcarpus-var-microcarpus.md +1 -0
- package/data/text/Lupinus-nanus.md +1 -0
- package/data/text/Lupinus-succulentus.md +1 -0
- package/data/text/Wyethia-angustifolia.md +1 -0
- package/data/text/Wyethia-glabra.md +1 -0
- package/data/text/Wyethia-helenioides.md +1 -0
- package/ebook/css/main.css +16 -0
- package/ebook/i/f-blue.svg +5 -0
- package/ebook/i/f-orange.svg +5 -0
- package/ebook/i/f-pink.svg +5 -0
- package/ebook/i/f-red.svg +5 -0
- package/ebook/i/f-white.svg +5 -0
- package/ebook/i/f-yellow.svg +5 -0
- package/jekyll/assets/css/main.css +6 -0
- package/lib/ebook/ebook.js +146 -0
- package/lib/ebook/ebookpage.js +47 -0
- package/lib/ebook/image.js +21 -0
- package/lib/ebook/pages/page_list_families.js +27 -0
- package/lib/ebook/pages/page_list_flower_color.js +26 -0
- package/lib/ebook/pages/page_list_species.js +26 -0
- package/lib/ebook/pages/taxonpage.js +79 -0
- package/lib/ebook/pages/tocpage.js +37 -0
- package/lib/ebook/plantbook.js +179 -0
- package/lib/ebook/xhtml.js +7 -0
- package/lib/exceptions.js +14 -4
- package/lib/families.js +4 -0
- package/lib/index.d.ts +14 -7
- package/lib/index.js +2 -1
- package/lib/pagetaxon.js +2 -2
- package/lib/taxa.js +53 -2
- package/lib/taxon.js +9 -1
- package/package.json +7 -2
- package/scripts/build-ebook.js +12 -0
@@ -0,0 +1 @@
|
|
1
|
+
Lemma awn < 4mm.
|
@@ -0,0 +1 @@
|
|
1
|
+
Lemma awn 4mm or longer. 9-11 prominent veins on distal half of lemma.
|
@@ -0,0 +1 @@
|
|
1
|
+
Most awns 7mm or longer. 7 lemma veins; veins obscure.
|
@@ -0,0 +1 @@
|
|
1
|
+
Most awns 4-7mm.
|
@@ -0,0 +1 @@
|
|
1
|
+
Gray-green to densely white-woolly, hairs branched.
|
@@ -0,0 +1 @@
|
|
1
|
+
Phyllaries flattened only at bases (rounded in cross section distally), phyllary tips often reflexed, or coiled; plants generally not hairy.
|
@@ -0,0 +1 @@
|
|
1
|
+
Phyllaries flattened, plants generally hairy.
|
@@ -0,0 +1 @@
|
|
1
|
+
Plant not glandular. Ray flowers often white-tipped.
|
@@ -0,0 +1 @@
|
|
1
|
+
Plant glandular, strongly scented. Stem purple-streaked. Ray flowers often white-tipped.
|
@@ -0,0 +1 @@
|
|
1
|
+
Plant glandular. Stem with purple spots or streaks. Ray flowers yellow, 1-4mm.
|
@@ -0,0 +1 @@
|
|
1
|
+
Plant glandular. Stem without black dots or streaks. Anthers usually purple. Ray flowers often white-tipped.
|
@@ -0,0 +1 @@
|
|
1
|
+
Flowers pedicelled. Corolla tube at least twice as long as calyx. Calyx membrane much narrower than lobes.
|
@@ -0,0 +1 @@
|
|
1
|
+
Flowers pedicelled. Corolla tube at least twice as long as calyx. Calyx membrane at least as wide as lobes.
|
@@ -0,0 +1 @@
|
|
1
|
+
Flowers sessile.
|
@@ -0,0 +1 @@
|
|
1
|
+
Pedicel 3-10 mm, floral tube conical at base. In open, grassy areas.
|
@@ -0,0 +1 @@
|
|
1
|
+
Pedicel 2 mm or less, floral tube squared off at base. In shaded areas.
|
@@ -0,0 +1 @@
|
|
1
|
+
Basal leaves either compound or deeply divided (more than half way to base of blade).
|
@@ -0,0 +1 @@
|
|
1
|
+
Banner longer than wide; pedicels generally < 3 mm.
|
@@ -0,0 +1 @@
|
|
1
|
+
Perennial. Keel margins not hairy.
|
@@ -0,0 +1 @@
|
|
1
|
+
Perennial. Fruit densely hairy.
|
@@ -0,0 +1 @@
|
|
1
|
+
Annual. At least lower part of stem clearly hollow. Lower keel margins usually not hairy or less hairy than upper. Flowers generally yellow or white.
|
@@ -0,0 +1 @@
|
|
1
|
+
Annual. At least lower part of stem clearly hollow. Lower keel margins usually not hairy or less hairy than upper. Flowers generally pink or purple.
|
@@ -0,0 +1 @@
|
|
1
|
+
Banner as wide as or wider than long; pedicels generally > 3 mm.
|
@@ -0,0 +1 @@
|
|
1
|
+
Annual. Fruit not densely hairy.
|
@@ -0,0 +1 @@
|
|
1
|
+
Outer phyllaries narrow and roughly the same width as inner.
|
@@ -0,0 +1 @@
|
|
1
|
+
Outer phyllaries wide, leaf-like, and usually much larger than inner phyllaries. Generally not hairy or with some glandular hairs.
|
@@ -0,0 +1 @@
|
|
1
|
+
Outer phyllaries wide, leaf-like, and usually much larger than inner phyllaries. Plant densely tomentose.
|
@@ -0,0 +1,5 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"
|
2
|
+
viewBox="0 0 16 16">
|
3
|
+
<path fill="white" stroke="blue"
|
4
|
+
d="M11.424 8c.437-.052.811-.136 1.04-.268a2 2 0 0 0-2-3.464c-.229.132-.489.414-.752.767C9.886 4.63 10 4.264 10 4a2 2 0 1 0-4 0c0 .264.114.63.288 1.035-.263-.353-.523-.635-.752-.767a2 2 0 0 0-2 3.464c.229.132.603.216 1.04.268-.437.052-.811.136-1.04.268a2 2 0 1 0 2 3.464c.229-.132.489-.414.752-.767C6.114 11.37 6 11.736 6 12a2 2 0 1 0 4 0c0-.264-.114-.63-.288-1.035.263.353.523.635.752.767a2 2 0 1 0 2-3.464c-.229-.132-.603-.216-1.04-.268zM9 4a1.468 1.468 0 0 1-.045.205c-.039.132-.1.295-.183.484a12.88 12.88 0 0 1-.637 1.223L8 6.142a21.73 21.73 0 0 1-.135-.23 12.88 12.88 0 0 1-.637-1.223 4.216 4.216 0 0 1-.183-.484A1.473 1.473 0 0 1 7 4a1 1 0 1 1 2 0zM3.67 5.5a1 1 0 0 1 1.366-.366 1.472 1.472 0 0 1 .156.142c.094.1.204.233.326.4.245.333.502.747.742 1.163l.13.232a21.86 21.86 0 0 1-.265.002 12.88 12.88 0 0 1-1.379-.06 4.214 4.214 0 0 1-.51-.083 1.47 1.47 0 0 1-.2-.064A1 1 0 0 1 3.67 5.5zm1.366 5.366a1 1 0 0 1-1-1.732c.001 0 .016-.008.047-.02.037-.013.087-.028.153-.044.134-.032.305-.06.51-.083a12.88 12.88 0 0 1 1.379-.06c.09 0 .178 0 .266.002a21.82 21.82 0 0 1-.131.232c-.24.416-.497.83-.742 1.163a4.1 4.1 0 0 1-.327.4 1.483 1.483 0 0 1-.155.142zM9 12a1 1 0 0 1-2 0 1.476 1.476 0 0 1 .045-.206c.039-.131.1-.294.183-.483.166-.378.396-.808.637-1.223L8 9.858l.135.23c.241.415.47.845.637 1.223.083.19.144.352.183.484A1.338 1.338 0 0 1 9 12zm3.33-6.5a1 1 0 0 1-.366 1.366 1.478 1.478 0 0 1-.2.064c-.134.032-.305.06-.51.083-.412.045-.898.061-1.379.06-.09 0-.178 0-.266-.002l.131-.232c.24-.416.497-.83.742-1.163a4.1 4.1 0 0 1 .327-.4c.046-.05.085-.086.114-.11.026-.022.04-.03.041-.032a1 1 0 0 1 1.366.366zm-1.366 5.366a1.494 1.494 0 0 1-.155-.141 4.225 4.225 0 0 1-.327-.4A12.88 12.88 0 0 1 9.74 9.16a22 22 0 0 1-.13-.232l.265-.002c.48-.001.967.015 1.379.06.205.023.376.051.51.083.066.016.116.031.153.044l.048.02a1 1 0 1 1-1 1.732zM8 9a1 1 0 1 1 0-2 1 1 0 0 1 0 2z" />
|
5
|
+
</svg>
|
@@ -0,0 +1,5 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"
|
2
|
+
viewBox="0 0 16 16">
|
3
|
+
<path fill="white" stroke="orange"
|
4
|
+
d="M11.424 8c.437-.052.811-.136 1.04-.268a2 2 0 0 0-2-3.464c-.229.132-.489.414-.752.767C9.886 4.63 10 4.264 10 4a2 2 0 1 0-4 0c0 .264.114.63.288 1.035-.263-.353-.523-.635-.752-.767a2 2 0 0 0-2 3.464c.229.132.603.216 1.04.268-.437.052-.811.136-1.04.268a2 2 0 1 0 2 3.464c.229-.132.489-.414.752-.767C6.114 11.37 6 11.736 6 12a2 2 0 1 0 4 0c0-.264-.114-.63-.288-1.035.263.353.523.635.752.767a2 2 0 1 0 2-3.464c-.229-.132-.603-.216-1.04-.268zM9 4a1.468 1.468 0 0 1-.045.205c-.039.132-.1.295-.183.484a12.88 12.88 0 0 1-.637 1.223L8 6.142a21.73 21.73 0 0 1-.135-.23 12.88 12.88 0 0 1-.637-1.223 4.216 4.216 0 0 1-.183-.484A1.473 1.473 0 0 1 7 4a1 1 0 1 1 2 0zM3.67 5.5a1 1 0 0 1 1.366-.366 1.472 1.472 0 0 1 .156.142c.094.1.204.233.326.4.245.333.502.747.742 1.163l.13.232a21.86 21.86 0 0 1-.265.002 12.88 12.88 0 0 1-1.379-.06 4.214 4.214 0 0 1-.51-.083 1.47 1.47 0 0 1-.2-.064A1 1 0 0 1 3.67 5.5zm1.366 5.366a1 1 0 0 1-1-1.732c.001 0 .016-.008.047-.02.037-.013.087-.028.153-.044.134-.032.305-.06.51-.083a12.88 12.88 0 0 1 1.379-.06c.09 0 .178 0 .266.002a21.82 21.82 0 0 1-.131.232c-.24.416-.497.83-.742 1.163a4.1 4.1 0 0 1-.327.4 1.483 1.483 0 0 1-.155.142zM9 12a1 1 0 0 1-2 0 1.476 1.476 0 0 1 .045-.206c.039-.131.1-.294.183-.483.166-.378.396-.808.637-1.223L8 9.858l.135.23c.241.415.47.845.637 1.223.083.19.144.352.183.484A1.338 1.338 0 0 1 9 12zm3.33-6.5a1 1 0 0 1-.366 1.366 1.478 1.478 0 0 1-.2.064c-.134.032-.305.06-.51.083-.412.045-.898.061-1.379.06-.09 0-.178 0-.266-.002l.131-.232c.24-.416.497-.83.742-1.163a4.1 4.1 0 0 1 .327-.4c.046-.05.085-.086.114-.11.026-.022.04-.03.041-.032a1 1 0 0 1 1.366.366zm-1.366 5.366a1.494 1.494 0 0 1-.155-.141 4.225 4.225 0 0 1-.327-.4A12.88 12.88 0 0 1 9.74 9.16a22 22 0 0 1-.13-.232l.265-.002c.48-.001.967.015 1.379.06.205.023.376.051.51.083.066.016.116.031.153.044l.048.02a1 1 0 1 1-1 1.732zM8 9a1 1 0 1 1 0-2 1 1 0 0 1 0 2z" />
|
5
|
+
</svg>
|
@@ -0,0 +1,5 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"
|
2
|
+
viewBox="0 0 16 16">
|
3
|
+
<path fill="white" stroke="pink"
|
4
|
+
d="M11.424 8c.437-.052.811-.136 1.04-.268a2 2 0 0 0-2-3.464c-.229.132-.489.414-.752.767C9.886 4.63 10 4.264 10 4a2 2 0 1 0-4 0c0 .264.114.63.288 1.035-.263-.353-.523-.635-.752-.767a2 2 0 0 0-2 3.464c.229.132.603.216 1.04.268-.437.052-.811.136-1.04.268a2 2 0 1 0 2 3.464c.229-.132.489-.414.752-.767C6.114 11.37 6 11.736 6 12a2 2 0 1 0 4 0c0-.264-.114-.63-.288-1.035.263.353.523.635.752.767a2 2 0 1 0 2-3.464c-.229-.132-.603-.216-1.04-.268zM9 4a1.468 1.468 0 0 1-.045.205c-.039.132-.1.295-.183.484a12.88 12.88 0 0 1-.637 1.223L8 6.142a21.73 21.73 0 0 1-.135-.23 12.88 12.88 0 0 1-.637-1.223 4.216 4.216 0 0 1-.183-.484A1.473 1.473 0 0 1 7 4a1 1 0 1 1 2 0zM3.67 5.5a1 1 0 0 1 1.366-.366 1.472 1.472 0 0 1 .156.142c.094.1.204.233.326.4.245.333.502.747.742 1.163l.13.232a21.86 21.86 0 0 1-.265.002 12.88 12.88 0 0 1-1.379-.06 4.214 4.214 0 0 1-.51-.083 1.47 1.47 0 0 1-.2-.064A1 1 0 0 1 3.67 5.5zm1.366 5.366a1 1 0 0 1-1-1.732c.001 0 .016-.008.047-.02.037-.013.087-.028.153-.044.134-.032.305-.06.51-.083a12.88 12.88 0 0 1 1.379-.06c.09 0 .178 0 .266.002a21.82 21.82 0 0 1-.131.232c-.24.416-.497.83-.742 1.163a4.1 4.1 0 0 1-.327.4 1.483 1.483 0 0 1-.155.142zM9 12a1 1 0 0 1-2 0 1.476 1.476 0 0 1 .045-.206c.039-.131.1-.294.183-.483.166-.378.396-.808.637-1.223L8 9.858l.135.23c.241.415.47.845.637 1.223.083.19.144.352.183.484A1.338 1.338 0 0 1 9 12zm3.33-6.5a1 1 0 0 1-.366 1.366 1.478 1.478 0 0 1-.2.064c-.134.032-.305.06-.51.083-.412.045-.898.061-1.379.06-.09 0-.178 0-.266-.002l.131-.232c.24-.416.497-.83.742-1.163a4.1 4.1 0 0 1 .327-.4c.046-.05.085-.086.114-.11.026-.022.04-.03.041-.032a1 1 0 0 1 1.366.366zm-1.366 5.366a1.494 1.494 0 0 1-.155-.141 4.225 4.225 0 0 1-.327-.4A12.88 12.88 0 0 1 9.74 9.16a22 22 0 0 1-.13-.232l.265-.002c.48-.001.967.015 1.379.06.205.023.376.051.51.083.066.016.116.031.153.044l.048.02a1 1 0 1 1-1 1.732zM8 9a1 1 0 1 1 0-2 1 1 0 0 1 0 2z" />
|
5
|
+
</svg>
|
@@ -0,0 +1,5 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"
|
2
|
+
viewBox="0 0 16 16">
|
3
|
+
<path fill="white" stroke="red"
|
4
|
+
d="M11.424 8c.437-.052.811-.136 1.04-.268a2 2 0 0 0-2-3.464c-.229.132-.489.414-.752.767C9.886 4.63 10 4.264 10 4a2 2 0 1 0-4 0c0 .264.114.63.288 1.035-.263-.353-.523-.635-.752-.767a2 2 0 0 0-2 3.464c.229.132.603.216 1.04.268-.437.052-.811.136-1.04.268a2 2 0 1 0 2 3.464c.229-.132.489-.414.752-.767C6.114 11.37 6 11.736 6 12a2 2 0 1 0 4 0c0-.264-.114-.63-.288-1.035.263.353.523.635.752.767a2 2 0 1 0 2-3.464c-.229-.132-.603-.216-1.04-.268zM9 4a1.468 1.468 0 0 1-.045.205c-.039.132-.1.295-.183.484a12.88 12.88 0 0 1-.637 1.223L8 6.142a21.73 21.73 0 0 1-.135-.23 12.88 12.88 0 0 1-.637-1.223 4.216 4.216 0 0 1-.183-.484A1.473 1.473 0 0 1 7 4a1 1 0 1 1 2 0zM3.67 5.5a1 1 0 0 1 1.366-.366 1.472 1.472 0 0 1 .156.142c.094.1.204.233.326.4.245.333.502.747.742 1.163l.13.232a21.86 21.86 0 0 1-.265.002 12.88 12.88 0 0 1-1.379-.06 4.214 4.214 0 0 1-.51-.083 1.47 1.47 0 0 1-.2-.064A1 1 0 0 1 3.67 5.5zm1.366 5.366a1 1 0 0 1-1-1.732c.001 0 .016-.008.047-.02.037-.013.087-.028.153-.044.134-.032.305-.06.51-.083a12.88 12.88 0 0 1 1.379-.06c.09 0 .178 0 .266.002a21.82 21.82 0 0 1-.131.232c-.24.416-.497.83-.742 1.163a4.1 4.1 0 0 1-.327.4 1.483 1.483 0 0 1-.155.142zM9 12a1 1 0 0 1-2 0 1.476 1.476 0 0 1 .045-.206c.039-.131.1-.294.183-.483.166-.378.396-.808.637-1.223L8 9.858l.135.23c.241.415.47.845.637 1.223.083.19.144.352.183.484A1.338 1.338 0 0 1 9 12zm3.33-6.5a1 1 0 0 1-.366 1.366 1.478 1.478 0 0 1-.2.064c-.134.032-.305.06-.51.083-.412.045-.898.061-1.379.06-.09 0-.178 0-.266-.002l.131-.232c.24-.416.497-.83.742-1.163a4.1 4.1 0 0 1 .327-.4c.046-.05.085-.086.114-.11.026-.022.04-.03.041-.032a1 1 0 0 1 1.366.366zm-1.366 5.366a1.494 1.494 0 0 1-.155-.141 4.225 4.225 0 0 1-.327-.4A12.88 12.88 0 0 1 9.74 9.16a22 22 0 0 1-.13-.232l.265-.002c.48-.001.967.015 1.379.06.205.023.376.051.51.083.066.016.116.031.153.044l.048.02a1 1 0 1 1-1 1.732zM8 9a1 1 0 1 1 0-2 1 1 0 0 1 0 2z" />
|
5
|
+
</svg>
|
@@ -0,0 +1,5 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"
|
2
|
+
viewBox="0 0 16 16">
|
3
|
+
<path
|
4
|
+
d="M11.424 8c.437-.052.811-.136 1.04-.268a2 2 0 0 0-2-3.464c-.229.132-.489.414-.752.767C9.886 4.63 10 4.264 10 4a2 2 0 1 0-4 0c0 .264.114.63.288 1.035-.263-.353-.523-.635-.752-.767a2 2 0 0 0-2 3.464c.229.132.603.216 1.04.268-.437.052-.811.136-1.04.268a2 2 0 1 0 2 3.464c.229-.132.489-.414.752-.767C6.114 11.37 6 11.736 6 12a2 2 0 1 0 4 0c0-.264-.114-.63-.288-1.035.263.353.523.635.752.767a2 2 0 1 0 2-3.464c-.229-.132-.603-.216-1.04-.268zM9 4a1.468 1.468 0 0 1-.045.205c-.039.132-.1.295-.183.484a12.88 12.88 0 0 1-.637 1.223L8 6.142a21.73 21.73 0 0 1-.135-.23 12.88 12.88 0 0 1-.637-1.223 4.216 4.216 0 0 1-.183-.484A1.473 1.473 0 0 1 7 4a1 1 0 1 1 2 0zM3.67 5.5a1 1 0 0 1 1.366-.366 1.472 1.472 0 0 1 .156.142c.094.1.204.233.326.4.245.333.502.747.742 1.163l.13.232a21.86 21.86 0 0 1-.265.002 12.88 12.88 0 0 1-1.379-.06 4.214 4.214 0 0 1-.51-.083 1.47 1.47 0 0 1-.2-.064A1 1 0 0 1 3.67 5.5zm1.366 5.366a1 1 0 0 1-1-1.732c.001 0 .016-.008.047-.02.037-.013.087-.028.153-.044.134-.032.305-.06.51-.083a12.88 12.88 0 0 1 1.379-.06c.09 0 .178 0 .266.002a21.82 21.82 0 0 1-.131.232c-.24.416-.497.83-.742 1.163a4.1 4.1 0 0 1-.327.4 1.483 1.483 0 0 1-.155.142zM9 12a1 1 0 0 1-2 0 1.476 1.476 0 0 1 .045-.206c.039-.131.1-.294.183-.483.166-.378.396-.808.637-1.223L8 9.858l.135.23c.241.415.47.845.637 1.223.083.19.144.352.183.484A1.338 1.338 0 0 1 9 12zm3.33-6.5a1 1 0 0 1-.366 1.366 1.478 1.478 0 0 1-.2.064c-.134.032-.305.06-.51.083-.412.045-.898.061-1.379.06-.09 0-.178 0-.266-.002l.131-.232c.24-.416.497-.83.742-1.163a4.1 4.1 0 0 1 .327-.4c.046-.05.085-.086.114-.11.026-.022.04-.03.041-.032a1 1 0 0 1 1.366.366zm-1.366 5.366a1.494 1.494 0 0 1-.155-.141 4.225 4.225 0 0 1-.327-.4A12.88 12.88 0 0 1 9.74 9.16a22 22 0 0 1-.13-.232l.265-.002c.48-.001.967.015 1.379.06.205.023.376.051.51.083.066.016.116.031.153.044l.048.02a1 1 0 1 1-1 1.732zM8 9a1 1 0 1 1 0-2 1 1 0 0 1 0 2z" />
|
5
|
+
</svg>
|
@@ -0,0 +1,5 @@
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"
|
2
|
+
viewBox="0 0 16 16">
|
3
|
+
<path fill="white" stroke="yellow"
|
4
|
+
d="M11.424 8c.437-.052.811-.136 1.04-.268a2 2 0 0 0-2-3.464c-.229.132-.489.414-.752.767C9.886 4.63 10 4.264 10 4a2 2 0 1 0-4 0c0 .264.114.63.288 1.035-.263-.353-.523-.635-.752-.767a2 2 0 0 0-2 3.464c.229.132.603.216 1.04.268-.437.052-.811.136-1.04.268a2 2 0 1 0 2 3.464c.229-.132.489-.414.752-.767C6.114 11.37 6 11.736 6 12a2 2 0 1 0 4 0c0-.264-.114-.63-.288-1.035.263.353.523.635.752.767a2 2 0 1 0 2-3.464c-.229-.132-.603-.216-1.04-.268zM9 4a1.468 1.468 0 0 1-.045.205c-.039.132-.1.295-.183.484a12.88 12.88 0 0 1-.637 1.223L8 6.142a21.73 21.73 0 0 1-.135-.23 12.88 12.88 0 0 1-.637-1.223 4.216 4.216 0 0 1-.183-.484A1.473 1.473 0 0 1 7 4a1 1 0 1 1 2 0zM3.67 5.5a1 1 0 0 1 1.366-.366 1.472 1.472 0 0 1 .156.142c.094.1.204.233.326.4.245.333.502.747.742 1.163l.13.232a21.86 21.86 0 0 1-.265.002 12.88 12.88 0 0 1-1.379-.06 4.214 4.214 0 0 1-.51-.083 1.47 1.47 0 0 1-.2-.064A1 1 0 0 1 3.67 5.5zm1.366 5.366a1 1 0 0 1-1-1.732c.001 0 .016-.008.047-.02.037-.013.087-.028.153-.044.134-.032.305-.06.51-.083a12.88 12.88 0 0 1 1.379-.06c.09 0 .178 0 .266.002a21.82 21.82 0 0 1-.131.232c-.24.416-.497.83-.742 1.163a4.1 4.1 0 0 1-.327.4 1.483 1.483 0 0 1-.155.142zM9 12a1 1 0 0 1-2 0 1.476 1.476 0 0 1 .045-.206c.039-.131.1-.294.183-.483.166-.378.396-.808.637-1.223L8 9.858l.135.23c.241.415.47.845.637 1.223.083.19.144.352.183.484A1.338 1.338 0 0 1 9 12zm3.33-6.5a1 1 0 0 1-.366 1.366 1.478 1.478 0 0 1-.2.064c-.134.032-.305.06-.51.083-.412.045-.898.061-1.379.06-.09 0-.178 0-.266-.002l.131-.232c.24-.416.497-.83.742-1.163a4.1 4.1 0 0 1 .327-.4c.046-.05.085-.086.114-.11.026-.022.04-.03.041-.032a1 1 0 0 1 1.366.366zm-1.366 5.366a1.494 1.494 0 0 1-.155-.141 4.225 4.225 0 0 1-.327-.4A12.88 12.88 0 0 1 9.74 9.16a22 22 0 0 1-.13-.232l.265-.002c.48-.001.967.015 1.379.06.205.023.376.051.51.083.066.016.116.031.153.044l.048.02a1 1 0 1 1-1 1.732zM8 9a1 1 0 1 1 0-2 1 1 0 0 1 0 2z" />
|
5
|
+
</svg>
|
@@ -0,0 +1,146 @@
|
|
1
|
+
import * as fs from "node:fs";
|
2
|
+
import { default as archiver } from "archiver";
|
3
|
+
import { XHTML } from "./xhtml.js";
|
4
|
+
import { Config } from "../config.js";
|
5
|
+
|
6
|
+
class EBook {
|
7
|
+
|
8
|
+
#outputDir;
|
9
|
+
#filename;
|
10
|
+
#pub_id;
|
11
|
+
#title;
|
12
|
+
|
13
|
+
constructor( outputDir, filename, pub_id, title ) {
|
14
|
+
|
15
|
+
this.#outputDir = outputDir;
|
16
|
+
this.#filename = filename;
|
17
|
+
this.#pub_id = pub_id;
|
18
|
+
this.#title = title;
|
19
|
+
|
20
|
+
// Initialize output directory.
|
21
|
+
fs.rmSync( this.#outputDir, { force: true, recursive: true } );
|
22
|
+
fs.mkdirSync( this.getContentDir(), { recursive: true } );
|
23
|
+
|
24
|
+
}
|
25
|
+
|
26
|
+
async create() {
|
27
|
+
|
28
|
+
const contentDir = this.getContentDir();
|
29
|
+
|
30
|
+
this.#createContainerFile();
|
31
|
+
await this.createPages();
|
32
|
+
this.#createPackageFile();
|
33
|
+
|
34
|
+
// Copy assets
|
35
|
+
// const cssDirTarget = contentDir + "/css";
|
36
|
+
// fs.mkdirSync( cssDirTarget, { recursive: true } );
|
37
|
+
fs.cpSync( Config.getPackageDir() + "/ebook", contentDir, { recursive: true } );
|
38
|
+
|
39
|
+
this.createZip();
|
40
|
+
|
41
|
+
}
|
42
|
+
|
43
|
+
#createContainerFile() {
|
44
|
+
|
45
|
+
const metaDir = this.#getMetaDir();
|
46
|
+
|
47
|
+
fs.mkdirSync( metaDir, { recursive: true } );
|
48
|
+
|
49
|
+
let xml = "<?xml version=\"1.0\"?>"
|
50
|
+
+ "<container version=\"1.0\" xmlns=\"urn:oasis:names:tc:opendocument:xmlns:container\">";
|
51
|
+
|
52
|
+
xml += "<rootfiles><rootfile full-path=\"epub/package.opf\" media-type=\"application/oebps-package+xml\" /></rootfiles>";
|
53
|
+
xml += "</container>";
|
54
|
+
|
55
|
+
fs.writeFileSync( metaDir + "/container.xml", xml );
|
56
|
+
|
57
|
+
}
|
58
|
+
|
59
|
+
#createPackageFile() {
|
60
|
+
|
61
|
+
const dir = this.getContentDir();
|
62
|
+
|
63
|
+
let xml = "<?xml version=\"1.0\"?>\n"
|
64
|
+
+ "<package version=\"3.0\" xml:lang=\"en\" xmlns=\"http://www.idpf.org/2007/opf\" unique-identifier=\"pub-id\">";
|
65
|
+
|
66
|
+
xml += this.#renderMetadata();
|
67
|
+
xml += this.#renderManifest();
|
68
|
+
xml += this.#renderSpine();
|
69
|
+
|
70
|
+
xml += "</package>";
|
71
|
+
|
72
|
+
fs.writeFileSync( dir + "/package.opf", xml );
|
73
|
+
|
74
|
+
}
|
75
|
+
|
76
|
+
async createPages() {
|
77
|
+
throw new Error( "must be implemented by subclass" );
|
78
|
+
}
|
79
|
+
|
80
|
+
createZip() {
|
81
|
+
// Create zip.
|
82
|
+
const filename = this.#outputDir + "/" + this.#filename + ".epub";
|
83
|
+
const output = fs.createWriteStream( filename );
|
84
|
+
const archive = archiver(
|
85
|
+
"zip",
|
86
|
+
{
|
87
|
+
zlib: { level: 9 } // Sets the compression level.
|
88
|
+
}
|
89
|
+
);
|
90
|
+
|
91
|
+
archive.pipe( output );
|
92
|
+
|
93
|
+
archive.append( "application/epub+zip", { name: "mimetype", store: true } );
|
94
|
+
|
95
|
+
archive.directory( this.#getMetaDir(), "META-INF" );
|
96
|
+
archive.directory( this.getContentDir(), "epub" );
|
97
|
+
|
98
|
+
archive.finalize();
|
99
|
+
|
100
|
+
}
|
101
|
+
|
102
|
+
getContentDir() {
|
103
|
+
return this.#outputDir + "/epub";
|
104
|
+
}
|
105
|
+
|
106
|
+
#getMetaDir() {
|
107
|
+
return this.#outputDir + "/META-INF";
|
108
|
+
}
|
109
|
+
|
110
|
+
#renderManifest() {
|
111
|
+
let xml = "<manifest>";
|
112
|
+
xml += "<item id=\"c0\" href=\"css/main.css\" media-type=\"text/css\" />";
|
113
|
+
xml += this.renderManifestEntries();
|
114
|
+
xml += "<item id=\"toc\" href=\"toc.xhtml\" media-type=\"application/xhtml+xml\" properties=\"nav\" />";
|
115
|
+
return xml + "</manifest>";
|
116
|
+
}
|
117
|
+
|
118
|
+
renderManifestEntries() {
|
119
|
+
throw new Error( "must be implemented by subclass" );
|
120
|
+
}
|
121
|
+
|
122
|
+
#renderMetadata() {
|
123
|
+
let xml = "<metadata xmlns:dc=\"http://purl.org/dc/elements/1.1/\">";
|
124
|
+
xml += XHTML.textElement( "dc:identifier", this.#pub_id, { id: "pub-id" } );
|
125
|
+
xml += "<dc:language>en-US</dc:language>";
|
126
|
+
xml += XHTML.textElement( "dc:title", this.#title );
|
127
|
+
const d = new Date();
|
128
|
+
d.setUTCMilliseconds( 0 );
|
129
|
+
xml += "<meta property=\"dcterms:modified\">" + d.toISOString().replace( ".000", "" ) + "</meta>";
|
130
|
+
return xml + "</metadata>";
|
131
|
+
}
|
132
|
+
|
133
|
+
#renderSpine() {
|
134
|
+
let xml = "<spine>";
|
135
|
+
xml += "<itemref idref=\"toc\"/>";
|
136
|
+
xml += this.renderSpineElements();
|
137
|
+
return xml + "</spine>";
|
138
|
+
}
|
139
|
+
|
140
|
+
renderSpineElements() {
|
141
|
+
throw new Error( "must be implemented by subclass" );
|
142
|
+
}
|
143
|
+
|
144
|
+
}
|
145
|
+
|
146
|
+
export { EBook };
|
@@ -0,0 +1,47 @@
|
|
1
|
+
import * as fs from "node:fs";
|
2
|
+
|
3
|
+
class EBookPage {
|
4
|
+
|
5
|
+
#fileName;
|
6
|
+
#title;
|
7
|
+
|
8
|
+
constructor( fileName, title ) {
|
9
|
+
this.#fileName = fileName;
|
10
|
+
this.#title = title;
|
11
|
+
}
|
12
|
+
|
13
|
+
create() {
|
14
|
+
let html = this.#renderPageStart( this.#title );
|
15
|
+
html += this.renderPageBody();
|
16
|
+
html += this.#renderPageEnd();
|
17
|
+
fs.writeFileSync( this.#fileName, html );
|
18
|
+
}
|
19
|
+
|
20
|
+
getTitle() {
|
21
|
+
return this.#title;
|
22
|
+
}
|
23
|
+
|
24
|
+
#renderBodyStart() {
|
25
|
+
return "<body>";
|
26
|
+
}
|
27
|
+
|
28
|
+
renderPageBody() {
|
29
|
+
throw new Error( "must be implemented by subclass" );
|
30
|
+
}
|
31
|
+
|
32
|
+
#renderPageEnd() {
|
33
|
+
return "</body></html>";
|
34
|
+
}
|
35
|
+
|
36
|
+
#renderPageStart( title ) {
|
37
|
+
let html = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
|
38
|
+
html += "<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:epub=\"http://www.idpf.org/2007/ops\">";
|
39
|
+
html += "<head><title>" + title + "</title>";
|
40
|
+
html += "<link href=\"./css/main.css\" rel=\"stylesheet\" />";
|
41
|
+
html += "</head>" + this.#renderBodyStart();
|
42
|
+
return html;
|
43
|
+
}
|
44
|
+
|
45
|
+
}
|
46
|
+
|
47
|
+
export { EBookPage };
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class Image {
|
2
|
+
|
3
|
+
#src;
|
4
|
+
#credit;
|
5
|
+
|
6
|
+
constructor( src, credit ) {
|
7
|
+
this.#src = src;
|
8
|
+
this.#credit = credit;
|
9
|
+
}
|
10
|
+
|
11
|
+
getCaption() {
|
12
|
+
return this.#credit ? this.#credit : undefined;
|
13
|
+
}
|
14
|
+
|
15
|
+
getSrc() {
|
16
|
+
return this.#src;
|
17
|
+
}
|
18
|
+
|
19
|
+
}
|
20
|
+
|
21
|
+
export { Image };
|
@@ -0,0 +1,27 @@
|
|
1
|
+
import { EBookPage } from "../ebookpage.js";
|
2
|
+
import { XHTML } from "../xhtml.js";
|
3
|
+
import { Families } from "../../families.js";
|
4
|
+
|
5
|
+
class PageListFamilies extends EBookPage {
|
6
|
+
|
7
|
+
constructor( outputDir ) {
|
8
|
+
super( outputDir + "/list_families.html", "All Families" );
|
9
|
+
}
|
10
|
+
|
11
|
+
renderPageBody() {
|
12
|
+
|
13
|
+
const html = XHTML.textElement( "h1", this.getTitle() );
|
14
|
+
|
15
|
+
const links = [];
|
16
|
+
for ( const family of Families.getFamilies() ) {
|
17
|
+
if ( !family.getTaxa() ) {
|
18
|
+
continue;
|
19
|
+
}
|
20
|
+
links.push( XHTML.getLink( family.getFileName(), family.getName() ) );
|
21
|
+
}
|
22
|
+
|
23
|
+
return html + XHTML.wrap( "ol", XHTML.arrayToLI( links ) );
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
export { PageListFamilies };
|
@@ -0,0 +1,26 @@
|
|
1
|
+
import { EBookPage } from "../ebookpage.js";
|
2
|
+
import { XHTML } from "../xhtml.js";
|
3
|
+
|
4
|
+
class PageListFlowerColor extends EBookPage {
|
5
|
+
|
6
|
+
#color;
|
7
|
+
|
8
|
+
constructor( outputDir, color ) {
|
9
|
+
super( outputDir + "/" + color.getFileName(), color.getColorName( true ) + " Flowers" );
|
10
|
+
this.#color = color;
|
11
|
+
}
|
12
|
+
|
13
|
+
renderPageBody() {
|
14
|
+
|
15
|
+
const html = XHTML.textElement( "h1", this.getTitle() );
|
16
|
+
|
17
|
+
const links = [];
|
18
|
+
for ( const taxon of this.#color.getTaxa() ) {
|
19
|
+
links.push( XHTML.getLink( taxon.getFileName(), taxon.getName() ) );
|
20
|
+
}
|
21
|
+
|
22
|
+
return html + XHTML.wrap( "ol", XHTML.arrayToLI( links ) );
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
26
|
+
export { PageListFlowerColor };
|
@@ -0,0 +1,26 @@
|
|
1
|
+
import { EBookPage } from "../ebookpage.js";
|
2
|
+
import { XHTML } from "../xhtml.js";
|
3
|
+
|
4
|
+
class PageListSpecies extends EBookPage {
|
5
|
+
|
6
|
+
#taxa;
|
7
|
+
|
8
|
+
constructor( outputDir, taxa, filename, title ) {
|
9
|
+
super( outputDir + "/" + filename, title );
|
10
|
+
this.#taxa = taxa;
|
11
|
+
}
|
12
|
+
|
13
|
+
renderPageBody() {
|
14
|
+
|
15
|
+
const html = XHTML.textElement( "h1", this.getTitle() );
|
16
|
+
|
17
|
+
const links = [];
|
18
|
+
for ( const taxon of this.#taxa ) {
|
19
|
+
links.push( XHTML.getLink( taxon.getFileName(), taxon.getName() ) );
|
20
|
+
}
|
21
|
+
|
22
|
+
return html + XHTML.wrap( "ol", XHTML.arrayToLI( links ) );
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
26
|
+
export { PageListSpecies };
|
@@ -0,0 +1,79 @@
|
|
1
|
+
import sizeOf from "image-size";
|
2
|
+
import markdownIt from "markdown-it";
|
3
|
+
import { Config, Files } from "@ca-plant-list/ca-plant-list";
|
4
|
+
import { EBookPage } from "../ebookpage.js";
|
5
|
+
import { XHTML } from "../xhtml.js";
|
6
|
+
|
7
|
+
class TaxonPage extends EBookPage {
|
8
|
+
|
9
|
+
#outputDir;
|
10
|
+
#taxon;
|
11
|
+
#photos;
|
12
|
+
|
13
|
+
constructor( outputDir, taxon, photos ) {
|
14
|
+
super( outputDir + "/" + taxon.getFileName(), taxon.getName() );
|
15
|
+
this.#outputDir = outputDir;
|
16
|
+
this.#taxon = taxon;
|
17
|
+
this.#photos = photos;
|
18
|
+
}
|
19
|
+
|
20
|
+
renderPageBody() {
|
21
|
+
|
22
|
+
function renderColors( colors ) {
|
23
|
+
if ( !colors ) {
|
24
|
+
return "";
|
25
|
+
}
|
26
|
+
let html = "";
|
27
|
+
for ( const color of colors ) {
|
28
|
+
// html += XHTML.textElement( "span", "", { class: "color " + color } );
|
29
|
+
html += XHTML.textElement( "img", "", { src: "./i/f-" + color + ".svg", class: "flr" } );
|
30
|
+
}
|
31
|
+
return html;
|
32
|
+
}
|
33
|
+
|
34
|
+
|
35
|
+
function renderCustomText( name ) {
|
36
|
+
// See if there is custom text.
|
37
|
+
const fileName = Config.getPackageDir() + "/data/text/" + name + ".md";
|
38
|
+
if ( !Files.exists( fileName ) ) {
|
39
|
+
return "";
|
40
|
+
}
|
41
|
+
const text = Files.read( fileName );
|
42
|
+
const md = new markdownIt();
|
43
|
+
return md.render( text );
|
44
|
+
}
|
45
|
+
|
46
|
+
const name = this.#taxon.getName();
|
47
|
+
let html = XHTML.textElement( "h1", name );
|
48
|
+
|
49
|
+
const family = this.#taxon.getFamily();
|
50
|
+
html += XHTML.wrap( "div", XHTML.getLink( family.getFileName(), family.getName() ) );
|
51
|
+
|
52
|
+
const cn = this.#taxon.getCommonNames();
|
53
|
+
if ( cn && cn.length > 0 ) {
|
54
|
+
html += XHTML.textElement( "p", cn.join( ", " ) );
|
55
|
+
}
|
56
|
+
|
57
|
+
html += renderColors( this.#taxon.getFlowerColors() );
|
58
|
+
|
59
|
+
html += renderCustomText( this.#taxon.getBaseFileName() );
|
60
|
+
|
61
|
+
if ( this.#photos ) {
|
62
|
+
for ( const photo of this.#photos ) {
|
63
|
+
const src = photo.getSrc();
|
64
|
+
const dimensions = sizeOf( this.#outputDir + "/" + src );
|
65
|
+
let img = XHTML.textElement( "img", "", { src: src, style: "max-width:" + dimensions.width + "px" } );
|
66
|
+
const caption = photo.getCaption();
|
67
|
+
if ( caption ) {
|
68
|
+
img += XHTML.textElement( "figcaption", caption );
|
69
|
+
}
|
70
|
+
html += XHTML.wrap( "figure", img );
|
71
|
+
}
|
72
|
+
}
|
73
|
+
|
74
|
+
return html;
|
75
|
+
}
|
76
|
+
|
77
|
+
}
|
78
|
+
|
79
|
+
export { TaxonPage };
|
@@ -0,0 +1,37 @@
|
|
1
|
+
import { EBookPage } from "../ebookpage.js";
|
2
|
+
import { XHTML } from "../xhtml.js";
|
3
|
+
import { FLOWER_COLOR_NAMES } from "../../taxa.js";
|
4
|
+
|
5
|
+
class TOCPage extends EBookPage {
|
6
|
+
|
7
|
+
constructor( outputDir ) {
|
8
|
+
super( outputDir + "/toc.xhtml", "Table of Contents" );
|
9
|
+
}
|
10
|
+
|
11
|
+
renderPageBody() {
|
12
|
+
|
13
|
+
let html = "<nav id=\"toc\" role=\"doc-toc\" epub:type=\"toc\">";
|
14
|
+
html += "<h1 epub:type=\"title\">Table of Contents</h1>";
|
15
|
+
|
16
|
+
const mainLinks = [];
|
17
|
+
mainLinks.push( this.#getFlowerColorLinks() );
|
18
|
+
mainLinks.push( XHTML.getLink( "./list_families.html", "All Families" ) );
|
19
|
+
mainLinks.push( XHTML.getLink( "./list_species.html", "All Species" ) );
|
20
|
+
html += XHTML.wrap( "ol", XHTML.arrayToLI( mainLinks ) );
|
21
|
+
|
22
|
+
html += "</nav>";
|
23
|
+
|
24
|
+
return html;
|
25
|
+
}
|
26
|
+
|
27
|
+
#getFlowerColorLinks() {
|
28
|
+
const html = XHTML.textElement( "span", "Flower Color" );
|
29
|
+
const links = [];
|
30
|
+
for ( const colorName of FLOWER_COLOR_NAMES ) {
|
31
|
+
links.push( XHTML.getLink( "list_fc_" + colorName + ".html", colorName ) );
|
32
|
+
}
|
33
|
+
return html + XHTML.wrap( "ol", XHTML.arrayToLI( links ) );
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
export { TOCPage };
|