@ca-plant-list/ca-plant-list 0.3.6 → 0.4.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.
Files changed (94) hide show
  1. package/.vscode/settings.json +7 -1
  2. package/data/synonyms.csv +109 -3
  3. package/data/taxa.csv +65 -29
  4. package/data/text/Antennaria-media.md +1 -0
  5. package/data/text/Antennaria-rosea-subsp-rosea.md +1 -0
  6. package/data/text/Antirrhinum-thompsonii.md +1 -0
  7. package/data/text/Calyptridium-monospermum.md +1 -0
  8. package/data/text/Calyptridium-umbellatum.md +1 -0
  9. package/data/text/Camassia-leichtlinii-subsp-suksdorfii.md +1 -0
  10. package/data/text/Camassia-quamash-subsp-breviflora.md +1 -0
  11. package/data/text/Clarkia-affinis.md +1 -0
  12. package/data/text/Clarkia-breweri.md +1 -0
  13. package/data/text/Clarkia-concinna-subsp-automixa.md +1 -0
  14. package/data/text/Clarkia-modesta.md +1 -0
  15. package/data/text/Clarkia-purpurea-subsp-quadrivulnera.md +1 -0
  16. package/data/text/Clarkia-rubicunda.md +1 -0
  17. package/data/text/Delphinium-californicum-subsp-californicum.md +1 -1
  18. package/data/text/Delphinium-californicum-subsp-interius.md +1 -0
  19. package/data/text/Delphinium-glaucum.md +1 -0
  20. package/data/text/Delphinium-hesperium-subsp-hesperium.md +1 -1
  21. package/data/text/Delphinium-hesperium-subsp-pallescens.md +1 -0
  22. package/data/text/Delphinium-nuttallianum.md +1 -0
  23. package/data/text/Delphinium-parryi-subsp-parryi.md +1 -0
  24. package/data/text/Drymocallis-glandulosa-var-glandulosa.md +1 -0
  25. package/data/text/Drymocallis-lactea-var-austiniae.md +1 -0
  26. package/data/text/Erigeron-compositus.md +1 -0
  27. package/data/text/Erigeron-glacialis-var-glacialis.md +1 -0
  28. package/data/text/Erythranthe-breweri.md +1 -0
  29. package/data/text/Erythranthe-erubescens.md +1 -0
  30. package/data/text/Erythranthe-moschata.md +1 -0
  31. package/data/text/Erythranthe-primuloides.md +1 -0
  32. package/data/text/Erythranthe-tilingii.md +1 -0
  33. package/data/text/Lilium-pardalinum-subsp-shastense.md +1 -0
  34. package/data/text/Logfia-filaginoides.md +1 -0
  35. package/data/text/Logfia-gallica.md +1 -0
  36. package/data/text/Malacothamnus-arcuatus-var-elmeri.md +1 -0
  37. package/data/text/Malacothamnus-fremontii-var-fremontii.md +1 -0
  38. package/data/text/Navarretia-leptalea-subsp-bicolor.md +1 -0
  39. package/data/text/Navarretia-leptalea-subsp-leptalea.md +1 -0
  40. package/data/text/Polemonium-californicum.md +1 -0
  41. package/data/text/Polemonium-pulcherrimum-var-pulcherrimum.md +1 -0
  42. package/data/text/Primula-jeffreyi.md +1 -0
  43. package/data/text/Primula-tetrandra.md +1 -0
  44. package/data/text/Trifolium-obtusiflorum.md +1 -0
  45. package/data/text/Trifolium-willdenovii.md +1 -0
  46. package/lib/basepagerenderer.js +3 -4
  47. package/lib/config.js +42 -19
  48. package/lib/csv.js +54 -36
  49. package/lib/ebook/ebook.js +84 -57
  50. package/lib/ebook/ebookpage.js +22 -11
  51. package/lib/ebook/ebooksitegenerator.js +36 -14
  52. package/lib/ebook/glossarypages.js +20 -17
  53. package/lib/ebook/images.js +59 -42
  54. package/lib/ebook/pages/page_list_families.js +0 -2
  55. package/lib/ebook/pages/page_list_flower_color.js +14 -9
  56. package/lib/ebook/pages/page_list_flowers.js +59 -41
  57. package/lib/ebook/pages/page_list_species.js +15 -9
  58. package/lib/ebook/pages/taxonpage.js +3 -6
  59. package/lib/ebook/pages/tocpage.js +26 -20
  60. package/lib/ebook/plantbook.js +6 -13
  61. package/lib/ebook/{image.js → taxonimage.js} +2 -2
  62. package/lib/ebook/xhtml.js +3 -5
  63. package/lib/exceptions.js +42 -26
  64. package/lib/externalsites.js +11 -4
  65. package/lib/families.js +10 -10
  66. package/lib/flowercolor.js +42 -0
  67. package/lib/genera.js +13 -23
  68. package/lib/genericpage.js +38 -18
  69. package/lib/html.js +11 -23
  70. package/lib/htmltaxon.js +114 -14
  71. package/lib/index.d.ts +54 -0
  72. package/lib/index.js +2 -30
  73. package/lib/jekyll.js +49 -21
  74. package/lib/jepson.js +7 -8
  75. package/lib/markdown.js +13 -9
  76. package/lib/pagerenderer.js +162 -82
  77. package/lib/plants/glossary.js +14 -14
  78. package/lib/program.js +47 -0
  79. package/lib/rareplants.js +44 -30
  80. package/lib/sitegenerator.js +41 -24
  81. package/lib/taxa.js +25 -142
  82. package/lib/taxon.js +3 -5
  83. package/lib/web/glossarypages.js +37 -18
  84. package/lib/web/pagetaxon.js +1 -5
  85. package/package.json +5 -3
  86. package/schemas/exceptions.schema.json +57 -0
  87. package/scripts/build-ebook.js +39 -48
  88. package/scripts/build-site.js +49 -28
  89. package/types/classes.d.ts +154 -0
  90. package/lib/commandandtaxaprocessor.js +0 -25
  91. package/lib/commandprocessor.js +0 -108
  92. package/lib/generictaxaloader.js +0 -48
  93. package/lib/taxaloader.js +0 -48
  94. package/lib/taxaprocessor.js +0 -34
