@ca-plant-list/ca-plant-list 0.4.26 → 0.4.27
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/taxa.csv +1 -0
- package/generators/eleventy/layouts/h1.njk +6 -0
- package/generators/eleventy/layouts/html.njk +55 -0
- package/lib/basepagerenderer.js +35 -15
- package/lib/config.js +5 -3
- package/lib/ebook/ebookpage.js +1 -4
- package/lib/ebook/ebooksitegenerator.js +4 -12
- package/lib/ebook/glossarypages.js +1 -3
- package/lib/ebook/plantbook.js +1 -1
- package/lib/files.js +1 -0
- package/lib/htmltaxon.js +8 -19
- package/lib/index.d.ts +20 -8
- package/lib/index.js +4 -2
- package/lib/jekyll.js +40 -59
- package/lib/markdown.js +3 -5
- package/lib/sitegenerator.js +68 -12
- package/lib/types.js +4 -0
- package/lib/utils/eleventyGenerator.js +82 -0
- package/lib/utils/htmlFragments.js +19 -0
- package/lib/web/glossarypages.js +6 -10
- package/lib/web/pageFamily.js +14 -14
- package/lib/web/pageGeneric.js +78 -0
- package/lib/web/{pagetaxon.js → pageTaxon.js} +4 -4
- package/lib/web/pageTaxonList.js +53 -0
- package/lib/{pagerenderer.js → web/renderAllPages.js} +38 -80
- package/package.json +12 -10
- package/scripts/build-site.js +20 -52
- package/static/assets/js/nameSearchData.js +2 -0
- package/{jekyll → static}/assets/js/name_search.js +12 -14
- package/static/name_search.html +15 -0
- package/jekyll/_includes/glossary.html +0 -0
- package/jekyll/name_search.html +0 -17
- package/lib/genericpage.js +0 -88
- /package/{jekyll → generators}/_includes/analytics.html +0 -0
- /package/{jekyll → generators}/_includes/menu_extra.html +0 -0
- /package/{jekyll → generators/jekyll}/_config.yml +0 -0
- /package/{jekyll → generators/jekyll}/_layouts/default.html +0 -0
- /package/{jekyll → generators/jekyll}/_layouts/html.html +0 -0
- /package/{jekyll → static}/assets/css/main.css +0 -0
- /package/{jekyll → static}/assets/js/ui.js +0 -0
- /package/{jekyll → static}/assets/js/utils.js +0 -0
- /package/{jekyll → static}/index.md +0 -0
package/data/taxa.csv
CHANGED
@@ -503,6 +503,7 @@ Cryptantha clevelandii var. florosa,,N,57120,11565,1045003,203153,,Coastal Crypt
|
|
503
503
|
Cryptantha corollata,,N,21213,2452,58853,203157,,Coast Range Cryptantha
|
504
504
|
Cryptantha flaccida,,N,21228,2460,56989,203167,,Flaccid Cryptantha
|
505
505
|
Cryptantha hooveri,,N,21240,2468,57701,245944,,Hoover's Cryptantha,,,,,525,1A,,,SH,GH
|
506
|
+
Cryptantha hispidula,Napa cryptantha,N,21237,2465,57703,203175,,Napa Cryptantha,annual,white,3,5
|
506
507
|
Cryptantha intermedia var. intermedia,,N,71933,11568,80627,203183
|
507
508
|
Cryptantha juniperensis,rigid cryptantha,N,103476,14557,769572,203205
|
508
509
|
Cryptantha micromeres,,N,21263,2476,770232,203194,,Minute-flowered Cryptantha
|
@@ -0,0 +1,55 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html lang="en">
|
3
|
+
|
4
|
+
<head>
|
5
|
+
<meta charset="utf-8">
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
7
|
+
<link href="https://cdn.jsdelivr.net/npm/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" crossorigin="anonymous">
|
8
|
+
<title>{{title}}</title>
|
9
|
+
<link href="/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="/index.html">{{siteName}}</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="/index_lists.html">Plant Lists</a>
|
26
|
+
</li>
|
27
|
+
<li class="nav-item">
|
28
|
+
<a class="nav-link" href="/rare_plants.html">Rare Plants</a>
|
29
|
+
</li>
|
30
|
+
<li class="nav-item">
|
31
|
+
<a class="nav-link" href="/name_search.html">Name Search</a>
|
32
|
+
</li>
|
33
|
+
<li class="nav-item">
|
34
|
+
<a class="nav-link" href="/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
|
+
{{content|safe}}
|
44
|
+
</div>
|
45
|
+
|
46
|
+
<script src="https://cdn.jsdelivr.net/npm/bootstrap/dist/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script>
|
47
|
+
|
48
|
+
{%if js%}<script src="/assets/js/{{js}}" type="module"></script>{%endif%}
|
49
|
+
|
50
|
+
<script src="/assets/js/ui.js" type="module"></script>
|
51
|
+
|
52
|
+
{%include "analytics.html"%}
|
53
|
+
</body>
|
54
|
+
|
55
|
+
</html>
|
package/lib/basepagerenderer.js
CHANGED
@@ -1,33 +1,49 @@
|
|
1
|
-
import
|
1
|
+
import path from "node:path";
|
2
2
|
import { Files } from "./files.js";
|
3
|
-
import { Jekyll } from "./jekyll.js";
|
4
3
|
import { GlossaryPages } from "./web/glossarypages.js";
|
5
4
|
import { PageFamilyList } from "./web/pageFamily.js";
|
5
|
+
import { Jekyll } from "./jekyll.js";
|
6
|
+
import { EleventyGenerator } from "./utils/eleventyGenerator.js";
|
6
7
|
|
7
8
|
export class BasePageRenderer {
|
8
9
|
/**
|
10
|
+
* @param {import("./types.js").Config} config
|
9
11
|
* @param {string} outputDir
|
12
|
+
* @param {import("./index.js").SiteGeneratorOptions} options
|
13
|
+
* @param {"11ty"|"jekyll"} [type="11ty"]
|
14
|
+
* @returns {import("./types.js").SiteGenerator}
|
15
|
+
*/
|
16
|
+
static newSiteGenerator(config, outputDir, options = {}, type = "11ty") {
|
17
|
+
switch (type) {
|
18
|
+
case "jekyll":
|
19
|
+
return new Jekyll(config, outputDir);
|
20
|
+
}
|
21
|
+
return new EleventyGenerator(config, outputDir, options);
|
22
|
+
}
|
23
|
+
|
24
|
+
/**
|
25
|
+
* @param {import("./types.js").SiteGenerator} siteGenerator
|
10
26
|
* @param {import("./types.js").Taxa} taxa
|
11
27
|
* @param {import("./types.js").TaxaColDef[]} [familyCols]
|
12
28
|
*/
|
13
|
-
static renderBasePages(
|
14
|
-
const
|
29
|
+
static renderBasePages(siteGenerator, taxa, familyCols) {
|
30
|
+
const outputDir = siteGenerator.getBaseDir();
|
15
31
|
|
16
32
|
// Copy static files
|
17
|
-
|
18
|
-
|
19
|
-
//
|
20
|
-
|
33
|
+
siteGenerator.copyStaticFiles();
|
34
|
+
|
35
|
+
// Copy static files
|
36
|
+
siteGenerator.copyGeneratorFiles();
|
21
37
|
|
22
38
|
// Copy illustrations.
|
23
39
|
siteGenerator.copyIllustrations(taxa.getFlowerColors());
|
24
40
|
|
25
41
|
const fl = new PageFamilyList(
|
26
|
-
|
42
|
+
siteGenerator,
|
27
43
|
taxa.getFamilies().getFamilies(),
|
28
44
|
);
|
29
45
|
fl.render(familyCols);
|
30
|
-
fl.renderPages(
|
46
|
+
fl.renderPages(siteGenerator, familyCols);
|
31
47
|
|
32
48
|
new GlossaryPages(siteGenerator).renderPages();
|
33
49
|
|
@@ -41,22 +57,26 @@ export class BasePageRenderer {
|
|
41
57
|
static renderTools(outputDir, taxa) {
|
42
58
|
const names = [];
|
43
59
|
for (const taxon of taxa.getTaxonList()) {
|
44
|
-
|
45
|
-
row
|
60
|
+
/** @type {(import("./types.js").NameSearchData)} */
|
61
|
+
const row = { t: taxon.getName() };
|
46
62
|
const cn = taxon.getCommonNames().join(", ");
|
47
63
|
if (cn) {
|
48
|
-
row.
|
64
|
+
row.c = cn;
|
49
65
|
}
|
50
66
|
const synonyms = [];
|
51
67
|
for (const syn of taxon.getSynonyms()) {
|
52
68
|
synonyms.push(syn);
|
53
69
|
}
|
54
70
|
if (synonyms.length > 0) {
|
55
|
-
row
|
71
|
+
row.s = synonyms;
|
56
72
|
}
|
57
73
|
names.push(row);
|
58
74
|
}
|
59
75
|
|
60
|
-
Files.write(
|
76
|
+
Files.write(
|
77
|
+
path.join(outputDir, "./assets/js/nameSearchData.js"),
|
78
|
+
`export const NAMES = ${JSON.stringify(names)};`,
|
79
|
+
true,
|
80
|
+
);
|
61
81
|
}
|
62
82
|
}
|
package/lib/config.js
CHANGED
@@ -8,7 +8,7 @@ const COUNTY_NAMES = {
|
|
8
8
|
CCA: "Contra Costa",
|
9
9
|
};
|
10
10
|
|
11
|
-
class Config {
|
11
|
+
export class Config {
|
12
12
|
static #packageDir = path.dirname(
|
13
13
|
path.dirname(url.fileURLToPath(import.meta.url)),
|
14
14
|
);
|
@@ -88,6 +88,8 @@ class Config {
|
|
88
88
|
static getPackageDir() {
|
89
89
|
return this.#packageDir;
|
90
90
|
}
|
91
|
-
}
|
92
91
|
|
93
|
-
|
92
|
+
getSiteName() {
|
93
|
+
return this.#config.siteName ?? "California Plants";
|
94
|
+
}
|
95
|
+
}
|
package/lib/ebook/ebookpage.js
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
import * as fs from "node:fs";
|
2
2
|
|
3
|
-
class EBookPage {
|
3
|
+
export class EBookPage {
|
4
4
|
#fileName;
|
5
5
|
#title;
|
6
6
|
#rootPrefix;
|
7
7
|
|
8
8
|
/**
|
9
|
-
*
|
10
9
|
* @param {string} fileName
|
11
10
|
* @param {string} title
|
12
11
|
* @param {string} rootPrefix
|
@@ -56,5 +55,3 @@ class EBookPage {
|
|
56
55
|
return html;
|
57
56
|
}
|
58
57
|
}
|
59
|
-
|
60
|
-
export { EBookPage };
|
@@ -1,14 +1,8 @@
|
|
1
|
+
import path from "node:path";
|
1
2
|
import { Files } from "../files.js";
|
2
3
|
import { SiteGenerator } from "../sitegenerator.js";
|
3
4
|
|
4
|
-
class EBookSiteGenerator extends SiteGenerator {
|
5
|
-
/**
|
6
|
-
* @param {string} baseDir
|
7
|
-
*/
|
8
|
-
constructor(baseDir) {
|
9
|
-
super(baseDir);
|
10
|
-
}
|
11
|
-
|
5
|
+
export class EBookSiteGenerator extends SiteGenerator {
|
12
6
|
#pageEnd() {
|
13
7
|
return "</body></html>";
|
14
8
|
}
|
@@ -47,10 +41,8 @@ class EBookSiteGenerator extends SiteGenerator {
|
|
47
41
|
writeTemplate(content, attributes, filename) {
|
48
42
|
const depth = (filename.match(/\//g) || []).length;
|
49
43
|
Files.write(
|
50
|
-
|
51
|
-
this.#wrap(depth, content, attributes)
|
44
|
+
path.join(this.getBaseDir(), filename),
|
45
|
+
this.#wrap(depth, content, attributes),
|
52
46
|
);
|
53
47
|
}
|
54
48
|
}
|
55
|
-
|
56
|
-
export { EBookSiteGenerator };
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import { GlossaryPages as BaseGlossaryPages } from "../web/glossarypages.js";
|
2
2
|
import { EBook } from "./ebook.js";
|
3
3
|
|
4
|
-
class GlossaryPages extends BaseGlossaryPages {
|
4
|
+
export class GlossaryPages extends BaseGlossaryPages {
|
5
5
|
/**
|
6
6
|
* @param {import("../sitegenerator.js").SiteGenerator} siteGenerator
|
7
7
|
*/
|
@@ -39,5 +39,3 @@ class GlossaryPages extends BaseGlossaryPages {
|
|
39
39
|
return spineEntries.join("");
|
40
40
|
}
|
41
41
|
}
|
42
|
-
|
43
|
-
export { GlossaryPages };
|
package/lib/ebook/plantbook.js
CHANGED
@@ -29,7 +29,7 @@ class PlantBook extends EBook {
|
|
29
29
|
);
|
30
30
|
|
31
31
|
this.#taxa = taxa;
|
32
|
-
const generator = new EBookSiteGenerator(this.getContentDir());
|
32
|
+
const generator = new EBookSiteGenerator(config, this.getContentDir());
|
33
33
|
this.#glossary = new GlossaryPages(generator);
|
34
34
|
this.#images = new Images(generator, this.getContentDir(), taxa);
|
35
35
|
}
|
package/lib/files.js
CHANGED
package/lib/htmltaxon.js
CHANGED
@@ -1,10 +1,11 @@
|
|
1
|
+
import path from "node:path";
|
1
2
|
import { Config } from "./config.js";
|
2
3
|
import { DateUtils } from "./dateutils.js";
|
3
4
|
import { ExternalSites } from "./externalsites.js";
|
4
5
|
import { HTML } from "./html.js";
|
5
|
-
import { Markdown } from "./markdown.js";
|
6
6
|
import { RarePlants } from "./rareplants.js";
|
7
7
|
import { TextUtils } from "./textutils.js";
|
8
|
+
import { HTMLFragments } from "./utils/htmlFragments.js";
|
8
9
|
|
9
10
|
/**
|
10
11
|
* @type {Record<string,import("./types.js").TaxaColDef>}
|
@@ -204,12 +205,12 @@ class HTMLTaxon {
|
|
204
205
|
* @returns {string}
|
205
206
|
*/
|
206
207
|
static getFooterHTML(taxon) {
|
207
|
-
const footerTextPath =
|
208
|
-
Config.getPackageDir()
|
209
|
-
"/data/text/"
|
210
|
-
taxon.getBaseFileName()
|
211
|
-
|
212
|
-
return
|
208
|
+
const footerTextPath = path.join(
|
209
|
+
Config.getPackageDir(),
|
210
|
+
"/data/text/",
|
211
|
+
`${taxon.getBaseFileName()}.footer.md`,
|
212
|
+
);
|
213
|
+
return HTMLFragments.getMarkdownSection(footerTextPath);
|
213
214
|
}
|
214
215
|
|
215
216
|
/**
|
@@ -271,18 +272,6 @@ class HTMLTaxon {
|
|
271
272
|
return html;
|
272
273
|
}
|
273
274
|
|
274
|
-
/**
|
275
|
-
* @param {string} filePath
|
276
|
-
* @returns {string}
|
277
|
-
*/
|
278
|
-
static getMarkdownSection(filePath) {
|
279
|
-
const footerMarkdown = Markdown.fileToHTML(filePath);
|
280
|
-
if (footerMarkdown) {
|
281
|
-
return HTML.wrap("div", footerMarkdown, "section");
|
282
|
-
}
|
283
|
-
return "";
|
284
|
-
}
|
285
|
-
|
286
275
|
/**
|
287
276
|
* @param {import("./types.js").Taxon} taxon
|
288
277
|
*/
|
package/lib/index.d.ts
CHANGED
@@ -15,6 +15,10 @@ type RefSourceCode =
|
|
15
15
|
| "jepson"
|
16
16
|
| "rpi";
|
17
17
|
|
18
|
+
type SiteGeneratorOptions = {
|
19
|
+
passThroughPatterns?: string[];
|
20
|
+
};
|
21
|
+
|
18
22
|
type TaxaColDef<T> = {
|
19
23
|
title: string;
|
20
24
|
class?: string;
|
@@ -53,8 +57,13 @@ export type TaxonOverrides = {
|
|
53
57
|
// Classes
|
54
58
|
|
55
59
|
export class BasePageRenderer {
|
56
|
-
static
|
60
|
+
static newSiteGenerator(
|
61
|
+
config: Config,
|
57
62
|
outputDir: string,
|
63
|
+
options?: SiteGeneratorOptions,
|
64
|
+
): SiteGenerator;
|
65
|
+
static renderBasePages<T extends Taxon>(
|
66
|
+
siteGenerator: SiteGenerator,
|
58
67
|
taxa: Taxa<T>,
|
59
68
|
familyCols?: TaxaColDef<T>[],
|
60
69
|
): void;
|
@@ -150,6 +159,10 @@ export class HTML {
|
|
150
159
|
): string;
|
151
160
|
}
|
152
161
|
|
162
|
+
export class HTMLFragments {
|
163
|
+
static getMarkdownSection(filePath: string): string;
|
164
|
+
}
|
165
|
+
|
153
166
|
export class HTMLTaxon {
|
154
167
|
static addLink(
|
155
168
|
links: string[],
|
@@ -174,13 +187,6 @@ export class HTMLTaxon {
|
|
174
187
|
header: string,
|
175
188
|
className?: string,
|
176
189
|
): string;
|
177
|
-
static getMarkdownSection(filePath: string): string;
|
178
|
-
}
|
179
|
-
|
180
|
-
export class Jekyll {
|
181
|
-
static hasInclude(baseDir: string, path: string): boolean;
|
182
|
-
static include(fileName: string): string;
|
183
|
-
static writeInclude(baseDir: string, path: string, data: string): void;
|
184
190
|
}
|
185
191
|
|
186
192
|
export class Photo {
|
@@ -196,6 +202,12 @@ export class Program {
|
|
196
202
|
static getProgram(): Command;
|
197
203
|
}
|
198
204
|
|
205
|
+
export class SiteGenerator {
|
206
|
+
generate(outputDir: string): Promise<void>;
|
207
|
+
getBaseDir(): string;
|
208
|
+
getFrontMatter(atts: Record<string, string | undefined>): string;
|
209
|
+
}
|
210
|
+
|
199
211
|
export class Taxa<T> {
|
200
212
|
constructor(
|
201
213
|
inclusionList: Record<string, TaxonOverrides> | true,
|
package/lib/index.js
CHANGED
@@ -7,10 +7,11 @@ import { ExternalSites } from "./externalsites.js";
|
|
7
7
|
import { Families } from "./taxonomy/families.js";
|
8
8
|
import { Files } from "./files.js";
|
9
9
|
import { HTML } from "./html.js";
|
10
|
+
import { HTMLFragments } from "./utils/htmlFragments.js";
|
10
11
|
import { HTMLTaxon } from "./htmltaxon.js";
|
11
|
-
import { Jekyll } from "./jekyll.js";
|
12
12
|
import { PlantBook } from "./ebook/plantbook.js";
|
13
13
|
import { Program } from "./program.js";
|
14
|
+
import { SiteGenerator } from "./sitegenerator.js";
|
14
15
|
import { Taxa } from "./taxonomy/taxa.js";
|
15
16
|
import { Taxon } from "./taxonomy/taxon.js";
|
16
17
|
|
@@ -24,10 +25,11 @@ export {
|
|
24
25
|
Families,
|
25
26
|
Files,
|
26
27
|
HTML,
|
28
|
+
HTMLFragments,
|
27
29
|
HTMLTaxon,
|
28
|
-
Jekyll,
|
29
30
|
PlantBook,
|
30
31
|
Program,
|
32
|
+
SiteGenerator,
|
31
33
|
Taxa,
|
32
34
|
Taxon,
|
33
35
|
};
|
package/lib/jekyll.js
CHANGED
@@ -1,71 +1,52 @@
|
|
1
|
+
import * as child_process from "node:child_process";
|
2
|
+
import * as path from "node:path";
|
1
3
|
import { Files } from "./files.js";
|
2
4
|
import { SiteGenerator } from "./sitegenerator.js";
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
5
|
+
import { Config } from "./config.js";
|
6
|
+
|
7
|
+
export class Jekyll extends SiteGenerator {
|
8
|
+
copyGeneratorFiles() {
|
9
|
+
// First copy default files from package.
|
10
|
+
Files.copyDir(
|
11
|
+
path.join(Config.getPackageDir(), "./generators/jekyll"),
|
12
|
+
this.getBaseDir(),
|
13
|
+
);
|
14
|
+
// Then copy files from current dir (which may override default files).
|
15
|
+
Files.copyDir("./generators/jekyll", this.getBaseDir());
|
12
16
|
}
|
13
17
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
async generate() {
|
19
|
+
/**
|
20
|
+
* @param {string[]} configFiles
|
21
|
+
* @param {string} dir
|
22
|
+
* @param {string} name
|
23
|
+
*/
|
24
|
+
function addConfigFile(configFiles, dir, name) {
|
25
|
+
const fullPath = path.join(dir, name);
|
26
|
+
if (Files.exists(fullPath)) {
|
27
|
+
configFiles.push(fullPath);
|
28
|
+
}
|
21
29
|
}
|
22
|
-
if (!atts.layout) {
|
23
|
-
lines.push("layout: default");
|
24
|
-
}
|
25
|
-
lines.push(FRONT_DELIM);
|
26
|
-
return lines.join("\n") + "\n";
|
27
|
-
}
|
28
30
|
|
29
|
-
|
30
|
-
|
31
|
-
* @param {string} path
|
32
|
-
*/
|
33
|
-
static hasInclude(baseDir, path) {
|
34
|
-
return Files.exists(baseDir + "/_includes/" + path);
|
35
|
-
}
|
31
|
+
const srcDir = "./output";
|
32
|
+
const destDir = "./public";
|
36
33
|
|
37
|
-
|
38
|
-
|
39
|
-
*/
|
40
|
-
static include(path) {
|
41
|
-
// This works for .md includes; should have conditional logic to detect other types.
|
42
|
-
return (
|
43
|
-
"{% capture my_include %}{% include " +
|
44
|
-
path +
|
45
|
-
" %}{% endcapture %}{{ my_include | markdownify }}"
|
46
|
-
);
|
47
|
-
}
|
34
|
+
// Remove existing files.
|
35
|
+
Files.rmDir(destDir);
|
48
36
|
|
49
|
-
|
50
|
-
* @param {string} baseDir
|
51
|
-
* @param {string} path
|
52
|
-
* @param {string} data
|
53
|
-
*/
|
54
|
-
static writeInclude(baseDir, path, data) {
|
55
|
-
Files.write(baseDir + "/_includes/" + path, data);
|
56
|
-
}
|
37
|
+
const options = ["--source", srcDir, "--destination", destDir];
|
57
38
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
39
|
+
// Find out what config files are available.
|
40
|
+
/** @type {string[]} */
|
41
|
+
const configFiles = [];
|
42
|
+
addConfigFile(configFiles, srcDir, "_config.yml");
|
43
|
+
addConfigFile(configFiles, 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(" "),
|
67
49
|
);
|
50
|
+
console.log(result.toString());
|
68
51
|
}
|
69
52
|
}
|
70
|
-
|
71
|
-
export { Jekyll };
|
package/lib/markdown.js
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
import markdownIt from "markdown-it";
|
2
2
|
import { Files } from "./files.js";
|
3
3
|
|
4
|
-
class Markdown {
|
4
|
+
export class Markdown {
|
5
5
|
static #md = new markdownIt({ xhtmlOut: true });
|
6
6
|
|
7
7
|
/**
|
8
8
|
* @param {string} filePath
|
9
|
-
* @returns {string
|
9
|
+
* @returns {string}
|
10
10
|
*/
|
11
11
|
static fileToHTML(filePath) {
|
12
12
|
if (!Files.exists(filePath)) {
|
13
|
-
return;
|
13
|
+
return "";
|
14
14
|
}
|
15
15
|
return this.strToHTML(Files.read(filePath));
|
16
16
|
}
|
@@ -22,5 +22,3 @@ class Markdown {
|
|
22
22
|
return this.#md.render(str);
|
23
23
|
}
|
24
24
|
}
|
25
|
-
|
26
|
-
export { Markdown };
|
package/lib/sitegenerator.js
CHANGED
@@ -1,16 +1,29 @@
|
|
1
|
+
import path from "node:path";
|
1
2
|
import { optimize } from "svgo-ll";
|
2
3
|
|
3
4
|
import { Config } from "./config.js";
|
4
5
|
import { Files } from "./files.js";
|
5
6
|
|
6
|
-
|
7
|
+
const FRONT_DELIM = "---";
|
8
|
+
|
9
|
+
export class SiteGenerator {
|
10
|
+
#config;
|
7
11
|
#baseDir;
|
12
|
+
#options;
|
8
13
|
|
9
14
|
/**
|
15
|
+
* @param {Config} config
|
10
16
|
* @param {string} baseDir
|
17
|
+
* @param {import("./index.js").SiteGeneratorOptions} [options]
|
11
18
|
*/
|
12
|
-
constructor(baseDir) {
|
19
|
+
constructor(config, baseDir, options = {}) {
|
20
|
+
this.#config = config;
|
13
21
|
this.#baseDir = baseDir;
|
22
|
+
this.#options = options;
|
23
|
+
}
|
24
|
+
|
25
|
+
copyGeneratorFiles() {
|
26
|
+
throw new Error("must be implemented by subclass");
|
14
27
|
}
|
15
28
|
|
16
29
|
/**
|
@@ -23,11 +36,11 @@ class SiteGenerator {
|
|
23
36
|
*/
|
24
37
|
function createFlowerColorIcons(outputDir, flowerColors) {
|
25
38
|
// Read generic input.
|
26
|
-
const inputFileName =
|
39
|
+
const inputFileName = path.join(outputDir, "flower.svg");
|
27
40
|
const srcSVG = Files.read(inputFileName);
|
28
41
|
for (const color of flowerColors) {
|
29
42
|
Files.write(
|
30
|
-
|
43
|
+
path.join(outputDir, "f-" + color.getColorName() + ".svg"),
|
31
44
|
srcSVG.replace("#ff0", color.getColorCode()),
|
32
45
|
);
|
33
46
|
}
|
@@ -59,26 +72,69 @@ class SiteGenerator {
|
|
59
72
|
createFlowerColorIcons(outputDir, flowerColors);
|
60
73
|
}
|
61
74
|
|
75
|
+
copyStaticFiles() {
|
76
|
+
// First copy default files from ca-plant-list.
|
77
|
+
Files.copyDir(
|
78
|
+
path.join(Config.getPackageDir(), "static"),
|
79
|
+
this.#baseDir,
|
80
|
+
);
|
81
|
+
// Then copy files from current directory (which may override default files).
|
82
|
+
Files.copyDir("./static", this.#baseDir);
|
83
|
+
}
|
84
|
+
|
85
|
+
/**
|
86
|
+
* @param {string} webDir
|
87
|
+
*/
|
88
|
+
// eslint-disable-next-line no-unused-vars
|
89
|
+
async generate(webDir) {
|
90
|
+
throw new Error("must be implemented by subclass");
|
91
|
+
}
|
92
|
+
|
62
93
|
getBaseDir() {
|
63
94
|
return this.#baseDir;
|
64
95
|
}
|
65
96
|
|
97
|
+
getConfig() {
|
98
|
+
return this.#config;
|
99
|
+
}
|
100
|
+
|
66
101
|
/**
|
67
|
-
* @param {string}
|
102
|
+
* @param {Object<string,string|undefined>} atts
|
68
103
|
*/
|
69
|
-
|
70
|
-
|
104
|
+
getFrontMatter(atts) {
|
105
|
+
const lines = [FRONT_DELIM];
|
106
|
+
for (const [k, v] of Object.entries(atts)) {
|
107
|
+
if (v) {
|
108
|
+
lines.push(k + ': "' + v + '"');
|
109
|
+
}
|
110
|
+
}
|
111
|
+
lines.push(FRONT_DELIM);
|
112
|
+
return lines.join("\n") + "\n\n";
|
113
|
+
}
|
114
|
+
|
115
|
+
/**
|
116
|
+
* @returns {string[]}
|
117
|
+
*/
|
118
|
+
getPassThroughPatterns() {
|
119
|
+
return this.#options.passThroughPatterns ?? [];
|
120
|
+
}
|
121
|
+
|
122
|
+
/**
|
123
|
+
* @param {string} outputSubdir
|
124
|
+
*/
|
125
|
+
mkdir(outputSubdir) {
|
126
|
+
Files.mkdir(path.join(this.#baseDir, outputSubdir));
|
71
127
|
}
|
72
128
|
|
73
129
|
/**
|
74
130
|
* @param {string} content
|
75
|
-
* @param {
|
131
|
+
* @param {Object<string,string>} attributes
|
76
132
|
* @param {string} filename
|
77
133
|
*/
|
78
|
-
// eslint-disable-next-line no-unused-vars
|
79
134
|
writeTemplate(content, attributes, filename) {
|
80
|
-
|
135
|
+
Files.write(
|
136
|
+
path.join(this.getBaseDir(), filename),
|
137
|
+
this.getFrontMatter(attributes) + content,
|
138
|
+
);
|
81
139
|
}
|
82
140
|
}
|
83
|
-
|
84
|
-
export { SiteGenerator };
|