@ca-plant-list/ca-plant-list 0.3.7 → 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 (69) hide show
  1. package/.vscode/settings.json +7 -1
  2. package/data/synonyms.csv +85 -2
  3. package/data/taxa.csv +38 -16
  4. package/data/text/Antennaria-media.md +1 -0
  5. package/data/text/Antennaria-rosea-subsp-rosea.md +1 -0
  6. package/data/text/Camassia-leichtlinii-subsp-suksdorfii.md +1 -0
  7. package/data/text/Camassia-quamash-subsp-breviflora.md +1 -0
  8. package/data/text/Delphinium-glaucum.md +1 -0
  9. package/data/text/Delphinium-nuttallianum.md +1 -0
  10. package/data/text/Drymocallis-glandulosa-var-glandulosa.md +1 -0
  11. package/data/text/Drymocallis-lactea-var-austiniae.md +1 -0
  12. package/data/text/Erigeron-compositus.md +1 -0
  13. package/data/text/Erigeron-glacialis-var-glacialis.md +1 -0
  14. package/data/text/Erythranthe-breweri.md +1 -0
  15. package/data/text/Erythranthe-erubescens.md +1 -0
  16. package/data/text/Navarretia-leptalea-subsp-bicolor.md +1 -0
  17. package/data/text/Navarretia-leptalea-subsp-leptalea.md +1 -0
  18. package/data/text/Polemonium-californicum.md +1 -0
  19. package/data/text/Polemonium-pulcherrimum-var-pulcherrimum.md +1 -0
  20. package/data/text/Primula-jeffreyi.md +1 -0
  21. package/data/text/Primula-tetrandra.md +1 -0
  22. package/lib/basepagerenderer.js +3 -4
  23. package/lib/config.js +42 -19
  24. package/lib/csv.js +54 -36
  25. package/lib/ebook/ebook.js +84 -57
  26. package/lib/ebook/ebookpage.js +22 -11
  27. package/lib/ebook/ebooksitegenerator.js +36 -14
  28. package/lib/ebook/glossarypages.js +20 -17
  29. package/lib/ebook/images.js +13 -5
  30. package/lib/ebook/pages/page_list_families.js +0 -2
  31. package/lib/ebook/pages/page_list_flower_color.js +14 -9
  32. package/lib/ebook/pages/page_list_flowers.js +59 -41
  33. package/lib/ebook/pages/taxonpage.js +1 -1
  34. package/lib/ebook/pages/tocpage.js +26 -20
  35. package/lib/ebook/plantbook.js +6 -13
  36. package/lib/ebook/{image.js → taxonimage.js} +2 -2
  37. package/lib/exceptions.js +42 -26
  38. package/lib/externalsites.js +11 -4
  39. package/lib/families.js +10 -8
  40. package/lib/flowercolor.js +42 -0
  41. package/lib/genera.js +13 -21
  42. package/lib/genericpage.js +12 -0
  43. package/lib/html.js +11 -23
  44. package/lib/htmltaxon.js +89 -6
  45. package/lib/index.d.ts +54 -0
  46. package/lib/index.js +2 -30
  47. package/lib/jekyll.js +49 -21
  48. package/lib/jepson.js +7 -8
  49. package/lib/markdown.js +6 -0
  50. package/lib/pagerenderer.js +43 -8
  51. package/lib/plants/glossary.js +5 -0
  52. package/lib/program.js +47 -0
  53. package/lib/rareplants.js +44 -30
  54. package/lib/sitegenerator.js +41 -24
  55. package/lib/taxa.js +20 -134
  56. package/lib/taxon.js +1 -1
  57. package/lib/web/glossarypages.js +6 -0
  58. package/lib/web/pagetaxon.js +1 -5
  59. package/package.json +6 -3
  60. package/schemas/exceptions.schema.json +57 -0
  61. package/scripts/build-ebook.js +38 -47
  62. package/scripts/build-site.js +25 -14
  63. package/types/classes.d.ts +136 -8
  64. package/lib/commandandtaxaprocessor.js +0 -25
  65. package/lib/commandprocessor.js +0 -108
  66. package/lib/generictaxaloader.js +0 -48
  67. package/lib/taxaloader.js +0 -50
  68. package/lib/taxaprocessor.js +0 -34
  69. /package/data/text/{Calyptridium-ubellatum.md → Calyptridium-umbellatum.md} +0 -0