@@ -1,50 +1,23 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { PlantBook } from "@ca-plant-list/ca-plant-list";
4
3
  import { Config } from "../lib/config.js";
4
+ import { ErrorLog } from "../lib/errorlog.js";
5
5
  import { Files } from "../lib/files.js";
6
- import { TaxaProcessor } from "../lib/taxaprocessor.js";
7
- import { CommandProcessor } from "../lib/commandprocessor.js";
6
+ import { PlantBook } from "../lib/ebook/plantbook.js";
7
+ import { Program } from "../lib/program.js";
8
+ import { Taxa } from "../lib/taxa.js";
8
9
 
9
- const OPTION_DEFS = [{ name: "locationsdir", type: String }];
10
+ const program = Program.getProgram();
11
+ program
12
+ .option("-l, --locationsdir <dir>", "directory containing location data")
13
+ .action(build);
10
14
 
11
- const OPTION_HELP = [
12
- {
13
- name: "locationsdir",
14
- type: String,
15
- typeLabel: "{underline path}",
16
- description:
17
- "If this option is specified, multiple ebooks will be generated. {bold locationsdir} must be a subdirectory" +
18
- " of the current directory, and each subdirectory of {bold locationsdir} is processed in turn to generate an ebook." +
19
- " Each ebook is placed in a subdirectory of {bold outputdir}.",
20
- },
21
- ];
22
-
23
- class BookCommand extends CommandProcessor {
24
- constructor() {
25
- super(
26
- "ca-plant-book",
27
- "A tool to generate an ebook with local plant data.",
28
- OPTION_DEFS,
29
- OPTION_HELP
30
- );
31
- }
32
- }
15
+ await program.parseAsync();
33
16
 
