portosaurus 3.0.2 → 4.0.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/README.md +26 -126
- package/bin/portosaurus.mjs +8 -0
- package/package.json +6 -3
- package/src/assets/img/icon.png +0 -0
- package/src/assets/img/{icon.svg → svg/icon.svg} +35 -37
- package/src/assets/img/svg/project-blank.svg +140 -0
- package/src/assets/sample-resume.pdf +0 -0
- package/src/cli/build.mjs +2 -5
- package/src/cli/dev.mjs +27 -5
- package/src/cli/init.mjs +6 -12
- package/src/cli/schema.mjs +211 -0
- package/src/core/buildDocuConfig.mjs +305 -188
- package/src/core/constants.mjs +7 -1
- package/src/template/config.yml +150 -0
- package/src/template/notes/welcome.mdx +6 -0
- package/src/template/package.json +3 -3
- package/src/theme/MDXComponents.js +0 -1
- package/src/theme/components/AboutSection/index.js +32 -17
- package/src/theme/components/AboutSection/styles.module.css +151 -344
- package/src/theme/components/ContactSection/index.js +23 -14
- package/src/theme/components/ContactSection/styles.module.css +19 -8
- package/src/theme/components/ExperienceSection/index.js +12 -5
- package/src/theme/components/HeroSection/index.js +4 -3
- package/src/theme/components/HeroSection/styles.module.css +17 -16
- package/src/theme/components/NavArrow/index.js +114 -0
- package/src/theme/components/NavArrow/styles.module.css +107 -0
- package/src/theme/components/NoteIndex/index.js +66 -95
- package/src/theme/components/NoteIndex/styles.module.css +85 -89
- package/src/theme/components/Preview/components/FeedbackStates.js +3 -1
- package/src/theme/components/Preview/components/PreviewContent.js +91 -0
- package/src/theme/components/Preview/components/PreviewHeader.js +41 -33
- package/src/theme/components/Preview/components/Triggers/Pv.js +129 -72
- package/src/theme/components/Preview/components/ViewerWindow.js +198 -234
- package/src/theme/components/Preview/hooks/useAdaptiveSizing.js +115 -0
- package/src/theme/components/Preview/hooks/useDeepLinkHash.js +18 -23
- package/src/theme/components/Preview/hooks/useDockLayout.js +48 -8
- package/src/theme/components/Preview/hooks/useTouchZoom.js +118 -0
- package/src/theme/components/Preview/renderers/CodeRenderer.js +64 -25
- package/src/theme/components/Preview/state/index.js +70 -17
- package/src/theme/components/Preview/styles.module.css +181 -45
- package/src/theme/components/Preview/utils/index.js +11 -10
- package/src/theme/components/ProjectsSection/index.js +138 -148
- package/src/theme/components/ProjectsSection/styles.module.css +178 -112
- package/src/theme/components/SocialLinks/index.js +9 -7
- package/src/theme/components/Tooltip/index.js +31 -20
- package/src/theme/components/Tooltip/styles.module.css +101 -38
- package/src/theme/config/iconMappings.js +2 -0
- package/src/theme/css/custom.css +72 -0
- package/src/theme/hooks/useScrollReveal.js +30 -0
- package/src/theme/pages/index.js +7 -27
- package/src/theme/pages/notes.js +2 -2
- package/src/theme/pages/tasks.js +12 -11
- package/src/utils/cliUtils.mjs +23 -51
- package/src/utils/configUtils.mjs +95 -84
- package/src/utils/systemUtils.mjs +171 -0
- package/src/template/config.js +0 -68
- package/src/theme/components/ScrollToTop/index.js +0 -95
- package/src/theme/components/ScrollToTop/styles.module.css +0 -97
- package/src/theme/config/metaTags.js +0 -21
- /package/src/template/{.nojekyll → static/.nojekyll} +0 -0
|
@@ -1,206 +1,296 @@
|
|
|
1
1
|
import fs from "fs";
|
|
2
2
|
import path from "path";
|
|
3
|
-
import {
|
|
4
|
-
|
|
3
|
+
import { PortoRoot, Paths, PortoPkg } from "./constants.mjs";
|
|
4
|
+
import {
|
|
5
|
+
loadPkg,
|
|
6
|
+
getGitDate,
|
|
7
|
+
useEnabled,
|
|
8
|
+
getNestedValue,
|
|
9
|
+
} from "../utils/systemUtils.mjs";
|
|
5
10
|
import {
|
|
6
|
-
deepMerge,
|
|
7
11
|
resolveVars,
|
|
8
12
|
resolveSiteUrl,
|
|
9
13
|
resolveBasePath,
|
|
10
|
-
getVersion,
|
|
11
|
-
useEnabled,
|
|
12
14
|
createStaticAssetResolver,
|
|
15
|
+
buildHeadTags,
|
|
13
16
|
} from "../utils/configUtils.mjs";
|
|
14
|
-
import { PortoRoot } from "./constants.mjs";
|
|
15
|
-
|
|
16
|
-
// ─── Main Config Generator ─────────────────────────────────
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Creates a Docusaurus config from a user's Portosaurus config.
|
|
20
|
-
*
|
|
21
|
-
* @param {Object} rawUserConfig - The user's config object (export of config.js).
|
|
22
|
-
* May be { usrConf: {...} } or just {...}.
|
|
23
|
-
* @param {string} UserRoot - Absolute path to the user's project root.
|
|
24
|
-
* @returns {Object} Complete Docusaurus configuration object.
|
|
25
|
-
*/
|
|
26
|
-
export function buildDocuConfig(rawUserConfig, UserRoot) {
|
|
27
|
-
// Support both { usrConf: {...} } and direct config objects
|
|
28
|
-
const UserConfigRaw = rawUserConfig.usrConf ?? rawUserConfig;
|
|
29
|
-
|
|
30
|
-
// Load master template defaults for fallback resolution
|
|
31
|
-
const require = createRequire(import.meta.url);
|
|
32
|
-
const templateDefaults = require("../template/config.js").usrConf;
|
|
33
|
-
|
|
34
|
-
// Static directories — defined early so aliases can reference them
|
|
35
|
-
const UserStaticDir = path.resolve(UserRoot, "static");
|
|
36
|
-
const PortoAssetDir = path.resolve(PortoRoot, "src/assets");
|
|
37
|
-
|
|
38
|
-
// Hydrate the configuration by deep-merging user config over the template defaults.
|
|
39
|
-
// This ensures that even if the user deletes nested fields, the structure remains safe.
|
|
40
|
-
const merged = deepMerge(templateDefaults, UserConfigRaw);
|
|
41
|
-
|
|
42
|
-
// Find Docusaurus root for reference
|
|
43
|
-
let docuRoot = "";
|
|
44
|
-
try {
|
|
45
|
-
docuRoot = path.dirname(require.resolve("@docusaurus/core/package.json"));
|
|
46
|
-
} catch {
|
|
47
|
-
// If not found (e.g. during some build stages), fallback to node_modules relative to PortoRoot
|
|
48
|
-
docuRoot = path.resolve(PortoRoot, "node_modules/@docusaurus/core");
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// Resolve {{...}} template variables path prefixes in one pass
|
|
52
|
-
const UserConfig = resolveVars(merged, merged, {
|
|
53
|
-
siteRoot: UserRoot,
|
|
54
|
-
portoRoot: PortoRoot,
|
|
55
|
-
docuRoot: docuRoot,
|
|
56
|
-
});
|
|
57
17
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const
|
|
61
|
-
const version = getVersion();
|
|
62
|
-
|
|
63
|
-
const UserProjName = UserConfig.hero_section.title;
|
|
64
|
-
|
|
65
|
-
// Resolve internal paths
|
|
66
|
-
|
|
67
|
-
// Prism themes
|
|
68
|
-
let catppuccinMocha, catppuccinLatte;
|
|
69
|
-
try {
|
|
70
|
-
const prism = require(path.resolve(PortoRoot, "src/theme/config/prism.js"));
|
|
71
|
-
catppuccinMocha = prism.catppuccinMocha;
|
|
72
|
-
catppuccinLatte = prism.catppuccinLatte;
|
|
73
|
-
} catch {
|
|
74
|
-
catppuccinMocha = {};
|
|
75
|
-
catppuccinLatte = {};
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// Meta tags
|
|
79
|
-
let PortoMetaTags = [];
|
|
80
|
-
try {
|
|
81
|
-
const meta = require(
|
|
82
|
-
path.resolve(PortoRoot, "src/theme/config/metaTags.js"),
|
|
83
|
-
);
|
|
84
|
-
PortoMetaTags = meta.PortoMetaTags ?? meta.metaTags ?? [];
|
|
85
|
-
} catch {
|
|
86
|
-
// OK — no meta tags
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// Paths for content — these point directly to the user's project
|
|
90
|
-
const UserNotesDir = "notes";
|
|
91
|
-
const UserBlogDir = "blog";
|
|
18
|
+
export function buildDocuConfig(UserConfigRaw, UserRoot) {
|
|
19
|
+
// Get user Project Version
|
|
20
|
+
const usrProjectVer = loadPkg(UserRoot).version || "0.0.0";
|
|
92
21
|
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
);
|
|
22
|
+
const portoVersion = PortoPkg.version || "0.0.0";
|
|
23
|
+
const portoRepo = (PortoPkg.repository?.url || "").replace(/\.git$/, "");
|
|
24
|
+
const lastUpdated = getGitDate(UserRoot);
|
|
97
25
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Validates a static asset path with fallback.
|
|
106
|
-
* - Remote URLs (http/https) pass through as-is.
|
|
107
|
-
* - Local paths are checked against UserStaticDir, then PortoAssetDir.
|
|
108
|
-
*/
|
|
26
|
+
// Static directories
|
|
27
|
+
const UserStaticDir = path.resolve(UserRoot, "static");
|
|
28
|
+
const PortoAssetDir = Paths.assets;
|
|
29
|
+
|
|
30
|
+
// Resolve static asset path with fallback
|
|
109
31
|
const resolveStaticAsset = createStaticAssetResolver(
|
|
32
|
+
UserRoot,
|
|
110
33
|
UserStaticDir,
|
|
111
34
|
PortoAssetDir,
|
|
112
35
|
);
|
|
113
36
|
|
|
114
|
-
//
|
|
115
|
-
const
|
|
37
|
+
// Resolve SiteURL and BasePath for Docusaurus Root
|
|
38
|
+
const usrSiteUrl = resolveSiteUrl(UserConfigRaw.site?.url || "auto");
|
|
39
|
+
const ursSitePath = resolveBasePath(UserConfigRaw.site?.path || "auto");
|
|
116
40
|
|
|
117
|
-
//
|
|
118
|
-
const
|
|
41
|
+
// Resolve {{...}} template variables in user config
|
|
42
|
+
const UserConfig = resolveVars(UserConfigRaw, UserConfigRaw, {
|
|
43
|
+
siteRoot: UserRoot,
|
|
44
|
+
portoRoot: PortoRoot,
|
|
45
|
+
compileYear: new Date().getFullYear(),
|
|
46
|
+
compileDate: new Date().toLocaleDateString(),
|
|
47
|
+
portoVersion,
|
|
48
|
+
projectVersion: usrProjectVer,
|
|
49
|
+
siteUrl: usrSiteUrl,
|
|
50
|
+
baseUrl: ursSitePath,
|
|
51
|
+
lastUpdated,
|
|
52
|
+
isProd: process.env.NODE_ENV === "production",
|
|
53
|
+
isDev: process.env.NODE_ENV === "development",
|
|
54
|
+
nodeEnv: process.env.NODE_ENV || "development",
|
|
55
|
+
custom: UserConfigRaw.custom || {},
|
|
56
|
+
});
|
|
119
57
|
|
|
120
|
-
//
|
|
121
|
-
const
|
|
58
|
+
// Helper to get nested values with fallbacks
|
|
59
|
+
const get = (...args) => getNestedValue(UserConfig, ...args);
|
|
122
60
|
|
|
123
|
-
//
|
|
124
|
-
const PortoCustomCss = path.resolve(PortoRoot, "src/theme/css/custom.css");
|
|
61
|
+
// ─────────────────────── Build the Docusaurus config ───────────────────────
|
|
125
62
|
|
|
126
|
-
|
|
63
|
+
/** The primary title of your website (e.g., your name or brand) */
|
|
64
|
+
const siteName = get("site.title", "Your Name");
|
|
65
|
+
const siteUrl = usrSiteUrl;
|
|
66
|
+
const sitePath = ursSitePath;
|
|
67
|
+
|
|
68
|
+
const UserNotesDir = "notes";
|
|
69
|
+
const UserBlogDir = "blog";
|
|
70
|
+
const UserTasksDir = "tasks";
|
|
127
71
|
|
|
128
72
|
const config = {
|
|
129
|
-
projectName:
|
|
130
|
-
title:
|
|
131
|
-
|
|
73
|
+
projectName: siteName,
|
|
74
|
+
title: siteName,
|
|
75
|
+
|
|
76
|
+
/** A short, catchy description shown below the title on the home page */
|
|
77
|
+
tagline: get(
|
|
78
|
+
"site.tagline",
|
|
79
|
+
"Short description about you, your passion, your goals etc.",
|
|
80
|
+
),
|
|
81
|
+
|
|
82
|
+
url: siteUrl,
|
|
83
|
+
baseUrl: sitePath,
|
|
84
|
+
|
|
85
|
+
// Checks user's given favicon path -> internal favicon/favicon.ico -> img/icon.png
|
|
132
86
|
favicon: resolveStaticAsset(
|
|
133
|
-
|
|
87
|
+
get("site.favicon", ""),
|
|
134
88
|
resolveStaticAsset("favicon/favicon.ico", "img/icon.png"),
|
|
135
89
|
),
|
|
136
|
-
url: siteUrl,
|
|
137
|
-
baseUrl: basePath,
|
|
138
90
|
|
|
139
|
-
organizationName:
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
91
|
+
organizationName: siteName,
|
|
92
|
+
|
|
93
|
+
/** Behavior when a broken anchor link is found (throw, warn, ignore) */
|
|
94
|
+
onBrokenAnchors: get("site.on_broken_anchors", "throw"),
|
|
95
|
+
|
|
96
|
+
/** Behavior when a broken internal link is found (throw, warn, ignore) */
|
|
97
|
+
onBrokenLinks: get("site.on_broken_links", "throw"),
|
|
143
98
|
|
|
99
|
+
// TODO: research & allow to configure this
|
|
144
100
|
i18n: {
|
|
145
101
|
defaultLocale: "en",
|
|
146
102
|
locales: ["en"],
|
|
147
103
|
},
|
|
148
104
|
|
|
149
|
-
headTags:
|
|
105
|
+
headTags: buildHeadTags([
|
|
106
|
+
{
|
|
107
|
+
meta: {
|
|
108
|
+
name: "msapplication-TileColor",
|
|
109
|
+
content: "var(--ifm-background-color)",
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
meta: {
|
|
114
|
+
name: "theme-color",
|
|
115
|
+
content: "var(--ifm-background-color)",
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
...get("site.head_tags", []),
|
|
119
|
+
]),
|
|
150
120
|
|
|
151
121
|
customFields: {
|
|
152
|
-
|
|
122
|
+
portoVersion,
|
|
123
|
+
|
|
124
|
+
corsProxyList: [
|
|
125
|
+
...[].concat(get("site.cors_proxy", [])),
|
|
126
|
+
"https://cors-proxy.soymadip.workers.dev/?url=",
|
|
127
|
+
"https://api.allorigins.win/raw?url=",
|
|
128
|
+
].filter(Boolean),
|
|
153
129
|
|
|
154
130
|
heroSection: {
|
|
155
131
|
profilePic: resolveStaticAsset(
|
|
156
|
-
|
|
132
|
+
get("home_page.hero.profile_pic", "site.favicon", ""),
|
|
157
133
|
"img/icon.png",
|
|
158
134
|
),
|
|
159
|
-
intro:
|
|
160
|
-
title:
|
|
161
|
-
subtitle:
|
|
162
|
-
profession:
|
|
163
|
-
|
|
164
|
-
|
|
135
|
+
intro: get("home_page.hero.intro", "Hello there, I'm"),
|
|
136
|
+
title: get("home_page.hero.title", "site.title", "Your Name"),
|
|
137
|
+
subtitle: get("home_page.hero.subtitle", "I am a"),
|
|
138
|
+
profession: get("home_page.hero.profession", "Your Profession"),
|
|
139
|
+
desc: get(
|
|
140
|
+
"home_page.hero.desc",
|
|
141
|
+
"site.tagline",
|
|
142
|
+
"Welcome to my portfolio.",
|
|
143
|
+
),
|
|
144
|
+
learnMoreButtonTxt: get(
|
|
145
|
+
"home_page.hero.learn_more_btn_txt",
|
|
146
|
+
"Learn More",
|
|
147
|
+
),
|
|
148
|
+
social: get("home_page.hero.social", null),
|
|
165
149
|
},
|
|
166
150
|
|
|
167
151
|
aboutMe: {
|
|
168
|
-
|
|
152
|
+
/** Enable or disable the About Me section entirely */
|
|
153
|
+
enable: get("home_page.about.enable", true),
|
|
154
|
+
|
|
155
|
+
/** Heading text for the About section */
|
|
156
|
+
heading: get("home_page.about.heading", "About Me"),
|
|
157
|
+
|
|
158
|
+
/** The main image for the About section */
|
|
169
159
|
image: resolveStaticAsset(
|
|
170
|
-
|
|
160
|
+
get(
|
|
161
|
+
"home_page.about.image",
|
|
162
|
+
"home_page.hero.profile_pic",
|
|
163
|
+
"site.favicon",
|
|
164
|
+
"",
|
|
165
|
+
),
|
|
171
166
|
"img/icon.png",
|
|
172
167
|
),
|
|
173
|
-
description
|
|
174
|
-
|
|
175
|
-
|
|
168
|
+
/** A detailed bio or description about yourself (Array of strings for paragraphs) */
|
|
169
|
+
bio: get("home_page.about.bio", [
|
|
170
|
+
"I am a developer who loves turning ideas into reality.",
|
|
171
|
+
"With background in computer science and a passion for design, I bridge the gap between aesthetics and functionality.",
|
|
172
|
+
"Driven by curiosity and a commitment to excellence.",
|
|
173
|
+
]),
|
|
174
|
+
|
|
175
|
+
/** A list of your professional skills or technologies */
|
|
176
|
+
skills: get("home_page.about.skills", [
|
|
177
|
+
"skill1",
|
|
178
|
+
"skill2",
|
|
179
|
+
"skill3",
|
|
180
|
+
"skill4",
|
|
181
|
+
]),
|
|
182
|
+
/** The title shown above the skills list */
|
|
183
|
+
skillsHeading: get("home_page.about.skills_heading", "My Skills"),
|
|
184
|
+
/** Path to your professional resume (PDF or external link) */
|
|
185
|
+
resume: resolveStaticAsset(get("home_page.about.resume", null), null),
|
|
186
|
+
},
|
|
187
|
+
|
|
188
|
+
projects: {
|
|
189
|
+
/** Enable or disable the Projects section */
|
|
190
|
+
enable: get("home_page.project_shelf.enable", true),
|
|
191
|
+
|
|
192
|
+
/** Heading for the projects section */
|
|
193
|
+
heading: get("home_page.project_shelf.heading", "My Projects"),
|
|
194
|
+
|
|
195
|
+
/** Sub-heading or description for your project shelf */
|
|
196
|
+
subheading: get(
|
|
197
|
+
"home_page.project_shelf.subheading",
|
|
198
|
+
"A collection of all my works, with featured projects highlighted",
|
|
199
|
+
),
|
|
200
|
+
/** Enable automatic scrolling for the project cards */
|
|
201
|
+
autoplay: get("home_page.project_shelf.autoplay", true),
|
|
202
|
+
|
|
203
|
+
/** The list of projects to display (Array of project objects) */
|
|
204
|
+
projects: get("home_page.project_shelf.projects", [
|
|
205
|
+
{
|
|
206
|
+
title: "Project One",
|
|
207
|
+
desc: "A brief description of your project and the tech used.",
|
|
208
|
+
tags: ["React", "Portosaurus"],
|
|
209
|
+
state: "active",
|
|
210
|
+
website: "https://example.com",
|
|
211
|
+
repo: "https://github.com/",
|
|
212
|
+
demo: "https://example.com/demo",
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
title: "Project Two",
|
|
216
|
+
icon: PortoRoot + "/img/icon.png",
|
|
217
|
+
featured: true,
|
|
218
|
+
desc: "Another awesome project you've built recently.",
|
|
219
|
+
tags: ["python", "tag2"],
|
|
220
|
+
state: "completed",
|
|
221
|
+
website: "https://example.com",
|
|
222
|
+
repo: "https://github.com/",
|
|
223
|
+
},
|
|
224
|
+
]).map((p) => ({
|
|
225
|
+
...p,
|
|
226
|
+
icon: resolveStaticAsset(p.icon, ""),
|
|
227
|
+
})),
|
|
176
228
|
},
|
|
177
229
|
|
|
178
|
-
|
|
179
|
-
experience:
|
|
230
|
+
// TODO
|
|
231
|
+
experience: {
|
|
232
|
+
/** Enable or disable the Experience timeline */
|
|
233
|
+
enable: get("home_page.experience.enable", false),
|
|
234
|
+
|
|
235
|
+
/** Heading for the experience section */
|
|
236
|
+
heading: get("home_page.experience.heading", "Experience"),
|
|
237
|
+
|
|
238
|
+
/** Sub-heading for your professional journey */
|
|
239
|
+
subheading: get(
|
|
240
|
+
"home_page.experience.subheading",
|
|
241
|
+
"My professional journey and work experience",
|
|
242
|
+
),
|
|
243
|
+
/** List of work history items */
|
|
244
|
+
list: get("home_page.experience.list", []),
|
|
245
|
+
},
|
|
180
246
|
|
|
181
247
|
socialLinks: {
|
|
182
|
-
|
|
183
|
-
|
|
248
|
+
/** Enable or disable the Social Links / Contact section */
|
|
249
|
+
enable: get("home_page.social.enable", true),
|
|
250
|
+
|
|
251
|
+
/** Heading for the contact section */
|
|
252
|
+
heading: get("home_page.social.heading", "Get In Touch"),
|
|
253
|
+
|
|
254
|
+
/** Brief call-to-action or invitation to contact you */
|
|
255
|
+
subheading: get(
|
|
256
|
+
"home_page.social.subheading",
|
|
257
|
+
"Feel free to reach out for collaborations, questions, or just to say hello!",
|
|
258
|
+
),
|
|
259
|
+
/** List of social media profiles and contact methods */
|
|
260
|
+
links: get("home_page.social.links", [
|
|
261
|
+
{
|
|
262
|
+
name: "Email",
|
|
263
|
+
desc: "Send me an email",
|
|
264
|
+
url: "mailto://you@yourdomain.com",
|
|
265
|
+
},
|
|
266
|
+
{
|
|
267
|
+
name: "LinkedIn",
|
|
268
|
+
desc: "Connect on LinkedIn",
|
|
269
|
+
url: "https://www.linkedin.com/in/yourusername",
|
|
270
|
+
},
|
|
271
|
+
]),
|
|
184
272
|
},
|
|
185
273
|
|
|
186
274
|
robotsTxt: {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
275
|
+
/** Enable generation of robots.txt file */
|
|
276
|
+
enable: get("site.robots_txt.enable", true),
|
|
277
|
+
rules: [{ disallow: [`/${UserNotesDir}/`, `/${UserTasksDir}/`] }],
|
|
278
|
+
|
|
279
|
+
/** Additional custom lines to add to robots.txt */
|
|
280
|
+
customLines: get("site.robots_txt.custom_lines", []),
|
|
190
281
|
},
|
|
191
282
|
|
|
192
283
|
tasksPage: {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
description: UserConfig.tasks_page.description,
|
|
196
|
-
taskList: UserConfig.tasks_page.tasks,
|
|
197
|
-
},
|
|
284
|
+
/** Enable or disable the Tasks/TODO page */
|
|
285
|
+
enable: get("tasks.enable", false),
|
|
198
286
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
287
|
+
/** Title for the Tasks page */
|
|
288
|
+
title: get("tasks.title", "Tasks"),
|
|
289
|
+
|
|
290
|
+
/** Subtitle for the Tasks page */
|
|
291
|
+
subtitle: get("tasks.subtitle", "My current focus and todo list"),
|
|
292
|
+
taskList: get("tasks.list", []),
|
|
293
|
+
},
|
|
204
294
|
},
|
|
205
295
|
|
|
206
296
|
presets: [
|
|
@@ -210,24 +300,24 @@ export function buildDocuConfig(rawUserConfig, UserRoot) {
|
|
|
210
300
|
}),
|
|
211
301
|
{
|
|
212
302
|
docs: {
|
|
213
|
-
routeBasePath:
|
|
303
|
+
routeBasePath: UserNotesDir,
|
|
214
304
|
path: UserNotesDir,
|
|
215
|
-
sidebarPath,
|
|
305
|
+
sidebarPath: path.resolve(PortoRoot, "src/theme/config/sidebar.js"),
|
|
216
306
|
admonitions: {
|
|
217
|
-
keywords: [
|
|
218
|
-
"note",
|
|
219
|
-
"tip",
|
|
220
|
-
"info",
|
|
221
|
-
"warning",
|
|
222
|
-
"danger",
|
|
223
|
-
"question",
|
|
224
|
-
],
|
|
225
307
|
extendDefaults: true,
|
|
308
|
+
// keywords: [
|
|
309
|
+
// "note",
|
|
310
|
+
// "tip",
|
|
311
|
+
// "info",
|
|
312
|
+
// "warning",
|
|
313
|
+
// "danger",
|
|
314
|
+
// "question",
|
|
315
|
+
// ],
|
|
226
316
|
},
|
|
227
317
|
},
|
|
228
318
|
blog: {
|
|
229
319
|
path: UserBlogDir,
|
|
230
|
-
feedOptions:
|
|
320
|
+
feedOptions: get("site.rss", true)
|
|
231
321
|
? { type: ["rss", "atom"], xslt: true }
|
|
232
322
|
: undefined,
|
|
233
323
|
showReadingTime: false,
|
|
@@ -236,10 +326,10 @@ export function buildDocuConfig(rawUserConfig, UserRoot) {
|
|
|
236
326
|
onUntruncatedBlogPosts: "warn",
|
|
237
327
|
},
|
|
238
328
|
theme: {
|
|
239
|
-
customCss:
|
|
329
|
+
customCss: path.resolve(PortoRoot, "src/theme/css/custom.css"),
|
|
240
330
|
},
|
|
241
331
|
pages: {
|
|
242
|
-
path:
|
|
332
|
+
path: path.resolve(PortoRoot, "src/theme/pages"),
|
|
243
333
|
},
|
|
244
334
|
},
|
|
245
335
|
],
|
|
@@ -251,44 +341,51 @@ export function buildDocuConfig(rawUserConfig, UserRoot) {
|
|
|
251
341
|
[
|
|
252
342
|
path.resolve(PortoRoot, "src/plugins/theme.mjs"),
|
|
253
343
|
{
|
|
254
|
-
themeDir:
|
|
344
|
+
themeDir: path.resolve(PortoRoot, "src/theme"),
|
|
255
345
|
},
|
|
256
346
|
],
|
|
257
347
|
],
|
|
258
348
|
|
|
259
349
|
markdown: {
|
|
260
|
-
mermaid: true,
|
|
350
|
+
mermaid: get("theme.markdown.mermaid", true),
|
|
261
351
|
hooks: {
|
|
262
|
-
onBrokenMarkdownLinks: "
|
|
352
|
+
onBrokenMarkdownLinks: get("theme.markdown.on_broken_links", "throw"),
|
|
353
|
+
onBrokenMarkdownImages: get("theme.markdown.on_broken_images", "throw"),
|
|
263
354
|
},
|
|
264
355
|
},
|
|
265
356
|
|
|
266
357
|
themeConfig: {
|
|
267
|
-
image: resolveStaticAsset(
|
|
358
|
+
image: resolveStaticAsset(
|
|
359
|
+
get("site.social_card", ""),
|
|
360
|
+
"img/social-card.jpeg",
|
|
361
|
+
),
|
|
362
|
+
|
|
268
363
|
docs: {
|
|
269
364
|
sidebar: {
|
|
270
|
-
hideable:
|
|
365
|
+
hideable: get("theme.navigation.collapsable_sidebar", true),
|
|
271
366
|
},
|
|
272
367
|
},
|
|
368
|
+
|
|
273
369
|
imageZoom: {
|
|
274
370
|
options: {
|
|
275
371
|
margin: 2,
|
|
276
372
|
background: "rgba(var(--ifm-background-color-rgb), 0.9)",
|
|
277
373
|
},
|
|
278
374
|
},
|
|
375
|
+
|
|
279
376
|
colorMode: {
|
|
280
|
-
defaultMode:
|
|
281
|
-
disableSwitch:
|
|
377
|
+
defaultMode: get("theme.appearance.dark_mode", true) ? "dark" : "light",
|
|
378
|
+
disableSwitch: get("theme.appearance.disable_switch", false),
|
|
282
379
|
},
|
|
283
380
|
navbar: {
|
|
284
|
-
title:
|
|
285
|
-
hideOnScroll:
|
|
381
|
+
title: get("site.title", "Your Portfolio"),
|
|
382
|
+
hideOnScroll: get("theme.navigation.hide_navbar_on_scroll", true),
|
|
286
383
|
logo: {
|
|
287
384
|
alt: "Site Logo",
|
|
288
385
|
src: resolveStaticAsset(
|
|
289
|
-
|
|
386
|
+
get("site.favicon", ""),
|
|
290
387
|
resolveStaticAsset(
|
|
291
|
-
|
|
388
|
+
get("home_page.hero.profile_pic", ""),
|
|
292
389
|
"img/icon.png",
|
|
293
390
|
),
|
|
294
391
|
),
|
|
@@ -300,7 +397,7 @@ export function buildDocuConfig(rawUserConfig, UserRoot) {
|
|
|
300
397
|
className: "navbar-search-bar",
|
|
301
398
|
},
|
|
302
399
|
{
|
|
303
|
-
enable:
|
|
400
|
+
enable: get("home_page.about.enable", true),
|
|
304
401
|
value: {
|
|
305
402
|
label: "About Me",
|
|
306
403
|
to: "/#about",
|
|
@@ -309,7 +406,7 @@ export function buildDocuConfig(rawUserConfig, UserRoot) {
|
|
|
309
406
|
},
|
|
310
407
|
},
|
|
311
408
|
{
|
|
312
|
-
enable:
|
|
409
|
+
enable: get("home_page.project_shelf.enable", true),
|
|
313
410
|
value: {
|
|
314
411
|
label: "Projects",
|
|
315
412
|
to: "/#projects",
|
|
@@ -318,7 +415,7 @@ export function buildDocuConfig(rawUserConfig, UserRoot) {
|
|
|
318
415
|
},
|
|
319
416
|
},
|
|
320
417
|
{
|
|
321
|
-
enable:
|
|
418
|
+
enable: get("home_page.experience.enable", false),
|
|
322
419
|
value: {
|
|
323
420
|
label: "Experience",
|
|
324
421
|
to: "/#experience",
|
|
@@ -327,7 +424,7 @@ export function buildDocuConfig(rawUserConfig, UserRoot) {
|
|
|
327
424
|
},
|
|
328
425
|
},
|
|
329
426
|
{
|
|
330
|
-
enable:
|
|
427
|
+
enable: get("home_page.social.enable", true),
|
|
331
428
|
value: {
|
|
332
429
|
label: "Contact",
|
|
333
430
|
to: "/#contact",
|
|
@@ -341,18 +438,20 @@ export function buildDocuConfig(rawUserConfig, UserRoot) {
|
|
|
341
438
|
position: "right",
|
|
342
439
|
className: "_navbar-more-items",
|
|
343
440
|
items: useEnabled([
|
|
344
|
-
{ label: "Notes", to:
|
|
345
|
-
{ label: "Blog", to:
|
|
441
|
+
{ label: "Notes", to: `/${UserNotesDir}` },
|
|
442
|
+
{ label: "Blog", to: `/${UserBlogDir}` },
|
|
346
443
|
{
|
|
347
|
-
|
|
348
|
-
|
|
444
|
+
/** Toggle the Tasks page visibility */
|
|
445
|
+
enable: get("home_page.tasks.enable", false),
|
|
446
|
+
value: { label: "Tasks", to: `/${UserTasksDir}` },
|
|
349
447
|
},
|
|
350
448
|
{
|
|
351
|
-
|
|
449
|
+
/** Hide the 'Powered by Portosaurus' branding in the menu */
|
|
450
|
+
enable: !get("theme.appearance.disable_branding", false),
|
|
352
451
|
value: {
|
|
353
|
-
label: `Portosaurus v${
|
|
452
|
+
label: `Portosaurus v${portoVersion}`,
|
|
354
453
|
className: "_nav-protosaurus-version",
|
|
355
|
-
to:
|
|
454
|
+
to: portoRepo,
|
|
356
455
|
},
|
|
357
456
|
},
|
|
358
457
|
]),
|
|
@@ -364,9 +463,23 @@ export function buildDocuConfig(rawUserConfig, UserRoot) {
|
|
|
364
463
|
maxHeadingLevel: 4,
|
|
365
464
|
},
|
|
366
465
|
prism: {
|
|
367
|
-
theme:
|
|
368
|
-
|
|
369
|
-
|
|
466
|
+
theme: (function () {
|
|
467
|
+
try {
|
|
468
|
+
return require(path.resolve(PortoRoot, "src/theme/config/prism.js"))
|
|
469
|
+
.catppuccinLatte;
|
|
470
|
+
} catch {
|
|
471
|
+
return {};
|
|
472
|
+
}
|
|
473
|
+
})(),
|
|
474
|
+
darkTheme: (function () {
|
|
475
|
+
try {
|
|
476
|
+
return require(path.resolve(PortoRoot, "src/theme/config/prism.js"))
|
|
477
|
+
.catppuccinMocha;
|
|
478
|
+
} catch {
|
|
479
|
+
return {};
|
|
480
|
+
}
|
|
481
|
+
})(),
|
|
482
|
+
additionalLanguages: ["java", "php", "bash", "diff"],
|
|
370
483
|
},
|
|
371
484
|
footer: {},
|
|
372
485
|
},
|
|
@@ -410,8 +523,8 @@ export function buildDocuConfig(rawUserConfig, UserRoot) {
|
|
|
410
523
|
hashed: true,
|
|
411
524
|
indexDocs: true,
|
|
412
525
|
docsDir: UserNotesDir,
|
|
413
|
-
docsRouteBasePath:
|
|
414
|
-
searchContextByPaths: [
|
|
526
|
+
docsRouteBasePath: UserNotesDir,
|
|
527
|
+
searchContextByPaths: [UserNotesDir, UserBlogDir],
|
|
415
528
|
highlightSearchTermsOnTargetPage: true,
|
|
416
529
|
explicitSearchResultPath: true,
|
|
417
530
|
hideSearchBarWithNoSearchContext: true,
|
|
@@ -421,7 +534,11 @@ export function buildDocuConfig(rawUserConfig, UserRoot) {
|
|
|
421
534
|
"plugin-image-zoom",
|
|
422
535
|
],
|
|
423
536
|
|
|
424
|
-
staticDirectories:
|
|
537
|
+
staticDirectories: [
|
|
538
|
+
UserStaticDir,
|
|
539
|
+
PortoAssetDir,
|
|
540
|
+
path.resolve(UserRoot, ".docusaurus/portosaurus/favicon"),
|
|
541
|
+
].filter((d) => fs.existsSync(d)),
|
|
425
542
|
};
|
|
426
543
|
|
|
427
544
|
return config;
|