package/lib/config.js CHANGED
@@ -3,46 +3,69 @@ import * as url from "node:url";
3
3
  import { Files } from "./files.js";
4
4
 
5
5
  class Config {
6
+ static #packageDir = path.dirname(
7
+ path.dirname(url.fileURLToPath(import.meta.url))
8
+ );
6
9
 
7
- static #packageDir = path.dirname( path.dirname( url.fileURLToPath( import.meta.url ) ) );
8
-
10
+ /** @type {Object<string,Object<string,Object<string,{}>>>} */
9
11
  #config = {};
10
12
 
11
- constructor( dataDir ) {
12
- this.#config = JSON.parse( Files.read( dataDir + "/config.json" ) );
13
+ /**
14
+ * @param {string} dataDir
15
+ */
16
+ constructor(dataDir) {
17
+ this.#config = JSON.parse(Files.read(dataDir + "/config.json"));
13
18
  }
14
19
 
15
- getConfigValue( prefix, name, subcat, dflt ) {
16
- const obj = this.#config[ prefix ];
17
- if ( obj ) {
18
- if ( Object.hasOwn( obj, name ) ) {
19
- const nameObj = obj[ name ];
20
- if ( nameObj === undefined ) {
20
+ /**
21
+ * @param {string} prefix
22
+ * @param {string} name
23
+ * @param {string|undefined} subcat
24
+ * @param {string} dflt
25
+ * @returns {string}
26
+ */
27
+ getConfigValue(prefix, name, subcat, dflt) {
28
+ const obj = this.#config[prefix];
29
+ if (obj) {
30
+ if (Object.hasOwn(obj, name)) {
31
+ const nameObj = obj[name];
32
+ if (nameObj === undefined) {
21
33
  return dflt;
22
34
  }
23
- if ( subcat === undefined ) {
24
- return nameObj;
35
+ if (subcat === undefined) {
36
+ return typeof nameObj === "string" ? nameObj : dflt;
25
37
  }
26
- if ( Object.hasOwn( nameObj, subcat ) ) {
27
- return nameObj[ subcat ];
38
+ if (Object.hasOwn(nameObj, subcat)) {
39
+ const v = nameObj[subcat];
40
+ return typeof v === "string" ? v : dflt;
28
41
  }
29
42
  }
30
43
  }
31
44
  return dflt;
32
45
  }
33
46
 
47
+ /**
48
+ * @returns {string[]}
49
+ */
34
50
  getCountyCodes() {
35
- return this.#config[ "counties" ];
51
+ const counties = this.#config["counties"];
52
+ if (counties instanceof Array) {
53
+ return counties;
54
+ }
55
+ return [];
36
56
  }
37
57
 
38
- getLabel( name, dflt ) {
39
- return this.getConfigValue( "labels", name, undefined, dflt );
58
+ /**
59
+ * @param {string} name
60
+ * @param {string} dflt
61
+ */
62
+ getLabel(name, dflt) {
63
+ return this.getConfigValue("labels", name, undefined, dflt);
40
64
  }
41
65
 
42
66
  static getPackageDir() {
43
67
  return this.#packageDir;
44
68
  }
45
-
46
69
  }
47
70
 
48
- export { Config };
71
+ export { Config };
package/lib/csv.js CHANGED
@@ -5,81 +5,99 @@ import { parse as parseSync } from "csv-parse/sync";
5
5
  import { parse } from "csv-parse";
6
6
 
7
7
  class CSV {
8
+ /**
9
+ * @param {string} dir
10
+ * @param {string} fileName
11
+ */
12
+ static getMap(dir, fileName) {
13
+ /** @type {string[]} */
14
+ let headers = [];
8
15
 
9
- static getMap( dir, fileName ) {
10
-
11
- let headers;
12
-
13
- function setHeaders( h ) {
16
+ /**
17
+ * @param {string[]} h
18
+ */
19
+ function setHeaders(h) {
14
20
  headers = h;
15
21
  return h;
16
22
  }
17
23
 
18
- const csv = this.parseFile( dir, fileName, setHeaders );
24
+ const csv = this.parseFile(dir, fileName, setHeaders);
25
+ /** @type {Object<string,string[]>} */
19
26
  const map = {};
20
- for ( const row of csv ) {
21
- map[ row[ headers[ 0 ] ] ] = row[ headers[ 1 ] ];
27
+ for (const row of csv) {
28
+ map[row[headers[0]]] = row[headers[1]];
22
29
  }
23
30
 
24
31
  return map;
25
32
  }
26
33
 
27
- static #getOptions( fileName, columns, delimiter ) {
34
+ /**
35
+ * @param {string} fileName
36
+ * @param {import("csv-parse").ColumnOption[]|boolean|function (string[]):string[]} columns
37
+ * @param {string|undefined} delimiter
38
+ */
39
+ static #getOptions(fileName, columns, delimiter) {
40
+ /** @type {import("csv-parse").Options} */
28
41
  const options = { relax_column_count_less: true };
29
42
  options.columns = columns;
30
- if ( path.extname( fileName ) === ".tsv" ) {
43
+ if (path.extname(fileName) === ".tsv") {
31
44
  options.delimiter = "\t";
32
45
  options.quote = false;
33
46
  } else {
34
47
  options.delimiter = delimiter ? delimiter : ",";
35
48
  }
36
- if ( options.delimiter === "\t" ) {
49
+ if (options.delimiter === "\t") {
37
50
  options.quote = null;
38
51
  }
39
52
  return options;
40
53
  }
41
54
 
42
55
  /**
43
- * @param {string} dir
44
- * @param {string} fileName
45
- * @param {boolean|undefined} [columns]
46
- * @param {string|undefined} [delimiter]
56
+ * @param {string} dir
57
+ * @param {string} fileName
58
+ * @param {boolean|import("csv-parse").ColumnOption[]|function (string[]):string[]} [columns]
59
+ * @param {string} [delimiter]
47
60
  */
48
- static parseFile( dir, fileName, columns = true, delimiter ) {
49
- const content = fs.readFileSync( dir + "/" + fileName );
61
+ static parseFile(dir, fileName, columns = true, delimiter) {
62
+ const content = fs.readFileSync(dir + "/" + fileName);
50
63
 
51
- const options = this.#getOptions( fileName, columns, delimiter );
52
- return parseSync( content, options );
64
+ const options = this.#getOptions(fileName, columns, delimiter);
65
+ return parseSync(content, options);
53
66
  }
54
67
 
55
68
  /**
56
- * @param {string} dir
57
- * @param {string} fileName
58
- * @param {boolean|undefined} columns
59
- * @param {string|undefined} delimiter
60
- * @param {*} callback
69
+ * @param {string} dir
70
+ * @param {string} fileName
71
+ * @param {boolean|import("csv-parse").ColumnOption[]} columns
72
+ * @param {string|undefined} delimiter
73
+ * @param {function (any):void} callback
61
74
  */
62
- static async parseStream( dir, fileName, columns = true, delimiter, callback ) {
63
- const options = this.#getOptions( fileName, columns, delimiter );
75
+ static async parseStream(
76
+ dir,
77
+ fileName,
78
+ columns = true,
79
+ delimiter,
80
+ callback
81
+ ) {
82
+ const options = this.#getOptions(fileName, columns, delimiter);
64
83
  const processFile = async () => {
84
+ /** @type {string[][]} */
65
85
  const records = [];
66
86
  const parser = fs
67
- .createReadStream( dir + "/" + fileName )
68
- .pipe( parse( options ) );
69
- parser.on( "readable", function () {
87
+ .createReadStream(dir + "/" + fileName)
88
+ .pipe(parse(options));
89
+ parser.on("readable", function () {
70
90
  let record;
71
- while ( ( record = parser.read() ) !== null ) {
72
- callback( record );
91
+ while ((record = parser.read()) !== null) {
92
+ callback(record);
73
93
  }
74
- } );
75
- await finished( parser );
94
+ });
95
+ await finished(parser);
76
96
  return records;
77
97
  };
78
98
  // Parse the CSV content
79
99
  await processFile();
80
-
81
100
  }
82
-
83
101
  }
84
102
 
85
- export { CSV };
103
+ export { CSV };
@@ -9,34 +9,40 @@ const MEDIA_TYPES = {
9
9
  XHTML: "application/xhtml+xml",
10
10
  };
11
11
 
12
+ /**
13
+ * @type {Object<string,string>}
14
+ */
12
15
  const EXT_MEDIA_MAP = {
13
- "jpeg": MEDIA_TYPES.JPG,
14
- "jpg": MEDIA_TYPES.JPG,
15
- "svg": MEDIA_TYPES.SVG,
16
+ jpeg: MEDIA_TYPES.JPG,
17
+ jpg: MEDIA_TYPES.JPG,
18
+ svg: MEDIA_TYPES.SVG,
16
19
  };
17
20
 
18
21
  class EBook {
19
-
20
22
  #outputDir;
21
23
  #filename;
22
24
  #pub_id;
23
25
  #title;
24
26
 
25
- constructor( outputDir, filename, pub_id, title ) {
26
-
27
+ /**
28
+ *
29
+ * @param {string} outputDir
30
+ * @param {string} filename
31
+ * @param {string} pub_id
32
+ * @param {string} title
33
+ */
34
+ constructor(outputDir, filename, pub_id, title) {
27
35
  this.#outputDir = outputDir;
28
36
  this.#filename = filename;
29
37
  this.#pub_id = pub_id;
30
38
  this.#title = title;
31
39
 
32
40
  // Initialize output directory.
33
- fs.rmSync( this.#outputDir, { force: true, recursive: true } );
34
- fs.mkdirSync( this.getContentDir(), { recursive: true } );
35
-
41
+ fs.rmSync(this.#outputDir, { force: true, recursive: true });
42
+ fs.mkdirSync(this.getContentDir(), { recursive: true });
36
43
  }
37
44
 
38
45
  async create() {
39
-
40
46
  const contentDir = this.getContentDir();
41
47
 
42
48
  this.#createContainerFile();
@@ -44,36 +50,35 @@ class EBook {
44
50
  this.#createPackageFile();
45
51
 
46
52
  // Copy assets
47
- // const cssDirTarget = contentDir + "/css";
48
- // fs.mkdirSync( cssDirTarget, { recursive: true } );
49
- fs.cpSync( Config.getPackageDir() + "/ebook", contentDir, { recursive: true } );
53
+ fs.cpSync(Config.getPackageDir() + "/ebook", contentDir, {
54
+ recursive: true,
55
+ });
50
56
 
51
57
  this.createZip();
52
-
53
58
  }
54
59
 
55
60
  #createContainerFile() {
56
-
57
61
  const metaDir = this.#getMetaDir();
58
62
 
59
- fs.mkdirSync( metaDir, { recursive: true } );
63
+ fs.mkdirSync(metaDir, { recursive: true });
60
64
 
61
- let xml = "<?xml version=\"1.0\"?>"
62
- + "<container version=\"1.0\" xmlns=\"urn:oasis:names:tc:opendocument:xmlns:container\">";
65
+ let xml =
66
+ '<?xml version="1.0"?>' +
67
+ '<container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">';
63
68
 
64
- xml += "<rootfiles><rootfile full-path=\"epub/package.opf\" media-type=\"application/oebps-package+xml\" /></rootfiles>";
69
+ xml +=
70
+ '<rootfiles><rootfile full-path="epub/package.opf" media-type="application/oebps-package+xml" /></rootfiles>';
65
71
  xml += "</container>";
66
72
 
67
- fs.writeFileSync( metaDir + "/container.xml", xml );
68
-
73
+ fs.writeFileSync(metaDir + "/container.xml", xml);
69
74
  }
70
75
 
71
76
  #createPackageFile() {
72
-
73
77
  const dir = this.getContentDir();
74
78
 
75
- let xml = "<?xml version=\"1.0\"?>\n"
76
- + "<package version=\"3.0\" xml:lang=\"en\" xmlns=\"http://www.idpf.org/2007/opf\" unique-identifier=\"pub-id\">";
79
+ let xml =
80
+ '<?xml version="1.0"?>\n' +
81
+ '<package version="3.0" xml:lang="en" xmlns="http://www.idpf.org/2007/opf" unique-identifier="pub-id">';
77
82
 
78
83
  xml += this.#renderMetadata();
79
84
  xml += this.#renderManifest();
@@ -81,50 +86,67 @@ class EBook {
81
86
 
82
87
  xml += "</package>";
83
88
 
84
- fs.writeFileSync( dir + "/package.opf", xml );
85
-
89
+ fs.writeFileSync(dir + "/package.opf", xml);
86
90
  }
87
91
 
88
92
  async createPages() {
89
- throw new Error( "must be implemented by subclass" );
93
+ throw new Error("must be implemented by subclass");
90
94
  }
91
95
 
92
96
  createZip() {
93
97
  // Create zip.
94
98
  const filename = this.#outputDir + "/" + this.#filename + ".epub";
95
- const output = fs.createWriteStream( filename );
96
- const archive = archiver(
97
- "zip",
98
- {
99
- zlib: { level: 9 } // Sets the compression level.
100
- }
101
- );
99
+ const output = fs.createWriteStream(filename);
100
+ const archive = archiver("zip", {
101
+ zlib: { level: 9 }, // Sets the compression level.
102
+ });
102
103
 
103
- archive.pipe( output );
104
+ archive.pipe(output);
104
105
 
105
- archive.append( "application/epub+zip", { name: "mimetype", store: true } );
106
+ archive.append("application/epub+zip", {
107
+ name: "mimetype",
108
+ store: true,
109
+ });
106
110
 
107
- archive.directory( this.#getMetaDir(), "META-INF" );
108
- archive.directory( this.getContentDir(), "epub" );
111
+ archive.directory(this.#getMetaDir(), "META-INF");
112
+ archive.directory(this.getContentDir(), "epub");
109
113
 
110
114
  archive.finalize();
111
-
112
115
  }
113
116
 
114
117
  getContentDir() {
115
118
  return this.#outputDir + "/epub";
116
119
  }
117
120
 
118
- static getManifestEntry( id, href, mediaType = MEDIA_TYPES.XHTML ) {
119
- return "<item id=\"" + id + "\" href=\"" + href + "\" media-type=\"" + mediaType + "\" />";
121
+ /**
122
+ * @param {string} id
123
+ * @param {string} href
124
+ * @param {string} mediaType
125
+ */
126
+ static getManifestEntry(id, href, mediaType = MEDIA_TYPES.XHTML) {
127
+ return (
128
+ '<item id="' +
129
+ id +
130
+ '" href="' +
131
+ href +
132
+ '" media-type="' +
133
+ mediaType +
134
+ '" />'
135
+ );
120
136
  }
121
137
 
122
- static getMediaTypeForExt( ext ) {
123
- return EXT_MEDIA_MAP[ ext ];
138
+ /**
139
+ * @param {string} ext
140
+ */
141
+ static getMediaTypeForExt(ext) {
142
+ return EXT_MEDIA_MAP[ext];
124
143
  }
125
144
 
126
- static getSpineEntry( id ) {
127
- return "<itemref idref=\"" + id + "\"/>";
145
+ /**
146
+ * @param {string} id
147
+ */
148
+ static getSpineEntry(id) {
149
+ return '<itemref idref="' + id + '"/>';
128
150
  }
129
151
 
130
152
  #getMetaDir() {
@@ -133,38 +155,43 @@ class EBook {
133
155
 
134
156
  #renderManifest() {
135
157
  let xml = "<manifest>";
136
- xml += "<item id=\"c0\" href=\"css/main.css\" media-type=\"text/css\" />";
158
+ xml += '<item id="c0" href="css/main.css" media-type="text/css" />';
137
159
  xml += this.renderManifestEntries();
138
- xml += "<item id=\"toc\" href=\"toc.xhtml\" media-type=\"application/xhtml+xml\" properties=\"nav\" />";
160
+ xml +=
161
+ '<item id="toc" href="toc.xhtml" media-type="application/xhtml+xml" properties="nav" />';
139
162
  return xml + "</manifest>";
140
163
  }
141
164
 
142
165
  renderManifestEntries() {
143
- throw new Error( "must be implemented by subclass" );
166
+ throw new Error("must be implemented by subclass");
144
167
  }
145
168
 
146
169
  #renderMetadata() {
147
- let xml = "<metadata xmlns:dc=\"http://purl.org/dc/elements/1.1/\">";
148
- xml += XHTML.textElement( "dc:identifier", this.#pub_id, { id: "pub-id" } );
170
+ let xml = '<metadata xmlns:dc="http://purl.org/dc/elements/1.1/">';
171
+ xml += XHTML.textElement("dc:identifier", this.#pub_id, {
172
+ id: "pub-id",
173
+ });
149
174
  xml += "<dc:language>en-US</dc:language>";
150
- xml += XHTML.textElement( "dc:title", this.#title );
175
+ xml += XHTML.textElement("dc:title", this.#title);
151
176
  const d = new Date();
152
- d.setUTCMilliseconds( 0 );
153
- xml += "<meta property=\"dcterms:modified\">" + d.toISOString().replace( ".000", "" ) + "</meta>";
177
+ d.setUTCMilliseconds(0);
178
+ xml +=
179
+ '<meta property="dcterms:modified">' +
180
+ d.toISOString().replace(".000", "") +
181
+ "</meta>";
154
182
  return xml + "</metadata>";
155
183
  }
156
184
 
157
185
  #renderSpine() {
158
186
  let xml = "<spine>";
159
- xml += "<itemref idref=\"toc\"/>";
187
+ xml += '<itemref idref="toc"/>';
160
188
  xml += this.renderSpineElements();
161
189
  return xml + "</spine>";
162
190
  }
163
191
 
164
192
  renderSpineElements() {
165
- throw new Error( "must be implemented by subclass" );
193
+ throw new Error("must be implemented by subclass");
166
194
  }
167
-
168
195
  }
169
196
 
170
- export { EBook };
197
+ export { EBook };
@@ -1,22 +1,27 @@
1
1
  import * as fs from "node:fs";
2
2
 
3
3
  class EBookPage {
4
-
5
4
  #fileName;
6
5
  #title;
7
6
  #rootPrefix;
8
7
 
9
- constructor( fileName, title, rootPrefix = "" ) {
8
+ /**
9
+ *
10
+ * @param {string} fileName
11
+ * @param {string} title
12
+ * @param {string} rootPrefix
13
+ */
14
+ constructor(fileName, title, rootPrefix = "") {
10
15
  this.#fileName = fileName;
11
16
  this.#title = title;
12
17
  this.#rootPrefix = rootPrefix;
13
18
  }
14
19
 
15
20
  create() {
16
- let html = this.#renderPageStart( this.#title );
21
+ let html = this.#renderPageStart(this.#title);
17
22
  html += this.renderPageBody();
18
23
  html += this.#renderPageEnd();
19
- fs.writeFileSync( this.#fileName, html );
24
+ fs.writeFileSync(this.#fileName, html);
20
25
  }
21
26
 
22
27
  getTitle() {
@@ -28,22 +33,28 @@ class EBookPage {
28
33
  }
29
34
 
30
35
  renderPageBody() {
31
- throw new Error( "must be implemented by subclass" );
36
+ throw new Error("must be implemented by subclass");
32
37
  }
33
38
 
34
39
  #renderPageEnd() {
35
40
  return "</body></html>";
36
41
  }
37
42
 
38
- #renderPageStart( title ) {
39
- let html = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
40
- html += "<html xmlns=\"http://www.w3.org/1999/xhtml\" xmlns:epub=\"http://www.idpf.org/2007/ops\">";
43
+ /**
44
+ * @param {string} title
45
+ */
46
+ #renderPageStart(title) {
47
+ let html = '<?xml version="1.0" encoding="utf-8"?>\n';
48
+ html +=
49
+ '<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">';
41
50
  html += "<head><title>" + title + "</title>";
42
- html += "<link href=\"" + this.#rootPrefix + "css/main.css\" rel=\"stylesheet\" />";
51
+ html +=
52
+ '<link href="' +
53
+ this.#rootPrefix +
54
+ 'css/main.css" rel="stylesheet" />';
43
55
  html += "</head>" + this.#renderBodyStart();
44
56
  return html;
45
57
  }
46
-
47
58
  }
48
59
 
49
- export { EBookPage };
60
+ export { EBookPage };
@@ -2,33 +2,55 @@ import { Files } from "../files.js";
2
2
  import { SiteGenerator } from "../sitegenerator.js";
3
3
 
4
4
  class EBookSiteGenerator extends SiteGenerator {
5
-
6
- constructor( baseDir ) {
7
- super( baseDir );
5
+ /**
6
+ * @param {string} baseDir
7
+ */
8
+ constructor(baseDir) {
9
+ super(baseDir);
8
10
  }
9
11
 
10
12
  #pageEnd() {
11
13
  return "</body></html>";
12
14
  }
13
15
 
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\">";
16
+ /**
17
+ * @param {number} depth
18
+ * @param {{title:string}} attributes
19
+ */
20
+ #pageStart(depth, attributes) {
21
+ let html = '<?xml version="1.0" encoding="utf-8"?>\n';
22
+ html +=
23
+ '<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">';
17
24
  html += "<head><title>" + attributes.title + "</title>";
18
- html += "<link href=\"" + "../".repeat( depth ) + "css/main.css\" rel=\"stylesheet\" />";
25
+ html +=
26
+ '<link href="' +
27
+ "../".repeat(depth) +
28
+ 'css/main.css" rel="stylesheet" />';
19
29
  html += "</head><body>";
20
30
  return html;
21
31
  }
22
32
 
23
- #wrap( depth, content, attributes ) {
24
- return this.#pageStart( depth, attributes ) + content + this.#pageEnd();
33
+ /**
34
+ * @param {number} depth
35
+ * @param {string} content
36
+ * @param {{title:string}} attributes
37
+ */
38
+ #wrap(depth, content, attributes) {
39
+ return this.#pageStart(depth, attributes) + content + this.#pageEnd();
25
40
  }
26
41
 
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 ) );
42
+ /**
43
+ * @param {string} content
44
+ * @param {{title:string}} attributes
45
+ * @param {string} filename
46
+ */
47
+ writeTemplate(content, attributes, filename) {
48
+ const depth = (filename.match(/\//g) || []).length;
49
+ Files.write(
50
+ Files.join(this.getBaseDir(), filename),
51
+ this.#wrap(depth, content, attributes)
52
+ );
30
53
  }
31
-
32
54
  }
33
55
 
34
- export { EBookSiteGenerator };
56
+ export { EBookSiteGenerator };
@@ -2,39 +2,42 @@ import { GlossaryPages as BaseGlossaryPages } from "../web/glossarypages.js";
2
2
  import { EBook } from "./ebook.js";
3
3
 
4
4
  class GlossaryPages extends BaseGlossaryPages {
5
-
6
- constructor( siteGenerator ) {
7
- super( siteGenerator );
5
+ /**
6
+ * @param {SiteGenerator} siteGenerator
7
+ */
8
+ constructor(siteGenerator) {
9
+ super(siteGenerator);
8
10
  }
9
11
 
10
12
  getManifestEntries() {
11
-
12
13
  const glossaryEntries = this.getGlossary().getEntries();
13
14
  const manifestEntries = [];
14
15
 
15
- manifestEntries.push( EBook.getManifestEntry( "g", "glossary.html" ) );
16
- for ( let index = 0; index < glossaryEntries.length; index++ ) {
17
- const entry = glossaryEntries[ index ];
18
- manifestEntries.push( EBook.getManifestEntry( "g" + index, "g/" + entry.getHTMLFileName() ) );
16
+ manifestEntries.push(EBook.getManifestEntry("g", "glossary.html"));
17
+ for (let index = 0; index < glossaryEntries.length; index++) {
18
+ const entry = glossaryEntries[index];
19
+ manifestEntries.push(
20
+ EBook.getManifestEntry(
21
+ "g" + index,
22
+ "g/" + entry.getHTMLFileName()
23
+ )
24
+ );
19
25
  }
20
26
 
21
- return manifestEntries.join( "" );
27
+ return manifestEntries.join("");
22
28
  }
23
29
 
24
30
  getSpineEntries() {
25
-
26
31
  const glossaryEntries = this.getGlossary().getEntries();
27
32
  const spineEntries = [];
28
33
 
29
- spineEntries.push( EBook.getSpineEntry( "g", "glossary.html" ) );
30
- for ( let index = 0; index < glossaryEntries.length; index++ ) {
31
- spineEntries.push( EBook.getSpineEntry( "g" + index ) );
34
+ spineEntries.push(EBook.getSpineEntry("g"));
35
+ for (let index = 0; index < glossaryEntries.length; index++) {
36
+ spineEntries.push(EBook.getSpineEntry("g" + index));
32
37
  }
33
38
 
34
- return spineEntries.join( "" );
35
-
39
+ return spineEntries.join("");
36
40
  }
37
-
38
41
  }
39
42
 
40
- export { GlossaryPages };
43
+ export { GlossaryPages };