34
17
  /**
35
- * @param {TaxaProcessor} tp
18
+ * @param {import("commander").OptionValues} options
36
19
  */
37
- async function commandRunner(tp) {
38
- const options = tp.getOptions();
39
- const ebook = new PlantBook(
40
- options.outputdir,
41
- new Config(options.datadir),
42
- tp.getTaxa()
43
- );
44
- await ebook.create();
45
- }
46
-
47
- async function generateEBooks(options) {
20
+ async function build(options) {
48
21
  const locationsDir = options.locationsdir;
49
22
 
50
23
  // If there is a "locations" directory, generate a book for all subdirectories.
@@ -57,21 +30,39 @@ async function generateEBooks(options) {
57
30
  const suffix = "/" + subdir;
58
31
  const path = locationsDir + suffix;
59
32
  if (Files.isDir(path)) {
60
- options.datadir = path;
61
- options.outputdir = outputBase + suffix;
62
- const gen = new TaxaProcessor(options);
63
- await gen.process(commandRunner);
33
+ await buildBook(
34
+ outputBase + suffix,
35
+ path,
36
+ options.showFlowerErrors
37
+ );
64
38
  }
65
39
  }
66
40
  } else {
67
41
  // Otherwise use the default directory.
68
- const gen = new TaxaProcessor(options);
69
- await gen.process(commandRunner);
42
+ await buildBook(
43
+ options.outputdir,
44
+ options.datadir,
45
+ options.showFlowerErrors
46
+ );
70
47
  }
71
48
  }
72
49
 
