@ca-plant-list/ca-plant-list 0.2.18 → 0.3.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.
@@ -1,57 +1,6 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
1
+ ---
2
+ layout: default
3
+ ---
3
4
 
4
- <head>
5
- <meta charset="utf-8">
6
- <meta name="viewport" content="width=device-width, initial-scale=1">
7
- <link href="{{site.bootstrap-prefix}}/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">
8
- <title>{{page.title}}</title>
9
- <link href="{{site.baseurl}}/assets/css/main.css" rel="stylesheet">
10
- </head>
11
-
12
- <body>
13
-
14
- <nav class="navbar navbar-expand-md">
15
- <div class="container-xxl px-5">
16
- <button id="hamburger" class="navbar-toggler" type="button" data-bs-toggle="collapse"
17
- data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false"
18
- aria-label="Toggle navigation">
19
- <span class="navbar-toggler-icon"></span>
20
- </button>
21
- <a class="navbar-brand" href="{{'/' | relative_url}}">{{site.navbar-name}}</a>
22
- <div class="collapse navbar-collapse" id="navbarSupportedContent">
23
- <ul class="navbar-nav me-auto mb-lg-0">
24
- <li class="nav-item">
25
- <a class="nav-link" href="{{site.baseurl}}/index_lists.html">Plant Lists</a>
26
- </li>
27
- <li class="nav-item">
28
- <a class="nav-link" href="{{site.baseurl}}/rare_plants.html">Rare Plants</a>
29
- </li>
30
- <li class="nav-item">
31
- <a class="nav-link" href="{{site.baseurl}}/name_search.html">Name Search</a>
32
- </li>
33
- <li class="nav-item">
34
- <a class="nav-link" href="{{site.baseurl}}/glossary.html">Glossary</a>
35
- </li>
36
- {%include menu_extra.html %}
37
- </ul>
38
- </div>
39
- </div>
40
- </nav>
41
-
42
- <div class="container-xxl px-5">
43
- <h1>{{page.title}}</h1>
44
- {{content}}
45
- </div>
46
-
47
- <script src="{{site.bootstrap-prefix}}/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script>
48
-
49
- {%if page.js%}
50
- <script src="{{site.baseurl}}/assets/js/{{page.js}}" type="module"></script>{%endif%}
51
-
52
- <script src="{{site.baseurl}}/assets/js/ui.js" type="module"></script>
53
-
54
- {%include analytics.html%}
55
- </body>
56
-
57
- </html>
5
+ <h1>{{page.title}}</h1>
6
+ {{content}}
@@ -73,6 +73,11 @@ span.rare::before {
73
73
  content: "\2606";
74
74
  }
75
75
 
76
+ /* Glossary */
77
+ div.glossary img {
78
+ max-height: 300px;
79
+ }
80
+
76
81
  /* Taxon Page */
77
82
 
