@ca-plant-list/ca-plant-list 0.2.16 → 0.2.17
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/glossary/peduncle.md +3 -1
- package/data/illustrations/inkscape/peduncle.svg +170 -0
- package/data/illustrations/optimized/peduncle.svg +21 -0
- package/jekyll/name_search.html +4 -4
- package/lib/commandandtaxaprocessor.js +37 -0
- package/lib/commandprocessor.js +108 -0
- package/lib/dataloader.js +12 -1
- package/lib/errorlog.js +14 -4
- package/lib/generictaxaloader.js +40 -0
- package/lib/index.d.ts +53 -16
- package/lib/index.js +3 -3
- package/lib/taxa.js +9 -6
- package/lib/taxaloader.js +35 -0
- package/lib/taxaprocessor.js +40 -0
- package/package.json +1 -1
- package/scripts/build-ebook.js +41 -44
- package/scripts/build-site.js +9 -33
- package/lib/commandrunner.js +0 -71
@@ -0,0 +1,170 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
2
|
+
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
3
|
+
|
4
|
+
<svg
|
5
|
+
width="102.55142"
|
6
|
+
height="60"
|
7
|
+
viewBox="0 0 102.55142 60"
|
8
|
+
version="1.1"
|
9
|
+
id="svg1"
|
10
|
+
inkscape:version="1.3 (0e150ed6c4, 2023-07-21)"
|
11
|
+
sodipodi:docname="peduncle.svg"
|
12
|
+
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
13
|
+
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
14
|
+
xmlns:xlink="http://www.w3.org/1999/xlink"
|
15
|
+
xmlns="http://www.w3.org/2000/svg"
|
16
|
+
xmlns:svg="http://www.w3.org/2000/svg">
|
17
|
+
<sodipodi:namedview
|
18
|
+
id="namedview1"
|
19
|
+
pagecolor="#ffffff"
|
20
|
+
bordercolor="#000000"
|
21
|
+
borderopacity="0.25"
|
22
|
+
inkscape:showpageshadow="2"
|
23
|
+
inkscape:pageopacity="0.0"
|
24
|
+
inkscape:pagecheckerboard="0"
|
25
|
+
inkscape:deskcolor="#d1d1d1"
|
26
|
+
inkscape:document-units="px"
|
27
|
+
showgrid="true"
|
28
|
+
inkscape:zoom="4"
|
29
|
+
inkscape:cx="50.625"
|
30
|
+
inkscape:cy="59.875"
|
31
|
+
inkscape:window-width="1920"
|
32
|
+
inkscape:window-height="991"
|
33
|
+
inkscape:window-x="-9"
|
34
|
+
inkscape:window-y="-9"
|
35
|
+
inkscape:window-maximized="1"
|
36
|
+
inkscape:current-layer="layer1">
|
37
|
+
<inkscape:grid
|
38
|
+
id="grid1"
|
39
|
+
units="px"
|
40
|
+
originx="0"
|
41
|
+
originy="0"
|
42
|
+
spacingx="1"
|
43
|
+
spacingy="1"
|
44
|
+
empcolor="#0099e5"
|
45
|
+
empopacity="0.30196078"
|
46
|
+
color="#0099e5"
|
47
|
+
opacity="0.14901961"
|
48
|
+
empspacing="5"
|
49
|
+
dotted="false"
|
50
|
+
gridanglex="30"
|
51
|
+
gridanglez="30"
|
52
|
+
visible="true" />
|
53
|
+
</sodipodi:namedview>
|
54
|
+
<defs
|
55
|
+
id="defs1">
|
56
|
+
<marker
|
57
|
+
style="overflow:visible"
|
58
|
+
id="Triangle"
|
59
|
+
refX="0"
|
60
|
+
refY="0"
|
61
|
+
orient="auto-start-reverse"
|
62
|
+
inkscape:stockid="Triangle arrow"
|
63
|
+
markerWidth="1"
|
64
|
+
markerHeight="1"
|
65
|
+
viewBox="0 0 1 1"
|
66
|
+
inkscape:isstock="true"
|
67
|
+
inkscape:collect="always"
|
68
|
+
preserveAspectRatio="xMidYMid">
|
69
|
+
<path
|
70
|
+
transform="scale(0.5)"
|
71
|
+
style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
|
72
|
+
d="M 5.77,0 -2.88,5 V -5 Z"
|
73
|
+
id="path135" />
|
74
|
+
</marker>
|
75
|
+
</defs>
|
76
|
+
<g
|
77
|
+
inkscape:label="Layer 1"
|
78
|
+
inkscape:groupmode="layer"
|
79
|
+
id="layer1">
|
80
|
+
<path
|
81
|
+
style="fill:#14140c;fill-opacity:1;stroke:#160707;stroke-width:1;stroke-dasharray:none;stroke-opacity:1"
|
82
|
+
d="M 15,60 V 15"
|
83
|
+
id="path2" />
|
84
|
+
<use
|
85
|
+
x="0"
|
86
|
+
y="0"
|
87
|
+
inkscape:tiled-clone-of="#path1"
|
88
|
+
xlink:href="#path1"
|
89
|
+
id="use1" />
|
90
|
+
<use
|
91
|
+
x="0"
|
92
|
+
y="0"
|
93
|
+
inkscape:tiled-clone-of="#path1"
|
94
|
+
xlink:href="#path1"
|
95
|
+
transform="rotate(30,15,15)"
|
96
|
+
id="use2" />
|
97
|
+
<use
|
98
|
+
x="0"
|
99
|
+
y="0"
|
100
|
+
inkscape:tiled-clone-of="#path1"
|
101
|
+
xlink:href="#path1"
|
102
|
+
transform="rotate(60,15,15)"
|
103
|
+
id="use3" />
|
104
|
+
<use
|
105
|
+
x="0"
|
106
|
+
y="0"
|
107
|
+
inkscape:tiled-clone-of="#path1"
|
108
|
+
xlink:href="#path1"
|
109
|
+
transform="rotate(90,15,15)"
|
110
|
+
id="use4" />
|
111
|
+
<use
|
112
|
+
x="0"
|
113
|
+
y="0"
|
114
|
+
inkscape:tiled-clone-of="#path1"
|
115
|
+
xlink:href="#path1"
|
116
|
+
transform="rotate(120,15,15)"
|
117
|
+
id="use5" />
|
118
|
+
<use
|
119
|
+
x="0"
|
120
|
+
y="0"
|
121
|
+
inkscape:tiled-clone-of="#path1"
|
122
|
+
xlink:href="#path1"
|
123
|
+
transform="rotate(150,15,15)"
|
124
|
+
id="use6" />
|
125
|
+
<ellipse
|
126
|
+
style="fill:#ffff00;stroke-width:0"
|
127
|
+
id="path1"
|
128
|
+
cx="15"
|
129
|
+
cy="15"
|
130
|
+
rx="2.5"
|
131
|
+
ry="15"
|
132
|
+
inkscape:tile-cx="15"
|
133
|
+
inkscape:tile-cy="15"
|
134
|
+
inkscape:tile-w="5"
|
135
|
+
inkscape:tile-h="30"
|
136
|
+
inkscape:tile-x0="12.5"
|
137
|
+
inkscape:tile-y0="0" />
|
138
|
+
<path
|
139
|
+
style="fill:#14140c;fill-opacity:1;stroke:#160707;stroke-width:0.5;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#Triangle)"
|
140
|
+
d="M 20,45 H 45"
|
141
|
+
id="path3" />
|
142
|
+
<text
|
143
|
+
xml:space="preserve"
|
144
|
+
style="font-size:8px;font-family:Arial;-inkscape-font-specification:Arial;letter-spacing:0.5px;opacity:0.558428;fill:#14140c;fill-opacity:1;stroke:#160707;stroke-width:0.1;stroke-dasharray:none;stroke-opacity:1"
|
145
|
+
x="50"
|
146
|
+
y="47.068359"
|
147
|
+
id="text3"><tspan
|
148
|
+
sodipodi:role="line"
|
149
|
+
id="tspan3"
|
150
|
+
x="50"
|
151
|
+
y="47.068359"
|
152
|
+
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:8px;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;letter-spacing:0.5px;stroke-width:0.1;stroke-dasharray:none">peduncle</tspan></text>
|
153
|
+
<path
|
154
|
+
style="fill:#14140c;fill-opacity:1;stroke:#160707;stroke-width:0.5;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#Triangle)"
|
155
|
+
d="M 35,15 H 45"
|
156
|
+
id="path4"
|
157
|
+
sodipodi:nodetypes="cc" />
|
158
|
+
<text
|
159
|
+
xml:space="preserve"
|
160
|
+
style="font-size:8px;font-family:Arial;-inkscape-font-specification:Arial;letter-spacing:0.5px;opacity:0.558428;fill:#14140c;fill-opacity:1;stroke:#160707;stroke-width:0.1;stroke-dasharray:none;stroke-opacity:1"
|
161
|
+
x="49.696735"
|
162
|
+
y="17.068359"
|
163
|
+
id="text4"><tspan
|
164
|
+
sodipodi:role="line"
|
165
|
+
id="tspan4"
|
166
|
+
x="49.696735"
|
167
|
+
y="17.068359"
|
168
|
+
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:8px;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;letter-spacing:0.5px;stroke-width:0.1;stroke-dasharray:none">inflorescence</tspan></text>
|
169
|
+
</g>
|
170
|
+
</svg>
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<svg version="1.1" viewBox="0 0 102.55 60" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
2
|
+
<defs>
|
3
|
+
<marker id="b" overflow="visible" markerHeight="1" markerWidth="1" orient="auto-start-reverse" preserveAspectRatio="xMidYMid" viewBox="0 0 1 1">
|
4
|
+
<path transform="scale(.5)" d="m5.77 0-8.65 5v-10z" fill="context-stroke" fill-rule="evenodd" stroke="context-stroke" stroke-width="1pt"/>
|
5
|
+
</marker>
|
6
|
+
</defs>
|
7
|
+
<path d="m15 60v-45" fill="#14140c" stroke="#160707"/>
|
8
|
+
<use xlink:href="#a"/>
|
9
|
+
<use transform="rotate(30,15,15)" xlink:href="#a"/>
|
10
|
+
<use transform="rotate(60,15,15)" xlink:href="#a"/>
|
11
|
+
<use transform="rotate(90,15,15)" xlink:href="#a"/>
|
12
|
+
<use transform="rotate(120,15,15)" xlink:href="#a"/>
|
13
|
+
<use transform="rotate(150,15,15)" xlink:href="#a"/>
|
14
|
+
<ellipse id="a" cx="15" cy="15" rx="2.5" ry="15" fill="#ff0" stroke-width="0"/>
|
15
|
+
<g fill="#14140c" stroke="#160707">
|
16
|
+
<path d="m20 45h25" marker-start="url(#b)" stroke-width=".5"/>
|
17
|
+
<text x="50" y="47.068359" font-family="Arial" font-size="8px" letter-spacing=".5px" opacity=".55843" stroke-width=".1" xml:space="preserve"><tspan x="50" y="47.068359" font-family="Arial" font-size="8px" letter-spacing=".5px" stroke-width=".1" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">peduncle</tspan></text>
|
18
|
+
<path d="m35 15h10" marker-start="url(#b)" stroke-width=".5"/>
|
19
|
+
<text x="49.696735" y="17.068359" font-family="Arial" font-size="8px" letter-spacing=".5px" opacity=".55843" stroke-width=".1" xml:space="preserve"><tspan x="49.696735" y="17.068359" font-family="Arial" font-size="8px" letter-spacing=".5px" stroke-width=".1" style="font-variant-caps:normal;font-variant-east-asian:normal;font-variant-ligatures:normal;font-variant-numeric:normal">inflorescence</tspan></text>
|
20
|
+
</g>
|
21
|
+
</svg>
|
package/jekyll/name_search.html
CHANGED
@@ -4,14 +4,14 @@ js: name_search.js
|
|
4
4
|
---
|
5
5
|
|
6
6
|
<script>
|
7
|
-
const NAMES = {% include names.json%};
|
7
|
+
const NAMES = {% include names.json %};
|
8
8
|
</script>
|
9
9
|
|
10
10
|
<form id="search_form">
|
11
|
-
<input type="text" id="name"
|
11
|
+
<input type="text" id="name">
|
12
|
+
<label for="name">Search for scientific name, common name, or synonym.</label>
|
12
13
|
</form>
|
13
14
|
|
14
15
|
<div class="section" id="message"></div>
|
15
16
|
|
16
|
-
<table id="results">
|
17
|
-
</table>
|
17
|
+
<table id="results"></table>
|
@@ -0,0 +1,37 @@
|
|
1
|
+
import { CommandProcessor } from "./commandprocessor.js";
|
2
|
+
import { TaxaProcessor } from "./taxaprocessor.js";
|
3
|
+
|
4
|
+
class GenericTaxaProcessor extends TaxaProcessor {
|
5
|
+
|
6
|
+
#fnCustomProcess;
|
7
|
+
|
8
|
+
constructor( fnCustomProcess, options, taxaLoaderClass ) {
|
9
|
+
super( options, taxaLoaderClass );
|
10
|
+
this.#fnCustomProcess = fnCustomProcess;
|
11
|
+
}
|
12
|
+
|
13
|
+
async customProcess() {
|
14
|
+
await this.#fnCustomProcess( this );
|
15
|
+
}
|
16
|
+
|
17
|
+
}
|
18
|
+
|
19
|
+
class CommandAndTaxaProcessor extends CommandProcessor {
|
20
|
+
|
21
|
+
#taxaProcessor;
|
22
|
+
|
23
|
+
constructor( commandName, commandDesc, fnCustomProcess, optionDefs = [], optionHelp = [], commandHelp = [], taxaLoaderClass ) {
|
24
|
+
super( commandName, commandDesc, optionDefs, optionHelp, commandHelp );
|
25
|
+
this.#taxaProcessor = new GenericTaxaProcessor( fnCustomProcess, this.getOptions(), taxaLoaderClass );
|
26
|
+
}
|
27
|
+
|
28
|
+
async process() {
|
29
|
+
if ( this.helpShown() ) {
|
30
|
+
return;
|
31
|
+
}
|
32
|
+
await this.#taxaProcessor.process();
|
33
|
+
}
|
34
|
+
|
35
|
+
}
|
36
|
+
|
37
|
+
export { CommandAndTaxaProcessor };
|
@@ -0,0 +1,108 @@
|
|
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 };
|
package/lib/dataloader.js
CHANGED
@@ -1,9 +1,16 @@
|
|
1
1
|
import { CSV } from "./csv.js";
|
2
2
|
import { Taxa } from "./taxa.js";
|
3
3
|
import { Files } from "./files.js";
|
4
|
+
import { ErrorLog } from "./errorlog.js";
|
4
5
|
|
5
6
|
class DataLoader {
|
6
7
|
|
8
|
+
static #errorLog = new ErrorLog();
|
9
|
+
|
10
|
+
static getErrorLog() {
|
11
|
+
return DataLoader.#errorLog;
|
12
|
+
}
|
13
|
+
|
7
14
|
static load( options ) {
|
8
15
|
|
9
16
|
function getIncludeList( dataDir ) {
|
@@ -26,8 +33,12 @@ class DataLoader {
|
|
26
33
|
|
27
34
|
console.log( "loading data" );
|
28
35
|
|
29
|
-
return new Taxa( getIncludeList( options.datadir ), showFlowerErrors );
|
36
|
+
return new Taxa( getIncludeList( options.datadir ), this.getErrorLog(), showFlowerErrors );
|
37
|
+
|
38
|
+
}
|
30
39
|
|
40
|
+
static writeErrorLog() {
|
41
|
+
DataLoader.#errorLog.write();
|
31
42
|
}
|
32
43
|
|
33
44
|
}
|
package/lib/errorlog.js
CHANGED
@@ -2,14 +2,24 @@ import * as fs from "node:fs";
|
|
2
2
|
|
3
3
|
class ErrorLog {
|
4
4
|
|
5
|
-
|
5
|
+
#fileName;
|
6
|
+
#echo;
|
7
|
+
#errors = [];
|
6
8
|
|
7
|
-
|
9
|
+
constructor( fileName, echo = false ) {
|
10
|
+
this.#fileName = fileName;
|
11
|
+
this.#echo = echo;
|
12
|
+
}
|
13
|
+
|
14
|
+
log( ...args ) {
|
15
|
+
if ( this.#echo ) {
|
16
|
+
console.log( args.join() );
|
17
|
+
}
|
8
18
|
this.#errors.push( args.join( "\t" ) );
|
9
19
|
}
|
10
20
|
|
11
|
-
|
12
|
-
fs.writeFileSync( fileName, this.#errors.join( "\n" ) );
|
21
|
+
write() {
|
22
|
+
fs.writeFileSync( this.#fileName, this.#errors.join( "\n" ) );
|
13
23
|
}
|
14
24
|
|
15
25
|
}
|
@@ -0,0 +1,40 @@
|
|
1
|
+
import { ErrorLog } from "./errorlog.js";
|
2
|
+
|
3
|
+
class GenericTaxaLoader {
|
4
|
+
|
5
|
+
#options;
|
6
|
+
#errorLog;
|
7
|
+
#taxa;
|
8
|
+
|
9
|
+
constructor( options ) {
|
10
|
+
this.#options = options;
|
11
|
+
this.#errorLog = new ErrorLog( options.outputdir + "/errors.tsv" );
|
12
|
+
}
|
13
|
+
|
14
|
+
getErrorLog() {
|
15
|
+
return this.#errorLog;
|
16
|
+
}
|
17
|
+
|
18
|
+
getOptions() {
|
19
|
+
return this.#options;
|
20
|
+
}
|
21
|
+
|
22
|
+
getTaxa() {
|
23
|
+
return this.#taxa;
|
24
|
+
}
|
25
|
+
|
26
|
+
async load() {
|
27
|
+
this.#taxa = await this.loadTaxa();
|
28
|
+
}
|
29
|
+
|
30
|
+
async loadTaxa() {
|
31
|
+
throw new Error( "must be implemented by subclass" );
|
32
|
+
}
|
33
|
+
|
34
|
+
writeErrorLog() {
|
35
|
+
this.#errorLog.write();
|
36
|
+
}
|
37
|
+
|
38
|
+
}
|
39
|
+
|
40
|
+
export { GenericTaxaLoader };
|
package/lib/index.d.ts
CHANGED
@@ -2,9 +2,23 @@ export class BasePageRenderer {
|
|
2
2
|
static render(outputDir: any, taxa: any, familyCols: any): void;
|
3
3
|
static renderTools(outputDir: any, taxa: any): void;
|
4
4
|
}
|
5
|
-
export class
|
6
|
-
constructor(commandName: any, commandDesc: any, optionDefs: any, optionHelp: any,
|
7
|
-
|
5
|
+
export class CommandAndTaxaProcessor extends CommandProcessor {
|
6
|
+
constructor(commandName: any, commandDesc: any, fnCustomProcess: any, optionDefs: any[], optionHelp: any[], commandHelp: any[], taxaLoaderClass: any);
|
7
|
+
process(): Promise<void>;
|
8
|
+
#private;
|
9
|
+
}
|
10
|
+
import { CommandProcessor } from "./commandprocessor.js";
|
11
|
+
export class CommandProcessor {
|
12
|
+
/**
|
13
|
+
* @param {String} commandName
|
14
|
+
* @param {String} commandDesc
|
15
|
+
* @param {*} optionDefs An array of command line options to be added to the standard options.
|
16
|
+
* @param {*} optionHelp An array of help descriptions to be added to the standard options in the first section.
|
17
|
+
* @param {*} commandHelp An array of help sections to be appended to the first option section in the help display.
|
18
|
+
*/
|
19
|
+
constructor(commandName: string, commandDesc: string, optionDefs?: any, optionHelp?: any, commandHelp?: any);
|
20
|
+
getOptions(): any;
|
21
|
+
helpShown(): boolean;
|
8
22
|
showHelp(): void;
|
9
23
|
#private;
|
10
24
|
}
|
@@ -19,24 +33,21 @@ export class Config {
|
|
19
33
|
}
|
20
34
|
export class CSV {
|
21
35
|
static getMap(dir: any, fileName: any): {};
|
22
|
-
static "__#
|
36
|
+
static "__#8@#getOptions"(fileName: any, columns: any, delimiter: any): {
|
23
37
|
relax_column_count_less: boolean;
|
24
38
|
};
|
25
39
|
static parseFile(dir: any, fileName: any, columns: boolean, delimiter: any): any;
|
26
40
|
static parseStream(dir: any, fileName: any, columns: boolean, delimiter: any, callback: any): Promise<void>;
|
27
41
|
}
|
28
|
-
export class DataLoader {
|
29
|
-
static load(options: any): Taxa;
|
30
|
-
}
|
31
|
-
import { Taxa } from "./taxa.js";
|
32
42
|
export class DateUtils {
|
33
43
|
static getMonthName(monthNum: any): string;
|
34
44
|
static monthRangesOverlap(r1: any, r2: any): any;
|
35
45
|
}
|
36
46
|
export class ErrorLog {
|
37
|
-
|
38
|
-
|
39
|
-
|
47
|
+
constructor(fileName: any, echo?: boolean);
|
48
|
+
log(...args: any[]): void;
|
49
|
+
write(): void;
|
50
|
+
#private;
|
40
51
|
}
|
41
52
|
export class Exceptions {
|
42
53
|
constructor(dir: any);
|
@@ -46,7 +57,7 @@ export class Exceptions {
|
|
46
57
|
#private;
|
47
58
|
}
|
48
59
|
export class Families {
|
49
|
-
static "__#
|
60
|
+
static "__#12@#families": any;
|
50
61
|
static getFamilies(): any[];
|
51
62
|
static getFamily(familyName: any): any;
|
52
63
|
static renderPages(outputDir: any, taxaColumns: any): void;
|
@@ -94,6 +105,17 @@ export class GenericPage {
|
|
94
105
|
writeFile(html: any): void;
|
95
106
|
#private;
|
96
107
|
}
|
108
|
+
export class GenericTaxaLoader {
|
109
|
+
constructor(options: any);
|
110
|
+
getErrorLog(): ErrorLog;
|
111
|
+
getOptions(): any;
|
112
|
+
getTaxa(): any;
|
113
|
+
load(): Promise<void>;
|
114
|
+
loadTaxa(): Promise<void>;
|
115
|
+
writeErrorLog(): void;
|
116
|
+
#private;
|
117
|
+
}
|
118
|
+
import { ErrorLog } from "./errorlog.js";
|
97
119
|
export namespace HTML_OPTIONS {
|
98
120
|
const OPEN_NEW: number;
|
99
121
|
const NO_ESCAPE: number;
|
@@ -134,21 +156,21 @@ export class HTML {
|
|
134
156
|
static wrap(elName: any, text: any, attributes?: {}): string;
|
135
157
|
}
|
136
158
|
import { BasePageRenderer } from "./basepagerenderer.js";
|
137
|
-
import {
|
159
|
+
import { CommandAndTaxaProcessor } from "./commandandtaxaprocessor.js";
|
138
160
|
import { Config } from "./config.js";
|
139
161
|
import { CSV } from "./csv.js";
|
140
|
-
import { DataLoader } from "./dataloader.js";
|
141
162
|
import { ErrorLog } from "./errorlog.js";
|
142
163
|
import { Exceptions } from "./exceptions.js";
|
143
164
|
import { Families } from "./families.js";
|
144
165
|
import { Files } from "./files.js";
|
166
|
+
import { GenericTaxaLoader } from "./generictaxaloader.js";
|
145
167
|
import { HTML } from "./html.js";
|
146
168
|
import { Jekyll } from "./jekyll.js";
|
147
169
|
import { PlantBook } from "./ebook/plantbook.js";
|
148
170
|
import { Taxa } from "./taxa.js";
|
149
171
|
import { TAXA_COLNAMES } from "./taxon.js";
|
150
172
|
import { Taxon } from "./taxon.js";
|
151
|
-
export { BasePageRenderer,
|
173
|
+
export { BasePageRenderer, CommandAndTaxaProcessor, Config, CSV, ErrorLog, Exceptions, Families, Files, GenericTaxaLoader, HTML, Jekyll, PlantBook, Taxa, TAXA_COLNAMES, Taxon };
|
152
174
|
export class Jekyll {
|
153
175
|
static getFrontMatter(atts: any): string;
|
154
176
|
static hasInclude(baseDir: any, path: any): boolean;
|
@@ -175,7 +197,7 @@ export class Taxa {
|
|
175
197
|
title: string;
|
176
198
|
data: (t: any) => any;
|
177
199
|
}[]): string;
|
178
|
-
constructor(inclusionList: any, showFlowerErrors: any, taxaMeta?: {}, taxonClass?: typeof Taxon, extraTaxa?: any[], extraSynonyms?: any[]);
|
200
|
+
constructor(inclusionList: any, errorLog: any, showFlowerErrors: any, taxaMeta?: {}, taxonClass?: typeof Taxon, extraTaxa?: any[], extraSynonyms?: any[]);
|
179
201
|
getFlowerColor(name: any): any;
|
180
202
|
getTaxon(name: any): any;
|
181
203
|
getTaxonList(): any[];
|
@@ -218,6 +240,21 @@ export namespace TAXA_LIST_COLS {
|
|
218
240
|
}
|
219
241
|
}
|
220
242
|
import { Taxon } from "./taxon.js";
|
243
|
+
export class TaxaLoader extends GenericTaxaLoader {
|
244
|
+
loadTaxa(): Promise<Taxa>;
|
245
|
+
}
|
246
|
+
import { GenericTaxaLoader } from "./generictaxaloader.js";
|
247
|
+
import { Taxa } from "./taxa.js";
|
248
|
+
export class TaxaProcessor {
|
249
|
+
constructor(options: any, taxaLoaderClass?: typeof TaxaLoader);
|
250
|
+
customProcess(): Promise<void>;
|
251
|
+
getErrorLog(): any;
|
252
|
+
getOptions(): any;
|
253
|
+
getTaxa(): any;
|
254
|
+
process(): Promise<void>;
|
255
|
+
#private;
|
256
|
+
}
|
257
|
+
import { TaxaLoader } from "./taxaloader.js";
|
221
258
|
export namespace TAXA_COLNAMES {
|
222
259
|
const BLOOM_START: string;
|
223
260
|
const BLOOM_END: string;
|
package/lib/index.js
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
import { BasePageRenderer } from "./basepagerenderer.js";
|
2
|
-
import {
|
2
|
+
import { CommandAndTaxaProcessor } from "./commandandtaxaprocessor.js";
|
3
3
|
import { Config } from "./config.js";
|
4
4
|
import { CSV } from "./csv.js";
|
5
|
-
import { DataLoader } from "./dataloader.js";
|
6
5
|
import { ErrorLog } from "./errorlog.js";
|
7
6
|
import { Exceptions } from "./exceptions.js";
|
8
7
|
import { Families } from "./families.js";
|
9
8
|
import { Files } from "./files.js";
|
9
|
+
import { GenericTaxaLoader } from "./generictaxaloader.js";
|
10
10
|
import { HTML } from "./html.js";
|
11
11
|
import { Jekyll } from "./jekyll.js";
|
12
12
|
import { PlantBook } from "./ebook/plantbook.js";
|
13
13
|
import { Taxa } from "./taxa.js";
|
14
14
|
import { Taxon, TAXA_COLNAMES } from "./taxon.js";
|
15
15
|
|
16
|
-
export { BasePageRenderer,
|
16
|
+
export { BasePageRenderer, CommandAndTaxaProcessor, Config, CSV, ErrorLog, Exceptions, Families, Files, GenericTaxaLoader, HTML, Jekyll, PlantBook, Taxa, TAXA_COLNAMES, Taxon };
|
package/lib/taxa.js
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
import { Config } from "./config.js";
|
2
2
|
import { Taxon } from "./taxon.js";
|
3
|
-
import { ErrorLog } from "./errorlog.js";
|
4
3
|
import { HTML } from "./html.js";
|
5
4
|
import { CSV } from "./csv.js";
|
6
5
|
import { RarePlants } from "./rareplants.js";
|
@@ -65,11 +64,15 @@ class FlowerColor {
|
|
65
64
|
|
66
65
|
class Taxa {
|
67
66
|
|
67
|
+
#errorLog;
|
68
68
|
#taxa = {};
|
69
69
|
#flower_colors = {};
|
70
70
|
#sortedTaxa;
|
71
71
|
|
72
|
-
constructor( inclusionList, showFlowerErrors, taxaMeta = {}, taxonClass = Taxon, extraTaxa = [], extraSynonyms = [] ) {
|
72
|
+
constructor( inclusionList, errorLog, showFlowerErrors, taxaMeta = {}, taxonClass = Taxon, extraTaxa = [], extraSynonyms = [] ) {
|
73
|
+
|
74
|
+
this.#errorLog = errorLog;
|
75
|
+
|
73
76
|
for ( const color of FLOWER_COLOR_NAMES ) {
|
74
77
|
this.#flower_colors[ color ] = new FlowerColor( color );
|
75
78
|
}
|
@@ -83,7 +86,7 @@ class Taxa {
|
|
83
86
|
// Make sure everything in the inclusionList has been loaded.
|
84
87
|
for ( const name of Object.keys( inclusionList ) ) {
|
85
88
|
if ( !this.getTaxon( name ) ) {
|
86
|
-
|
89
|
+
this.#errorLog.log( name, "not found in taxon list" );
|
87
90
|
}
|
88
91
|
}
|
89
92
|
|
@@ -164,7 +167,7 @@ class Taxa {
|
|
164
167
|
}
|
165
168
|
|
166
169
|
if ( this.#taxa[ name ] ) {
|
167
|
-
|
170
|
+
this.#errorLog.log( name, "has multiple entries" );
|
168
171
|
}
|
169
172
|
|
170
173
|
const status = taxon_overrides[ "status" ];
|
@@ -188,11 +191,11 @@ class Taxa {
|
|
188
191
|
// Make sure flower colors/bloom times are present or not depending on taxon.
|
189
192
|
if ( taxon.shouldHaveFlowers() ) {
|
190
193
|
if ( !colors || !taxon.getBloomStart() || !taxon.getBloomEnd() ) {
|
191
|
-
|
194
|
+
this.#errorLog.log( name, "does not have all flower info" );
|
192
195
|
}
|
193
196
|
} else {
|
194
197
|
if ( colors || taxon.getBloomStart() || taxon.getBloomEnd() ) {
|
195
|
-
|
198
|
+
this.#errorLog.log( name, "should not have flower info" );
|
196
199
|
}
|
197
200
|
}
|
198
201
|
}
|
@@ -0,0 +1,35 @@
|
|
1
|
+
import { CSV } from "./csv.js";
|
2
|
+
import { Files } from "./files.js";
|
3
|
+
import { GenericTaxaLoader } from "./generictaxaloader.js";
|
4
|
+
import { Taxa } from "./taxa.js";
|
5
|
+
|
6
|
+
class TaxaLoader extends GenericTaxaLoader {
|
7
|
+
|
8
|
+
constructor( options ) {
|
9
|
+
super( options );
|
10
|
+
}
|
11
|
+
|
12
|
+
async loadTaxa() {
|
13
|
+
function getIncludeList( dataDir ) {
|
14
|
+
// Read inclusion list.
|
15
|
+
const includeFileName = "taxa_include.csv";
|
16
|
+
const includeFilePath = dataDir + "/" + includeFileName;
|
17
|
+
if ( !Files.exists( includeFilePath ) ) {
|
18
|
+
console.log( includeFilePath + " not found; loading all taxa" );
|
19
|
+
return true;
|
20
|
+
}
|
21
|
+
const includeCSV = CSV.parseFile( dataDir, includeFileName );
|
22
|
+
const include = {};
|
23
|
+
for ( const row of includeCSV ) {
|
24
|
+
include[ row[ "taxon_name" ] ] = row;
|
25
|
+
}
|
26
|
+
return include;
|
27
|
+
}
|
28
|
+
|
29
|
+
const options = this.getOptions();
|
30
|
+
return new Taxa( getIncludeList( options.datadir ), this.getErrorLog(), options[ "show-flower-errors" ] );
|
31
|
+
}
|
32
|
+
|
33
|
+
}
|
34
|
+
|
35
|
+
export { TaxaLoader };
|
@@ -0,0 +1,40 @@
|
|
1
|
+
import { TaxaLoader } from "./taxaloader.js";
|
2
|
+
|
3
|
+
class TaxaProcessor {
|
4
|
+
|
5
|
+
#options;
|
6
|
+
#taxaLoaderClass;
|
7
|
+
#taxaLoader;
|
8
|
+
|
9
|
+
constructor( options, taxaLoaderClass = TaxaLoader ) {
|
10
|
+
this.#options = options;
|
11
|
+
this.#taxaLoaderClass = taxaLoaderClass;
|
12
|
+
}
|
13
|
+
|
14
|
+
async customProcess() {
|
15
|
+
throw new Error( "must be implemented by subclass" );
|
16
|
+
}
|
17
|
+
|
18
|
+
getErrorLog() {
|
19
|
+
return this.#taxaLoader.getErrorLog();
|
20
|
+
}
|
21
|
+
|
22
|
+
getOptions() {
|
23
|
+
return this.#options;
|
24
|
+
}
|
25
|
+
|
26
|
+
getTaxa() {
|
27
|
+
return this.#taxaLoader.getTaxa();
|
28
|
+
}
|
29
|
+
|
30
|
+
async process() {
|
31
|
+
console.log( "loading data" );
|
32
|
+
this.#taxaLoader = new this.#taxaLoaderClass( this.#options );
|
33
|
+
await this.#taxaLoader.load();
|
34
|
+
await this.customProcess();
|
35
|
+
this.#taxaLoader.writeErrorLog();
|
36
|
+
}
|
37
|
+
|
38
|
+
}
|
39
|
+
|
40
|
+
export { TaxaProcessor };
|
package/package.json
CHANGED
package/scripts/build-ebook.js
CHANGED
@@ -1,76 +1,73 @@
|
|
1
1
|
#!/usr/bin/env node
|
2
2
|
|
3
|
-
import {
|
4
|
-
import { DataLoader } from "../lib/dataloader.js";
|
3
|
+
import { PlantBook } from "@ca-plant-list/ca-plant-list";
|
5
4
|
import { Config } from "../lib/config.js";
|
6
5
|
import { Files } from "../lib/files.js";
|
7
|
-
import {
|
8
|
-
|
9
|
-
const OUTPUT_DIR = "./output";
|
10
|
-
const LOC_DIR = "./locations";
|
6
|
+
import { TaxaProcessor } from "../lib/taxaprocessor.js";
|
7
|
+
import { CommandProcessor } from "../lib/commandprocessor.js";
|
11
8
|
|
12
9
|
const OPTION_DEFS = [
|
13
|
-
{ name: "
|
10
|
+
{ name: "locationsdir", type: String },
|
14
11
|
];
|
15
12
|
|
16
13
|
const OPTION_HELP = [
|
17
14
|
{
|
18
|
-
name: "
|
15
|
+
name: "locationsdir",
|
19
16
|
type: String,
|
20
17
|
typeLabel: "{underline path}",
|
21
|
-
description: "
|
22
|
-
+ "
|
23
|
-
+ "
|
24
|
-
+ "- otherwise {bold ./data} will be used as the {bold datadir}"
|
18
|
+
description: "If this option is specified, multiple ebooks will be generated. {bold locationsdir} must be a subdirectory"
|
19
|
+
+ " of the current directory, and each subdirectory of {bold locationsdir} is processed in turn to generate an ebook."
|
20
|
+
+ " Each ebook is placed in a subdirectory of {bold outputdir}."
|
25
21
|
},
|
26
22
|
];
|
27
23
|
|
28
|
-
|
29
|
-
"ca-plant-book",
|
30
|
-
"A tool to generate an ebook with local plant data.",
|
31
|
-
OPTION_DEFS,
|
32
|
-
OPTION_HELP,
|
33
|
-
undefined,
|
34
|
-
generateEBooks,
|
35
|
-
);
|
36
|
-
await cr.processCommandLine();
|
24
|
+
class BookCommand extends CommandProcessor {
|
37
25
|
|
38
|
-
|
26
|
+
constructor() {
|
27
|
+
super( "ca-plant-book", "A tool to generate an ebook with local plant data.", OPTION_DEFS, OPTION_HELP );
|
28
|
+
}
|
39
29
|
|
40
|
-
|
30
|
+
}
|
41
31
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
32
|
+
class BookGenerator extends TaxaProcessor {
|
33
|
+
|
34
|
+
async customProcess() {
|
35
|
+
const options = this.getOptions();
|
36
|
+
const ebook = new PlantBook( options.outputdir, new Config( options.datadir ), this.getTaxa() );
|
37
|
+
await ebook.create();
|
46
38
|
}
|
47
39
|
|
40
|
+
}
|
41
|
+
|
42
|
+
async function generateEBooks( options ) {
|
43
|
+
const locationsDir = options.locationsdir;
|
44
|
+
|
48
45
|
// If there is a "locations" directory, generate a book for all subdirectories.
|
49
|
-
|
50
|
-
if ( hasLocations ) {
|
46
|
+
if ( locationsDir ) {
|
51
47
|
// Generate ebook for each location.
|
52
|
-
const
|
48
|
+
const outputBase = options.outputdir;
|
49
|
+
const subdirs = Files.getDirEntries( locationsDir );
|
53
50
|
for ( const subdir of subdirs ) {
|
51
|
+
console.log( "Generating " + subdir );
|
54
52
|
const suffix = "/" + subdir;
|
55
|
-
const path =
|
53
|
+
const path = locationsDir + suffix;
|
56
54
|
if ( Files.isDir( path ) ) {
|
57
55
|
options.datadir = path;
|
58
|
-
|
56
|
+
options.outputdir = outputBase + suffix;
|
57
|
+
const gen = new BookGenerator( options );
|
58
|
+
await gen.process( options );
|
59
59
|
}
|
60
60
|
}
|
61
|
-
|
61
|
+
} else {
|
62
|
+
// Otherwise use the default directory.
|
63
|
+
const gen = new BookGenerator( options );
|
64
|
+
await gen.process( options );
|
62
65
|
}
|
63
66
|
|
64
|
-
// Otherwise use the default directory.
|
65
|
-
options.datadir = "./data";
|
66
|
-
await generateEBook( options );
|
67
|
-
|
68
|
-
ErrorLog.write( OUTPUT_DIR + "/errors.tsv" );
|
69
|
-
|
70
|
-
}
|
71
|
-
|
72
|
-
async function generateEBook( options, outputSuffix = "" ) {
|
73
|
-
const ebook = new PlantBook( OUTPUT_DIR + outputSuffix, new Config( options.datadir ), DataLoader.load( options ) );
|
74
|
-
await ebook.create();
|
75
67
|
}
|
76
68
|
|
69
|
+
const cmd = new BookCommand();
|
70
|
+
const options = cmd.getOptions();
|
71
|
+
if ( !options.help ) {
|
72
|
+
generateEBooks( options );
|
73
|
+
}
|
package/scripts/build-site.js
CHANGED
@@ -4,26 +4,8 @@ import * as child_process from "node:child_process";
|
|
4
4
|
import * as path from "node:path";
|
5
5
|
import { Files } from "@ca-plant-list/ca-plant-list";
|
6
6
|
import { Config } from "../lib/config.js";
|
7
|
-
import { DataLoader } from "../lib/dataloader.js";
|
8
7
|
import { PageRenderer } from "../lib/pagerenderer.js";
|
9
|
-
import {
|
10
|
-
import { ErrorLog } from "../lib/errorlog.js";
|
11
|
-
|
12
|
-
const OUTPUT_DIR = "./output";
|
13
|
-
|
14
|
-
const OPTION_DEFS = [
|
15
|
-
{ name: "datadir", type: String, defaultValue: "./data" },
|
16
|
-
];
|
17
|
-
|
18
|
-
const OPTION_HELP = [
|
19
|
-
{
|
20
|
-
name: "datadir",
|
21
|
-
type: String,
|
22
|
-
typeLabel: "{underline path}",
|
23
|
-
description: "The directory in which the data files for the local plant list are located. Defaults to {bold ./data}."
|
24
|
-
|
25
|
-
},
|
26
|
-
];
|
8
|
+
import { CommandAndTaxaProcessor } from "../lib/commandandtaxaprocessor.js";
|
27
9
|
|
28
10
|
class JekyllRenderer {
|
29
11
|
|
@@ -57,23 +39,17 @@ class JekyllRenderer {
|
|
57
39
|
|
58
40
|
}
|
59
41
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
undefined,
|
66
|
-
generateSite,
|
67
|
-
);
|
68
|
-
await cr.processCommandLine();
|
69
|
-
|
70
|
-
async function generateSite( options ) {
|
71
|
-
const dataDir = options.datadir;
|
72
|
-
PageRenderer.render( OUTPUT_DIR, new Config( dataDir ), DataLoader.load( options ) );
|
73
|
-
ErrorLog.write( OUTPUT_DIR + "/errors.tsv" );
|
42
|
+
async function generateSite( taxaProcessor ) {
|
43
|
+
|
44
|
+
const options = taxaProcessor.getOptions();
|
45
|
+
|
46
|
+
PageRenderer.render( options.outputdir, new Config( options.datadir ), taxaProcessor.getTaxa() );
|
74
47
|
|
75
48
|
console.log( "generating site" );
|
76
49
|
const r = new JekyllRenderer();
|
77
50
|
await r.renderPages();
|
51
|
+
|
78
52
|
}
|
79
53
|
|
54
|
+
const gen = new CommandAndTaxaProcessor( "ca-plant-list", "A tool to generate a website with local plant data.", generateSite );
|
55
|
+
await gen.process();
|
package/lib/commandrunner.js
DELETED
@@ -1,71 +0,0 @@
|
|
1
|
-
import commandLineArgs from "command-line-args";
|
2
|
-
import commandLineUsage from "command-line-usage";
|
3
|
-
|
4
|
-
const OPTION_DEFS = [
|
5
|
-
{ name: "help", type: Boolean },
|
6
|
-
{ name: "show-flower-errors", type: Boolean },
|
7
|
-
];
|
8
|
-
|
9
|
-
const OPTION_HELP = [
|
10
|
-
{
|
11
|
-
name: "help",
|
12
|
-
type: Boolean,
|
13
|
-
description: "Print this usage guide."
|
14
|
-
},
|
15
|
-
{
|
16
|
-
name: "show-flower-errors",
|
17
|
-
type: Boolean,
|
18
|
-
description: "Include flower color and flowering time errors in errors.tsv."
|
19
|
-
},
|
20
|
-
];
|
21
|
-
|
22
|
-
class CommandRunner {
|
23
|
-
|
24
|
-
#commandName;
|
25
|
-
#commandDesc;
|
26
|
-
#optionDefs;
|
27
|
-
#optionHelp;
|
28
|
-
#additionalHelp;
|
29
|
-
#commandFunc;
|
30
|
-
|
31
|
-
constructor( commandName, commandDesc, optionDefs, optionHelp, additionalHelp = [], commandFunc ) {
|
32
|
-
this.#commandName = commandName;
|
33
|
-
this.#commandDesc = commandDesc;
|
34
|
-
this.#optionDefs = optionDefs;
|
35
|
-
this.#optionHelp = optionHelp;
|
36
|
-
this.#additionalHelp = additionalHelp;
|
37
|
-
this.#commandFunc = commandFunc;
|
38
|
-
}
|
39
|
-
|
40
|
-
async processCommandLine() {
|
41
|
-
|
42
|
-
const options = commandLineArgs( this.#optionDefs.concat( OPTION_DEFS ) );
|
43
|
-
|
44
|
-
if ( options.help ) {
|
45
|
-
this.showHelp();
|
46
|
-
return;
|
47
|
-
}
|
48
|
-
|
49
|
-
console.log( "Use --help to see all options" );
|
50
|
-
await this.#commandFunc( options );
|
51
|
-
|
52
|
-
}
|
53
|
-
|
54
|
-
showHelp() {
|
55
|
-
const help = [
|
56
|
-
{
|
57
|
-
header: this.#commandName,
|
58
|
-
content: this.#commandDesc
|
59
|
-
},
|
60
|
-
{
|
61
|
-
header: "Options",
|
62
|
-
optionList: OPTION_HELP
|
63
|
-
}
|
64
|
-
];
|
65
|
-
help[ 1 ].optionList = help[ 1 ].optionList.concat( this.#optionHelp );
|
66
|
-
console.log( commandLineUsage( help.concat( this.#additionalHelp ) ) );
|
67
|
-
}
|
68
|
-
|
69
|
-
}
|
70
|
-
|
71
|
-
export { CommandRunner };
|