73
- const cmd = new BookCommand();
74
- const options = cmd.getOptions();
75
- if (!options.help) {
76
- await generateEBooks(options);
50
+ /**
51
+ * @param {string} outputDir
52
+ * @param {string} dataDir
53
+ * @param {boolean} showFlowerErrors
54
+ */
55
+ async function buildBook(outputDir, dataDir, showFlowerErrors) {
56
+ const errorLog = new ErrorLog(outputDir + "/errors.tsv");
57
+
58
+ const taxa = new Taxa(
59
+ Program.getIncludeList(dataDir),
60
+ errorLog,
61
+ showFlowerErrors
62
+ );
63
+
64
+ const config = new Config(dataDir);
65
+ const ebook = new PlantBook(outputDir, config, taxa);
66
+ await ebook.create();
67
+ errorLog.write();
77
68
  }
@@ -2,54 +2,75 @@
2
2
 
3
3
  import * as child_process from "node:child_process";
4
4
  import * as path from "node:path";
5
- import { Files } from "@ca-plant-list/ca-plant-list";
6
5
  import { Config } from "../lib/config.js";
7
6
  import { PageRenderer } from "../lib/pagerenderer.js";
8
- import { CommandAndTaxaProcessor } from "../lib/commandandtaxaprocessor.js";
7
+ import { Files } from "../lib/files.js";
8
+ import { Program } from "../lib/program.js";
9
+ import { Taxa } from "../lib/taxa.js";
10
+ import { ErrorLog } from "../lib/errorlog.js";
9
11
 
10
12
  class JekyllRenderer {
11
-
12
13
  #srcDir = "./output";
13
14
  #destDir = "./public";
14
15
 
15
16
  async renderPages() {
16
-
17
- function addConfigFile( configFiles, dir, name ) {
18
- const fullPath = path.join( dir, name );
19
- if ( Files.exists( fullPath ) ) {
20
- configFiles.push( fullPath );
17
+ /**
18
+ * @param {string[]} configFiles
19
+ * @param {string} dir
20
+ * @param {string} name
21
+ */
22
+ function addConfigFile(configFiles, dir, name) {
23
+ const fullPath = path.join(dir, name);
24
+ if (Files.exists(fullPath)) {
25
+ configFiles.push(fullPath);
21
26
  }
22
27
  }
23
28
 
24
29
  // Remove existing files.
25
- Files.rmDir( this.#destDir );
30
+ Files.rmDir(this.#destDir);
26
31
 
27
- const options = [ "--source", this.#srcDir, "--destination", this.#destDir ];
32
+ const options = [
33
+ "--source",
34
+ this.#srcDir,
35
+ "--destination",
36
+ this.#destDir,
37
+ ];
28
38
 
29
39
  // Find out what config files are available.
40
+ /** @type {string[]} */
30
41
  const configFiles = [];
31
- addConfigFile( configFiles, this.#srcDir, "_config.yml" );
32
- addConfigFile( configFiles, this.#srcDir, "_config-local.yml" );
33
- addConfigFile( configFiles, ".", "_config-dev.yml" );
34
- options.push( "--config", "\"" + configFiles.join() + "\"" );
35
-
36
- const result = child_process.execSync( "bundle exec jekyll build " + options.join( " " ) );
37
- console.log( result.toString() );
42
+ addConfigFile(configFiles, this.#srcDir, "_config.yml");
43
+ addConfigFile(configFiles, this.#srcDir, "_config-local.yml");
44
+ addConfigFile(configFiles, ".", "_config-dev.yml");
45
+ options.push("--config", '"' + configFiles.join() + '"');
46
+
47
+ const result = child_process.execSync(
48
+ "bundle exec jekyll build " + options.join(" ")
49
+ );
50
+ console.log(result.toString());
38
51
  }
39
-
40
52
  }
41
53
 
42
- async function generateSite( taxaProcessor ) {
43
-
44
- const options = taxaProcessor.getOptions();
45
-
46
- PageRenderer.render( options.outputdir, new Config( options.datadir ), taxaProcessor.getTaxa() );
47
-
48
- console.log( "generating site" );
54
+ /**
55
+ * @param {import("commander").OptionValues} options
56
+ */
57
+ async function build(options) {
58
+ Files.rmDir(options.outputdir);
59
+ const errorLog = new ErrorLog(options.outputdir + "/errors.tsv");
60
+ const taxa = new Taxa(
61
+ Program.getIncludeList(options.datadir),
62
+ errorLog,
63
+ options.showFlowerErrors
64
+ );
65
+ PageRenderer.render(options.outputdir, new Config(options.datadir), taxa);
66
+ errorLog.write();
67
+
68
+ console.log("generating site");
49
69
  const r = new JekyllRenderer();
50
70
  await r.renderPages();
51
-
52
71
  }
53
72
 
54
- const gen = new CommandAndTaxaProcessor( "ca-plant-list", "A tool to generate a website with local plant data.", generateSite );
55
- await gen.process( generateSite );
73
+ const program = Program.getProgram();
74
+ program.action(build);
75
+
76
+ await program.parseAsync();
@@ -0,0 +1,154 @@
1
+ declare class CommandLineOptions {
2
+ datadir: string;
3
+ outputdir: string;
4
+ "show-flower-errors": boolean;
5
+ }
6
+
7
+ declare class Config {
8
+ getConfigValue(
9
+ prefix: string,
10
+ name: string,
11
+ subcategory?: string,
12
+ defaultValue?: string
13
+ ): string;
14
+ getCountyCodes(): string[];
15
+ getLabel(name: string, dflt: string): string;
16
+ }
17
+
18
+ declare class ErrorLog {
19
+ log(...args: string[]): void;
20
+ write();
21
+ }
22
+
23
+ declare class Families {
24
+ getFamilies(): Family[];
25
+ getFamily(name: string): Family;
26
+ renderPages(outputDir: string, cols?: TaxaCol[]);
27
+ }
28
+
29
+ declare class Family {
30
+ getFileName(): string;
31
+ getName(): string;
32
+ getSectionName(): string;
33
+ getTaxa(): Taxon[];
34
+ }
35
+
36
+ declare class FlowerColor {
37
+ getColorCode(): string;
38
+ getColorName(upperCase?: boolean): string;
39
+ getFileName(): string;
40
+ getTaxa(): Taxon[];
41
+ }
42
+
43
+ declare class Genera {
44
+ addTaxon(Taxon);
45
+ getGenus(name: string): Genus;
46
+ }
47
+
48
+ declare class Genus {
49
+ getFamily(): Family;
50
+ getTaxa(): Taxon[];
51
+ }
52
+
53
+ declare class GlossaryEntry {
54
+ getMarkdown(): string;
55
+ getTermName(): string;
56
+ }
57
+
58
+ declare class Images {
59
+ getTaxonImages(name: string): TaxonImage[];
60
+ }
61
+
62
+ declare class InatObsOptions {
63
+ coords?: [number, number];
64
+ project_id?: string;
65
+ subview?: "grid" | "list" | "map";
66
+ taxon_id?: string;
67
+ }
68
+
69
+ declare class SiteGenerator {
70
+ copyIllustrations(flowerColors: FlowerColor[]);
71
+ mkdir(path: string);
72
+ writeTemplate(
73
+ content: string,
74
+ attributes: Object<string, string>,
75
+ filename: string
76
+ );
77
+ }
78
+
79
+ declare class SynonymData {
80
+ Current: string;
81
+ Former: string;
82
+ Type: string;
83
+ }
84
+
85
+ declare class Taxa {
86
+ getFamilies(): Families;
87
+ getFlowerColors(): FlowerColor[];
88
+ getTaxon(name: string): Taxon;
89
+ getTaxonList(): Taxon[];
90
+ }
91
+
92
+ declare class TaxaCol {
93
+ class?: string;
94
+ data: Object<string, Taxon>;
95
+ title: string;
96
+ }
97
+
98
+ declare class Taxon {
99
+ constructor(data: TaxonData, genera: Genera, meta: any);
100
+ getBaseFileName(): string;
101
+ getBloomEnd(): number | undefined;
102
+ getBloomStart(): number | undefined;
103
+ getCalfloraName(): string;
104
+ getCalfloraTaxonLink(): string | undefined;
105
+ getCESA(): string | undefined;
106
+ getCommonNames(): string[];
107
+ getFamily(): Family;
108
+ getFESA(): string | undefined;
109
+ getFileName(): string;
110
+ getFlowerColors(): string[] | undefined;
111
+ getGenus(): Genus;
112
+ getGenusName(): string;
113
+ getHTMLLink(
114
+ href: boolean | string | undefined,
115
+ includeRPI?: boolean
116
+ ): string;
117
+ getINatID(): string;
118
+ getINatName(): string;
119
+ getINatTaxonLink(): string;
120
+ getJepsonID(): string;
121
+ getLifeCycle(): string;
122
+ getName(): string;
123
+ getRPIRank(): string;
124
+ getRPIRankAndThreat(): string;
125
+ getRPIRankAndThreatTooltip(): string;
126
+ getRPITaxonLink(): string;
127
+ getStatusDescription(config: Config): string;
128
+ getSynonyms(): string[];
129
+ isNative(): boolean;
130
+ }
131
+
132
+ declare class TaxonData {
133
+ bloom_end: string;
134
+ bloom_start: string;
135
+ calrecnum: string;
136
+ CESA: string;
137
+ "common name": string;
138
+ CRPR: string;
139
+ FESA: string;
140
+ flower_color: string;
141
+ GRank: string;
142
+ "inat id": string;
143
+ "jepson id": string;
144
+ life_cycle: string;
145
+ "RPI ID": string;
146
+ SRank: string;
147
+ status: string;
148
+ taxon_name: string;
149
+ }
150
+
151
+ declare class TaxonImage {
152
+ getCaption(): string | undefined;
153
+ getSrc(): string;
154
+ }
@@ -1,25 +0,0 @@
1
- import { CommandProcessor } from "./commandprocessor.js";
2
- import { Files } from "./files.js";
3
- import { TaxaProcessor } from "./taxaprocessor.js";
4
-
5
- class CommandAndTaxaProcessor extends CommandProcessor {
6
-
7
- #taxaProcessor;
8
-
9
- constructor( commandName, commandDesc, optionDefs = [], optionHelp = [], commandHelp = [], taxaLoaderClass ) {
10
- super( commandName, commandDesc, optionDefs, optionHelp, commandHelp );
11
- this.#taxaProcessor = new TaxaProcessor( this.getOptions(), taxaLoaderClass );
12
- }
13
-
14
- async process( commandRunner ) {
15
- if ( this.helpShown() ) {
16
- return;
17
- }
18
- Files.rmDir( this.getOptions().outputdir );
19
-
20
- await this.#taxaProcessor.process( commandRunner );
21
- }
22
-
23
- }
24
-
25
- export { CommandAndTaxaProcessor };
@@ -1,108 +0,0 @@
1
- import commandLineArgs from "command-line-args";
2
- import commandLineUsage from "command-line-usage";
3
-
4
- const OPTION_DEFS = [
5
- { name: "datadir", type: String, defaultValue: "./data" },
6
- { name: "help", type: Boolean },
7
- { name: "outputdir", type: String, defaultValue: "./output" },
8
- { name: "show-flower-errors", type: Boolean },
9
- ];
10
-
11
- const OPTION_HELP = [
12
- {
13
- name: "datadir",
14
- type: String,
15
- typeLabel: "{underline path}",
16
- description: "The directory in which the data files for the local plant list are located. Defaults to {bold ./data}."
17
-
18
- },
19
- {
20
- name: "outputdir",
21
- type: String,
22
- typeLabel: "{underline path}",
23
- description: "The directory in which the output files should be written. Any files or subdirectories originally" +
24
- " in this directory will be deleted. Defaults to {bold ./output}."
25
-
26
- },
27
- {
28
- name: "show-flower-errors",
29
- type: Boolean,
30
- description: "Include flower color and flowering time errors in errors.tsv."
31
- },
32
- {
33
- name: "help",
34
- type: Boolean,
35
- description: "Print this usage guide."
36
- },
37
- ];
38
-
39
- class CommandProcessor {
40
-
41
- #commandName;
42
- #commandDesc;
43
-
44
- #optionHelp;
45
- #commandHelp;
46
-
47
- #options;
48
-
49
- #helpShown = false;
50
-
51
- /**
52
- * @param {String} commandName
53
- * @param {String} commandDesc
54
- * @param {*} optionDefs An array of command line options to be added to the standard options.
55
- * @param {*} optionHelp An array of help descriptions to be added to the standard options in the first section.
56
- * @param {*} commandHelp An array of help sections to be appended to the first option section in the help display.
57
- */
58
- constructor( commandName, commandDesc, optionDefs = [], optionHelp = [], commandHelp = [] ) {
59
-
60
- this.#commandName = commandName;
61
- this.#commandDesc = commandDesc;
62
-
63
- this.#optionHelp = optionHelp;
64
- this.#commandHelp = commandHelp;
65
-
66
- this.#options = commandLineArgs( OPTION_DEFS.concat( optionDefs ) );
67
-
68
- if ( this.#options.help ) {
69
- this.showHelp();
70
- }
71
-
72
- }
73
-
74
- getOptions() {
75
- return this.#options;
76
- }
77
-
78
- helpShown() {
79
- return this.#helpShown;
80
- }
81
-
82
- showHelp() {
83
-
84
- if ( this.#helpShown ) {
85
- return;
86
- }
87
-
88
- this.#helpShown = true;
89
-
90
- const mainOptions = OPTION_HELP.concat( this.#optionHelp );
91
- mainOptions.sort( ( a, b ) => a.name.localeCompare( b.name ) );
92
-
93
- const help = [
94
- {
95
- header: this.#commandName,
96
- content: this.#commandDesc
97
- },
98
- {
99
- header: "Options",
100
- optionList: mainOptions
101
- }
102
- ];
103
- console.log( commandLineUsage( help.concat( this.#commandHelp ) ) );
104
- }
105
-
106
- }
107
-
108
- export { CommandProcessor };
@@ -1,48 +0,0 @@
1
- import { ErrorLog } from "./index.js";
2
-
3
- class GenericTaxaLoader {
4
- #options;
5
- #errorLog;
6
- /** @type {import("./index.js").Taxa|undefined}*/
7
- #taxa;
8
-
9
- /**
10
- * @param {*} options
11
- */
12
- constructor(options) {
13
- this.#options = options;
14
- this.#errorLog = new ErrorLog(options.outputdir + "/errors.tsv");
15
- }
16
-
17
- /**
18
- * @returns {ErrorLog}
19
- */
20
- getErrorLog() {
21
- return this.#errorLog;
22
- }
23
-
24
- getOptions() {
25
- return this.#options;
26
- }
27
-
28
- getTaxa() {
29
- return this.#taxa;
30
- }
31
-
32
- async load() {
33
- this.#taxa = await this.loadTaxa();
34
- }
35
-
36
- /**
37
- * @return {Promise<import("./index.js").Taxa>}
38
- */
39
- async loadTaxa() {
40
- throw new Error("must be implemented by subclass");
41
- }
42
-
43
- writeErrorLog() {
44
- this.#errorLog.write();
45
- }
46
- }
47
-
48
- export { GenericTaxaLoader };
package/lib/taxaloader.js DELETED
@@ -1,48 +0,0 @@
1
- import { GenericTaxaLoader } from "./generictaxaloader.js";
2
- import { CSV, Files, Taxa } from "./index.js";
3
-
4
- class TaxaLoader extends GenericTaxaLoader {
5
- /**
6
- * @param {*} options
7
- */
8
- constructor(options) {
9
- super(options);
10
- }
11
-
12
- /**
13
- * @return {Promise<Taxa>}
14
- */
15
- async loadTaxa() {
16
- /**
17
- *
18
- * @param {string} dataDir
19
- * @returns
20
- */
21
- function getIncludeList(dataDir) {
22
- // Read inclusion list.
23
- const includeFileName = "taxa_include.csv";
24
- const includeFilePath = dataDir + "/" + includeFileName;
25
- if (!Files.exists(includeFilePath)) {
26
- console.log(includeFilePath + " not found; loading all taxa");
27
- return true;
28
- }
29
- /**@type { import("./index.js").TaxonData[]} */
30
- const includeCSV = CSV.parseFile(dataDir, includeFileName);
31
- /** @type {Object<string,import("./index.js").TaxonData>} */
32
- const include = {};
33
- for (const row of includeCSV) {
34
- include[row["taxon_name"]] = row;
35
- }
36
- return include;
37
- }
38
-
39
- const options = this.getOptions();
40
- return new Taxa(
41
- getIncludeList(options.datadir),
42
- this.getErrorLog(),
43
- options["show-flower-errors"]
44
- );
45
- }
46
- }
47
-
48
- export { TaxaLoader };
@@ -1,34 +0,0 @@
1
- import { TaxaLoader } from "./taxaloader.js";
2
-
3
- class TaxaProcessor {
4
- #options;
5
- #taxaLoaderClass;
6
- #taxaLoader;
7
-
8
- constructor(options, taxaLoaderClass = TaxaLoader) {
9
- this.#options = options;
10
- this.#taxaLoaderClass = taxaLoaderClass;
11
- }
12
-
13
- getErrorLog() {
14
- return this.#taxaLoader.getErrorLog();
15
- }
16
-
17
- getOptions() {
18
- return this.#options;
19
- }
20
-
21
- getTaxa() {
22
- return this.#taxaLoader.getTaxa();
23
- }
24
-
25
- async process(commandRunner) {
26
- console.log("loading data");
27
- this.#taxaLoader = new this.#taxaLoaderClass(this.#options);
28
- await this.#taxaLoader.load();
29
- await commandRunner(this);
30
- this.#taxaLoader.writeErrorLog();
31
- }
32
- }
33
-
34
- export { TaxaProcessor };