78
83
  .common-names {
@@ -1,24 +1,29 @@
1
1
  import { Config } from "./config.js";
2
2
  import { Families } from "./families.js";
3
3
  import { Files } from "./files.js";
4
+ import { Jekyll } from "./jekyll.js";
5
+ import { Taxa } from "./taxa.js";
4
6
  import { GlossaryPages } from "./web/glossarypages.js";
5
7
 
6
8
  class BasePageRenderer {
7
9
 
8
10
  static render( outputDir, taxa, familyCols ) {
9
11
 
12
+ const siteGenerator = new Jekyll( outputDir );
13
+
10
14
  // Copy static files
11
15
  Files.rmDir( outputDir );
12
16
  // First copy default Jekyll files from package.
13
17
  Files.copyDir( Config.getPackageDir() + "/jekyll", outputDir );
14
18
  // Then copy Jekyll files from current dir (which may override default files).
15
19
  Files.copyDir( "jekyll", outputDir );
20
+
16
21
  // Copy illustrations.
17
- Files.copyDir( Config.getPackageDir() + "/data/illustrations/optimized", outputDir + "/i" );
22
+ siteGenerator.copyIllustrations( Taxa.getFlowerColors() );
18
23
 
19
24
  Families.renderPages( outputDir, familyCols );
20
25
 
21
- new GlossaryPages( outputDir ).renderPages();
26
+ new GlossaryPages( siteGenerator ).renderPages();
22
27
 
23
28
  this.renderTools( outputDir, taxa );
24
29
 
@@ -0,0 +1,34 @@
1
+ import { Files } from "../files.js";
2
+ import { SiteGenerator } from "../sitegenerator.js";
3
+
4
+ class EBookSiteGenerator extends SiteGenerator {
5
+
6
+ constructor( baseDir ) {
7
+ super( baseDir );
8
+ }
9
+
10
+ #pageEnd() {
11
+ return "</body></html>";
12
+ }
13
+
14
+ #pageStart( depth, attributes ) {
15
+ let html = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
16
+ html += "<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:epub=\"http://www.idpf.org/2007/ops\">";
17
+ html += "<head><title>" + attributes.title + "</title>";
18
+ html += "<link href=\"" + "../".repeat( depth ) + "css/main.css\" rel=\"stylesheet\" />";
19
+ html += "</head><body>";
20
+ return html;
21
+ }
22
+
23
+ #wrap( depth, content, attributes ) {
24
+ return this.#pageStart( depth, attributes ) + content + this.#pageEnd();
25
+ }
26
+
27
+ writeTemplate( content, attributes, filename ) {
28
+ const depth = ( filename.match( /\//g ) || [] ).length;
29
+ Files.write( Files.join( this.getBaseDir(), filename ), this.#wrap( depth, content, attributes ) );
30
+ }
31
+
32
+ }
33
+
34
+ export { EBookSiteGenerator };
@@ -1,46 +1,15 @@
1
- import * as fs from "node:fs";
2
-
3
- import { EBookPage } from "./ebookpage.js";
4
- import { XHTML } from "./xhtml.js";
5
-
6
- import { HTML } from "../html.js";
7
- import { Markdown } from "../markdown.js";
1
+ import { GlossaryPages as BaseGlossaryPages } from "../web/glossarypages.js";
8
2
  import { EBook } from "./ebook.js";
9
3
 
10
- import { Glossary } from "../plants/glossary.js";
11
-
12
- class GlossaryPages {
13
-
14
- #glossary;
15
-
16
- constructor() {
17
- this.#glossary = new Glossary();
18
- }
19
-
20
- createPages( contentDir ) {
21
-
22
- const termList = [];
23
-
24
- // Create target directory.
25
- const dirTarget = contentDir + "/g";
26
- fs.mkdirSync( dirTarget, { recursive: true } );
27
-
28
- for ( const entry of this.#glossary.getEntries() ) {
29
-
30
- new PageGlossaryEntry( contentDir, entry ).create();
31
-
32
- // Add term to index page list.
33
- termList.push( HTML.getLink( "g/" + entry.getHTMLFileName(), entry.getTermName() ) );
34
-
35
- }
4
+ class GlossaryPages extends BaseGlossaryPages {
36
5
 
37
- // Write glossary index page.
38
- new PageGlossary( contentDir, termList ).create();
6
+ constructor( siteGenerator ) {
7
+ super( siteGenerator );
39
8
  }
40
9
 
41
10
  getManifestEntries() {
42
11
 
43
- const glossaryEntries = this.#glossary.getEntries();
12
+ const glossaryEntries = this.getGlossary().getEntries();
44
13
  const manifestEntries = [];
45
14
 
46
15
  manifestEntries.push( EBook.getManifestEntry( "g", "glossary.html" ) );
@@ -54,7 +23,7 @@ class GlossaryPages {
54
23
 
55
24
  getSpineEntries() {
56
25
 
57
- const glossaryEntries = this.#glossary.getEntries();
26
+ const glossaryEntries = this.getGlossary().getEntries();
58
27
  const spineEntries = [];
59
28
 
60
29
  spineEntries.push( EBook.getSpineEntry( "g", "glossary.html" ) );
@@ -68,34 +37,4 @@ class GlossaryPages {
68
37
 
69
38
  }
70
39
 
71
- class PageGlossary extends EBookPage {
72
-
73
- #entries;
74
-
75
- constructor( outputDir, entries ) {
76
- super( outputDir + "/glossary.html", "Glossary" );
77
- this.#entries = entries;
78
- }
79
-
80
- renderPageBody() {
81
- const html = XHTML.textElement( "h1", this.getTitle() );
82
- return html + XHTML.wrap( "ol", XHTML.arrayToLI( this.#entries ) );
83
- }
84
- }
85
-
86
- class PageGlossaryEntry extends EBookPage {
87
-
88
- #entry;
89
-
90
- constructor( outputDir, entry ) {
91
- super( outputDir + "/g/" + entry.getHTMLFileName(), entry.getTermName(), "../" );
92
- this.#entry = entry;
93
- }
94
-
95
- renderPageBody() {
96
- const html = XHTML.textElement( "h1", this.getTitle() );
97
- return html + Markdown.strToHTML( this.#entry.getMarkdown() );
98
- }
99
- }
100
-
101
40
  export { GlossaryPages };
@@ -7,14 +7,17 @@ import { Config, CSV, Files } from "@ca-plant-list/ca-plant-list";
7
7
 
8
8
  import { Image } from "./image.js";
9
9
  import { EBook } from "./ebook.js";
10
+ import { Taxa } from "../taxa.js";
10
11
 
11
12
  class Images {
12
13
 
13
- #taxa;
14
+ #siteGenerator;
14
15
  #contentDir;
16
+ #taxa;
15
17
  #images = {};
16
18
 
17
- constructor( contentDir, taxa ) {
19
+ constructor( siteGenerator, contentDir, taxa ) {
20
+ this.#siteGenerator = siteGenerator;
18
21
  this.#contentDir = contentDir;
19
22
  this.#taxa = taxa;
20
23
  }
@@ -55,20 +58,16 @@ class Images {
55
58
  await Files.fetch( src, srcFileName );
56
59
  }
57
60
 
58
- await new sharp( srcFileName ).resize( { width: 400 } ).jpeg( { quality: 40 } ).toFile( targetFileName );
61
+ await new sharp( srcFileName ).resize( { width: 300 } ).jpeg( { quality: 40 } ).toFile( targetFileName );
59
62
 
60
63
  imageList.push( new Image( imagePrefix + "/" + filename, row[ "credit" ] ) );
61
64
 
62
65
  }
63
66
 
64
- this.#getIllustrations( this.#contentDir );
67
+ this.#siteGenerator.copyIllustrations( Taxa.getFlowerColors() );
65
68
 
66
69
  }
67
70
 
68
- #getIllustrations() {
69
- Files.copyDir( Config.getPackageDir() + "/data/illustrations/optimized", this.#contentDir + "/i" );
70
- }
71
-
72
71
  getManifestEntries() {
73
72
 
74
73
  const entries = [];
@@ -83,6 +82,9 @@ class Images {
83
82
  return entries.join( "" );
84
83
  }
85
84
 
85
+ getTaxonImages( name ) {
86
+ return this.#images[ name ];
87
+ }
86
88
  }
87
89
 
88
90
  export { Images };
@@ -67,6 +67,7 @@ class TaxonPage extends EBookPage {
67
67
  html += renderCustomText( this.#taxon.getBaseFileName() );
68
68
 
69
69
  if ( this.#photos ) {
70
+ let photoHTML = "";
70
71
  for ( const photo of this.#photos ) {
71
72
  const src = photo.getSrc();
72
73
  const dimensions = sizeOf( this.#outputDir + "/" + src );
@@ -75,7 +76,10 @@ class TaxonPage extends EBookPage {
75
76
  if ( caption ) {
76
77
  img += XHTML.textElement( "figcaption", caption );
77
78
  }
78
- html += XHTML.wrap( "figure", img );
79
+ photoHTML += XHTML.wrap( "figure", img );
80
+ }
81
+ if ( photoHTML ) {
82
+ html += XHTML.wrap( "div", photoHTML );
79
83
  }
80
84
  }
81
85
 
@@ -1,6 +1,6 @@
1
+ import { Taxa } from "../../taxa.js";
1
2
  import { EBookPage } from "../ebookpage.js";
2
3
  import { XHTML } from "../xhtml.js";
3
- import { FLOWER_COLOR_NAMES } from "../../taxa.js";
4
4
  import { PageListFlowers } from "./page_list_flowers.js";
5
5
 
6
6
  class TOCPage extends EBookPage {
@@ -30,7 +30,7 @@ class TOCPage extends EBookPage {
30
30
  #getFlowerColorLinks() {
31
31
  const html = XHTML.textElement( "span", "Flower Color" );
32
32
  const links = [];
33
- for ( const colorName of FLOWER_COLOR_NAMES ) {
33
+ for ( const colorName of Taxa.getFlowerColorNames() ) {
34
34
  links.push( XHTML.getLink( "list_fc_" + colorName + ".html", colorName ) );
35
35
  }
36
36
  return html + XHTML.wrap( "ol", XHTML.arrayToLI( links ) );
@@ -1,5 +1,6 @@
1
1
  import { Families } from "@ca-plant-list/ca-plant-list";
2
2
  import { EBook } from "./ebook.js";
3
+ import { EBookSiteGenerator } from "./ebooksitegenerator.js";
3
4
  import { GlossaryPages } from "./glossarypages.js";
4
5
  import { Images } from "./images.js";
5
6
  import { PageListFamilies } from "./pages/page_list_families.js";
@@ -8,7 +9,7 @@ import { PageListFlowers } from "./pages/page_list_flowers.js";
8
9
  import { PageListSpecies } from "./pages/page_list_species.js";
9
10
  import { TaxonPage } from "./pages/taxonpage.js";
10
11
  import { TOCPage } from "./pages/tocpage.js";
11
- import { FLOWER_COLOR_NAMES } from "../taxa.js";
12
+ import { Taxa } from "../taxa.js";
12
13
 
13
14
  class PlantBook extends EBook {
14
15
 
@@ -26,8 +27,9 @@ class PlantBook extends EBook {
26
27
  );
27
28
 
28
29
  this.#taxa = taxa;
29
- this.#glossary = new GlossaryPages();
30
- this.#images = new Images( this.getContentDir(), taxa );
30
+ const generator = new EBookSiteGenerator( this.getContentDir() );
31
+ this.#glossary = new GlossaryPages( generator );
32
+ this.#images = new Images( generator, this.getContentDir(), taxa );
31
33
 
32
34
  }
33
35
 
@@ -35,15 +37,17 @@ class PlantBook extends EBook {
35
37
 
36
38
  const contentDir = this.getContentDir();
37
39
 
40
+ await this.#images.createImages( contentDir );
41
+
38
42
  console.log( "creating taxon pages" );
39
43
  const taxonList = this.#taxa.getTaxonList();
40
44
  for ( const taxon of taxonList ) {
41
45
  const name = taxon.getName();
42
- new TaxonPage( contentDir, taxon, this.#images[ name ] ).create();
46
+ new TaxonPage( contentDir, taxon, this.#images.getTaxonImages( name ) ).create();
43
47
  }
44
48
 
45
49
  // Create lists.
46
- for ( const colorName of FLOWER_COLOR_NAMES ) {
50
+ for ( const colorName of Taxa.getFlowerColorNames() ) {
47
51
  new PageListFlowerColor( contentDir, this.#taxa.getFlowerColor( colorName ) ).create();
48
52
  }
49
53
 
@@ -60,8 +64,7 @@ class PlantBook extends EBook {
60
64
  }
61
65
  new PageListSpecies( contentDir, taxonList, "list_species.html", "All Species" ).create();
62
66
 
63
- await this.#images.createImages( contentDir );
64
- this.#glossary.createPages( contentDir );
67
+ this.#glossary.renderPages();
65
68
 
66
69
  new TOCPage( contentDir ).create();
67
70
  }
@@ -73,7 +76,7 @@ class PlantBook extends EBook {
73
76
  // Add lists.
74
77
  xml += "<item id=\"lspecies\" href=\"list_species.html\" media-type=\"application/xhtml+xml\" />";
75
78
  xml += "<item id=\"lfamilies\" href=\"list_families.html\" media-type=\"application/xhtml+xml\" />";
76
- for ( const colorName of FLOWER_COLOR_NAMES ) {
79
+ for ( const colorName of Taxa.getFlowerColorNames() ) {
77
80
  const color = this.#taxa.getFlowerColor( colorName );
78
81
  xml += "<item id=\"l" + color.getColorName() + "\" href=\"" + color.getFileName() + "\" media-type=\"application/xhtml+xml\" />";
79
82
  }
@@ -105,7 +108,7 @@ class PlantBook extends EBook {
105
108
  let xml = "";
106
109
 
107
110
  // Add lists.
108
- for ( const colorName of FLOWER_COLOR_NAMES ) {
111
+ for ( const colorName of Taxa.getFlowerColorNames() ) {
109
112
  const color = this.#taxa.getFlowerColor( colorName );
110
113
  xml += "<itemref idref=\"l" + color.getColorName() + "\"/>";
111
114
  }
package/lib/errorlog.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import * as fs from "node:fs";
2
+ import * as path from "node:path";
2
3
 
3
4
  class ErrorLog {
4
5
 
@@ -19,6 +20,9 @@ class ErrorLog {
19
20
  }
20
21
 
21
22
  write() {
23
+ // Make sure directory exists.
24
+ fs.mkdirSync( path.dirname( this.#fileName ), { recursive: true } );
25
+
22
26
  fs.writeFileSync( this.#fileName, this.#errors.join( "\n" ) );
23
27
  }
24
28
 
package/lib/files.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import * as fs from "node:fs";
2
+ import * as path from "node:path";
2
3
  import { default as unzipper } from "unzipper";
3
4
 
4
5
  class Files {
@@ -52,6 +53,10 @@ class Files {
52
53
  return stats !== undefined && stats.isDirectory();
53
54
  }
54
55
 
56
+ static join( ...paths ) {
57
+ return path.join( ...paths ).replaceAll( "\\", "/" );
58
+ }
59
+
55
60
  static mkdir( path ) {
56
61
  fs.mkdirSync( path, { recursive: true } );
57
62
  }
package/lib/index.d.ts CHANGED
@@ -76,6 +76,7 @@ export class Files {
76
76
  static fetch(url: string | URL, targetFileName: string | undefined, headers?: any): Promise<Headers>;
77
77
  static getDirEntries(path: any): string[];
78
78
  static isDir(path: any): boolean;
79
+ static join(...paths: any[]): any;
79
80
  static mkdir(path: any): void;
80
81
  static read(path: any): string;
81
82
  static rmDir(dir: any): void;
@@ -174,12 +175,14 @@ import { TaxaProcessor } from "./taxaprocessor.js";
174
175
  import { TAXA_COLNAMES } from "./taxon.js";
175
176
  import { Taxon } from "./taxon.js";
176
177
  export { BasePageRenderer, CommandProcessor, CommandAndTaxaProcessor, Config, CSV, ErrorLog, Exceptions, Families, Files, GenericTaxaLoader, HTML, Jekyll, PlantBook, Taxa, TaxaLoader, TaxaProcessor, TAXA_COLNAMES, Taxon };
177
- export class Jekyll {
178
+ export class Jekyll extends SiteGenerator {
178
179
  static getFrontMatter(atts: any): string;
179
180
  static hasInclude(baseDir: any, path: any): boolean;
180
181
  static include(path: any): string;
181
182
  static writeInclude(baseDir: any, path: any, data: any): void;
183
+ writeTemplate(content: any, attributes: any, filename: any): void;
182
184
  }
185
+ import { SiteGenerator } from "./sitegenerator.js";
183
186
  export class Jepson {
184
187
  static getEFloraLink(id: any): string;
185
188
  }
@@ -194,12 +197,23 @@ export class RarePlants {
194
197
  static getRPIRankDescription(rank: any): any;
195
198
  static getRPIRankAndThreatDescriptions(rank: any): any[];
196
199
  }
197
- export const FLOWER_COLOR_NAMES: string[];
200
+ export class SiteGenerator {
201
+ constructor(baseDir: any);
202
+ copyIllustrations(flowerColors: any): void;
203
+ getBaseDir(): any;
204
+ mkdir(path: any): void;
205
+ #private;
206
+ }
198
207
  export class Taxa {
199
208
  static getHTMLTable(taxa: any, columns?: {
200
209
  title: string;
201
210
  data: (t: any) => any;
202
211
  }[]): string;
212
+ static getFlowerColorNames(): string[];
213
+ static getFlowerColors(): {
214
+ name: string;
215
+ color: string;
216
+ }[];
203
217
  constructor(inclusionList: any, errorLog: any, showFlowerErrors: any, taxaMeta?: {}, taxonClass?: typeof Taxon, extraTaxa?: any[], extraSynonyms?: any[]);
204
218
  getFlowerColor(name: any): any;
205
219
  getTaxon(name: any): any;
package/lib/jekyll.js CHANGED
@@ -1,14 +1,22 @@
1
1
  import { Files } from "./files.js";
2
+ import { SiteGenerator } from "./sitegenerator.js";
2
3
 
3
4
  const FRONT_DELIM = "---";
4
5
 
5
- class Jekyll {
6
+ class Jekyll extends SiteGenerator {
7
+
8
+ constructor( baseDir ) {
9
+ super( baseDir );
10
+ }
6
11
 
7
12
  static getFrontMatter( atts ) {
8
13
  const lines = [ FRONT_DELIM ];
9
14
  for ( const [ k, v ] of Object.entries( atts ) ) {
10
15
  lines.push( k + ": \"" + v + "\"" );
11
16
  }
17
+ if ( !atts.layout ) {
18
+ lines.push( "layout: default" );
19
+ }
12
20
  lines.push( FRONT_DELIM );
13
21
  return lines.join( "\n" ) + "\n";
14
22
  }
@@ -26,6 +34,10 @@ class Jekyll {
26
34
  Files.write( baseDir + "/_includes/" + path, data );
27
35
  }
28
36
 
37
+ writeTemplate( content, attributes, filename ) {
38
+ Files.write( Files.join( this.getBaseDir(), filename ), Jekyll.getFrontMatter( attributes ) + content );
39
+ }
40
+
29
41
  }
30
42
 
31
43
  export { Jekyll };
@@ -0,0 +1,79 @@
1
+ import { optimize } from "svgo";
2
+
3
+ import { Config } from "./config.js";
4
+ import { Files } from "./files.js";
5
+
6
+ class SiteGenerator {
7
+ #baseDir;
8
+
9
+ constructor( baseDir ) {
10
+ this.#baseDir = baseDir;
11
+ }
12
+
13
+ copyIllustrations( flowerColors ) {
14
+ function createFlowerColorIcons( outputDir, flowerColors ) {
15
+ // Read generic input.
16
+ const inputFileName = Files.join( outputDir, "flower.svg" );
17
+ const srcSVG = Files.read( inputFileName );
18
+ for ( const color of flowerColors ) {
19
+ Files.write(
20
+ Files.join( outputDir, "f-" + color.name + ".svg" ),
21
+ srcSVG.replace( "#ff0", color.color )
22
+ );
23
+ }
24
+ // Delete input file.
25
+ Files.rmDir( inputFileName );
26
+ }
27
+
28
+ function optimizeSVG( outputDir ) {
29
+ const srcDir = Config.getPackageDir() + "/data/illustrations/inkscape";
30
+ const entries = Files.getDirEntries( srcDir );
31
+ for ( const entry of entries ) {
32
+ const srcFile = Files.join( srcDir, entry );
33
+ const srcSVG = Files.read( srcFile );
34
+ const result = optimize( srcSVG, {
35
+ plugins: [
36
+ {
37
+ name: "preset-default",
38
+ params: {
39
+ overrides: {
40
+ // minifyStyles changes font-weight: normal to 400, which keeps it from being removed as a default.
41
+ // Disable it here and run it last.
42
+ minifyStyles: false,
43
+ removeViewBox: false,
44
+ },
45
+ },
46
+ },
47
+ "convertStyleToAttrs",
48
+ {
49
+ name: "removeAttrs",
50
+ params: {
51
+ attrs: "(style)",
52
+ },
53
+ },
54
+ "removeDimensions",
55
+ "minifyStyles",
56
+ ],
57
+ multipass: true,
58
+ } );
59
+ Files.write( Files.join( outputDir, entry ), result.data );
60
+ }
61
+ }
62
+
63
+ const outputDir = Files.join( this.#baseDir, "i" );
64
+ Files.mkdir( outputDir );
65
+
66
+ optimizeSVG( outputDir );
67
+ createFlowerColorIcons( outputDir, flowerColors );
68
+ }
69
+
70
+ getBaseDir() {
71
+ return this.#baseDir;
72
+ }
73
+
74
+ mkdir( path ) {
75
+ Files.mkdir( Files.join( this.#baseDir, path ) );
76
+ }
77
+ }
78
+
79
+ export { SiteGenerator };
package/lib/taxa.js CHANGED
@@ -4,7 +4,14 @@ import { HTML } from "./html.js";
4
4
  import { CSV } from "./csv.js";
5
5
  import { RarePlants } from "./rareplants.js";
6
6
 
7
- const FLOWER_COLOR_NAMES = [ "white", "red", "pink", "orange", "yellow", "blue" ];
7
+ const FLOWER_COLORS = [
8
+ { name: "white", color: "white" },
9
+ { name: "red", color: "red" },
10
+ { name: "pink", color: "pink" },
11
+ { name: "orange", color: "orange" },
12
+ { name: "yellow", color: "yellow" },
13
+ { name: "blue", color: "blue" },
14
+ ];
8
15
 
9
16
  const TAXA_LIST_COLS = {
10
17
  CESA: {
@@ -73,8 +80,8 @@ class Taxa {
73
80
 
74
81
  this.#errorLog = errorLog;
75
82
 
76
- for ( const color of FLOWER_COLOR_NAMES ) {
77
- this.#flower_colors[ color ] = new FlowerColor( color );
83
+ for ( const color of FLOWER_COLORS ) {
84
+ this.#flower_colors[ color.name ] = new FlowerColor( color.name );
78
85
  }
79
86
 
80
87
  const dataDir = Config.getPackageDir() + "/data";
@@ -130,6 +137,14 @@ class Taxa {
130
137
  return this.#flower_colors[ name ];
131
138
  }
132
139
 
140
+ static getFlowerColorNames() {
141
+ return FLOWER_COLORS.map( ( o ) => o.name );
142
+ }
143
+
144
+ static getFlowerColors() {
145
+ return FLOWER_COLORS;
146
+ }
147
+
133
148
  getTaxon( name ) {
134
149
  return this.#taxa[ name ];
135
150
  }
@@ -206,4 +221,4 @@ class Taxa {
206
221
 
207
222
  }
208
223
 
209
- export { FLOWER_COLOR_NAMES, Taxa, TAXA_LIST_COLS };
224
+ export { Taxa, TAXA_LIST_COLS };