@portosaur/core 0.2.0 → 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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@portosaur/core",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "The engine of portosaur that translates YAML configuration into Docusaurus structures.",
5
5
  "license": "GPL-3.0-only",
6
6
  "author": "soymadip",
@@ -27,9 +27,11 @@
27
27
  },
28
28
  "types": "./src/index.d.ts",
29
29
  "dependencies": {
30
- "@portosaur/logger": "^0.2.0",
30
+ "@portosaur/logger": "^0.4.0",
31
31
  "favicons": "^7.2.0",
32
32
  "js-yaml": "^4.1.1",
33
+ "rehype-katex": "7",
34
+ "remark-math": "6",
33
35
  "sharp": "^0.34.5"
34
36
  },
35
37
  "engines": {
@@ -11,6 +11,9 @@ import {
11
11
  buildHeadTags,
12
12
  } from "../utils/docusaurus.mjs";
13
13
 
14
+ import remarkMath from "remark-math";
15
+ import rehypeKatex from "rehype-katex";
16
+
14
17
  // ------- Main Configuration Generator -------
15
18
 
16
19
  /**
@@ -302,8 +305,15 @@ export function buildDocuConfig(rawUserConfig, projectDir, context = {}) {
302
305
  portoPaths.theme ?? context.portoRoot ?? "",
303
306
  "config/sidebar.jsx",
304
307
  ),
308
+ remarkPlugins: [remarkMath],
309
+ rehypePlugins: [rehypeKatex],
310
+ },
311
+ blog: {
312
+ path: "blog",
313
+ showReadingTime: false,
314
+ remarkPlugins: [remarkMath],
315
+ rehypePlugins: [rehypeKatex],
305
316
  },
306
- blog: { path: "blog", showReadingTime: false },
307
317
  theme: {
308
318
  customCss: path.resolve(
309
319
  portoPaths.theme ?? context.portoRoot ?? "",
@@ -343,7 +353,37 @@ export function buildDocuConfig(rawUserConfig, projectDir, context = {}) {
343
353
 
344
354
  // ------- Plugins -------
345
355
 
356
+ stylesheets: [
357
+ {
358
+ href: "https://cdn.jsdelivr.net/npm/katex@0.17.0/dist/katex.min.css",
359
+ type: "text/css",
360
+ integrity:
361
+ "sha384-vlBdW0r3AcZO/HboRPznQNowvexd3fY8qHOWkBi5q7KGgqJ+F48+DceybYmrVbmB",
362
+ crossorigin: "anonymous",
363
+ },
364
+ ],
365
+
346
366
  plugins: [
367
+ function portosaurWebpackLoader(context, options) {
368
+ return {
369
+ name: "portosaur-webpack-loader",
370
+ configureWebpack(config, isServer, utils) {
371
+ return {
372
+ module: {
373
+ rules: [
374
+ {
375
+ test: /\.jsx?$/,
376
+ include: [
377
+ path.resolve(portoPaths.theme ?? context.portoRoot ?? ""),
378
+ ],
379
+ use: [utils.getJSLoader({ isServer })],
380
+ },
381
+ ],
382
+ },
383
+ };
384
+ },
385
+ };
386
+ },
347
387
  [
348
388
  "@docusaurus/plugin-pwa",
349
389
  {
package/src/index.d.ts CHANGED
@@ -31,6 +31,7 @@ export {
31
31
  openInBrowser,
32
32
  } from "./utils/system.mjs";
33
33
  export { porto, git, text, limits } from "./app.mjs";
34
+ export { getCssVar } from "./utils/cssExtractor.mjs";
34
35
  export { generateFavicons } from "./generators/generateFavicons.mjs";
35
36
  export { generateRobotsTxt } from "./generators/generateRobots.mjs";
36
37
  export {
package/src/index.mjs CHANGED
@@ -14,6 +14,8 @@ export {
14
14
 
15
15
  export * from "./app.mjs";
16
16
 
17
+ export { getCssVar } from "./utils/cssExtractor.mjs";
18
+
17
19
  export { generateFavicons } from "./generators/generateFavicons.mjs";
18
20
  export { generateRobotsTxt } from "./generators/generateRobots.mjs";
19
21
  export { buildDocuConfig } from "./generators/docusaurusConfig.mjs";
@@ -0,0 +1,72 @@
1
+ import fs from "fs";
2
+ import { logger } from "@portosaur/logger";
3
+
4
+ // Cache for CSS content and parsed variables to avoid redundant reads
5
+ const cssCache = new Map();
6
+ const varCache = new Map();
7
+
8
+ /**
9
+ * Extracts a CSS variable's value from an array of CSS files.
10
+ * Supports resolving nested variables (e.g., var(--other-var)).
11
+ *
12
+ * @param {string} varName - The CSS variable name to find (e.g., '--ifm-color-primary').
13
+ * @param {string[]} cssFiles - Array of absolute paths to CSS files to search in.
14
+ * @returns {string|null} The resolved CSS variable value, or null if not found.
15
+ */
16
+ export function getCssVar(varName, cssFiles = []) {
17
+ // Return cached value if exists
18
+ if (varCache.has(varName)) {
19
+ return varCache.get(varName);
20
+ }
21
+
22
+ for (const cssPath of cssFiles) {
23
+ try {
24
+ if (!fs.existsSync(cssPath)) {
25
+ continue;
26
+ }
27
+
28
+ let cssContent = cssCache.get(cssPath);
29
+ if (!cssContent) {
30
+ cssContent = fs.readFileSync(cssPath, "utf8");
31
+ cssCache.set(cssPath, cssContent);
32
+ }
33
+
34
+ // Find all occurrences of the variable (e.g., --var-name: value;)
35
+ // Using a regex that captures everything up to a semicolon or closing brace
36
+ const regex = new RegExp(`${varName}:\\s*([^;}]+)`, "g");
37
+ let lastValue = null;
38
+ let match;
39
+
40
+ // Find all matches and keep the last one (CSS cascade logic)
41
+ while ((match = regex.exec(cssContent)) !== null) {
42
+ lastValue = match[1].replace(/!important/g, "").trim();
43
+ }
44
+
45
+ // Process nested variables: if the value is var(--something)
46
+ if (lastValue && lastValue.includes("var(")) {
47
+ const nestedMatch = lastValue.match(/var\((--[^)]+)\)/);
48
+ if (nestedMatch) {
49
+ const nestedVar = nestedMatch[1];
50
+ try {
51
+ const resolvedValue = getCssVar(nestedVar, cssFiles);
52
+ if (resolvedValue) {
53
+ varCache.set(varName, resolvedValue);
54
+ return resolvedValue;
55
+ }
56
+ } catch (err) {
57
+ logger.warn(`Failed to resolve nested variable ${nestedVar}`);
58
+ }
59
+ }
60
+ }
61
+
62
+ if (lastValue) {
63
+ varCache.set(varName, lastValue);
64
+ return lastValue;
65
+ }
66
+ } catch (err) {
67
+ logger.warn(`Error processing CSS file ${cssPath}: ${err.message}`);
68
+ }
69
+ }
70
+
71
+ return null;
72
+ }