methanol 0.0.8 → 0.0.9
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 +2 -1
- package/src/build-system.js +7 -1
- package/src/config.js +16 -4
- package/src/dev-server.js +2 -0
- package/src/logger.js +80 -0
- package/src/main.js +7 -0
- package/src/mdx.js +12 -1
- package/src/pagefind.js +16 -5
- package/src/stage-logger.js +7 -4
- package/src/state.js +17 -3
- package/themes/default/sources/style.css +189 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "methanol",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.9",
|
|
4
4
|
"description": "Static site generator powered by rEFui and MDX",
|
|
5
5
|
"main": "./index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
"refurbish": "^0.1.8",
|
|
40
40
|
"rehype-slug": "^6.0.0",
|
|
41
41
|
"rehype-starry-night": "^2.2.0",
|
|
42
|
+
"remark-gfm": "^4.0.1",
|
|
42
43
|
"unist-util-visit": "^5.0.0",
|
|
43
44
|
"vite": "^7.3.0",
|
|
44
45
|
"yargs": "^18.0.0"
|
package/src/build-system.js
CHANGED
|
@@ -67,7 +67,7 @@ export const buildHtmlEntries = async () => {
|
|
|
67
67
|
await ensureDir(state.INTERMEDIATE_DIR)
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
const logEnabled = state.CURRENT_MODE === 'production' && cli.command === 'build'
|
|
70
|
+
const logEnabled = state.CURRENT_MODE === 'production' && cli.command === 'build' && !cli.CLI_VERBOSE
|
|
71
71
|
const stageLogger = createStageLogger(logEnabled)
|
|
72
72
|
const themeComponentsDir = state.THEME_COMPONENTS_DIR
|
|
73
73
|
const themeEnv = state.THEME_ENV
|
|
@@ -164,6 +164,10 @@ export const buildHtmlEntries = async () => {
|
|
|
164
164
|
}
|
|
165
165
|
|
|
166
166
|
export const runViteBuild = async (entry, htmlCache) => {
|
|
167
|
+
const logEnabled = state.CURRENT_MODE === 'production' && cli.command === 'build' && !cli.CLI_VERBOSE
|
|
168
|
+
const stageLogger = createStageLogger(logEnabled)
|
|
169
|
+
const token = stageLogger.start('Building bundle')
|
|
170
|
+
|
|
167
171
|
if (state.STATIC_DIR !== false && state.MERGED_ASSETS_DIR) {
|
|
168
172
|
await preparePublicAssets({
|
|
169
173
|
themeDir: state.THEME_ASSETS_DIR,
|
|
@@ -177,6 +181,7 @@ export const runViteBuild = async (entry, htmlCache) => {
|
|
|
177
181
|
root: state.PAGES_DIR,
|
|
178
182
|
appType: 'mpa',
|
|
179
183
|
publicDir: state.STATIC_DIR === false ? false : state.STATIC_DIR,
|
|
184
|
+
logLevel: cli.CLI_VERBOSE ? 'info' : 'silent',
|
|
180
185
|
build: {
|
|
181
186
|
outDir: state.DIST_DIR,
|
|
182
187
|
emptyOutDir: true,
|
|
@@ -198,4 +203,5 @@ export const runViteBuild = async (entry, htmlCache) => {
|
|
|
198
203
|
const userConfig = await resolveUserViteConfig('build')
|
|
199
204
|
const finalConfig = userConfig ? mergeConfig(baseConfig, userConfig) : baseConfig
|
|
200
205
|
await viteBuild(finalConfig)
|
|
206
|
+
stageLogger.end(token)
|
|
201
207
|
}
|
package/src/config.js
CHANGED
|
@@ -24,6 +24,7 @@ import { resolve, isAbsolute, extname, basename } from 'path'
|
|
|
24
24
|
import { pathToFileURL } from 'url'
|
|
25
25
|
import { mergeConfig } from 'vite'
|
|
26
26
|
import { cli, state } from './state.js'
|
|
27
|
+
import { logger } from './logger.js'
|
|
27
28
|
import { HTMLRenderer } from './renderer.js'
|
|
28
29
|
import { rewindEnv } from './components.js'
|
|
29
30
|
import { env as createEnv } from './rewind.js'
|
|
@@ -123,7 +124,7 @@ const warnDevBase = (value) => {
|
|
|
123
124
|
if (devBaseWarningShown) return
|
|
124
125
|
devBaseWarningShown = true
|
|
125
126
|
const label = value ? ` (received "${value}")` : ''
|
|
126
|
-
|
|
127
|
+
logger.warn(`Methanol: \`base\`${label} is disabled in dev mode due to module resolution inconsistencies in Vite. Using "/".\n`)
|
|
127
128
|
}
|
|
128
129
|
|
|
129
130
|
const hasOwn = (obj, key) => Object.prototype.hasOwnProperty.call(obj || {}, key)
|
|
@@ -264,7 +265,7 @@ export const applyConfig = async (config, mode) => {
|
|
|
264
265
|
const configSiteName = cli.CLI_SITE_NAME ?? config.site?.name ?? null
|
|
265
266
|
state.SITE_NAME = configSiteName || basename(root) || 'Methanol Site'
|
|
266
267
|
const userSite = config.site && typeof config.site === 'object' ? { ...config.site } : null
|
|
267
|
-
const siteBase = normalizeSiteBase(userSite?.base)
|
|
268
|
+
const siteBase = normalizeSiteBase(cli.CLI_BASE || userSite?.base)
|
|
268
269
|
state.SITE_BASE = siteBase
|
|
269
270
|
if (userSite) {
|
|
270
271
|
if (siteBase == null) {
|
|
@@ -392,6 +393,9 @@ export const applyConfig = async (config, mode) => {
|
|
|
392
393
|
state.THEME_POST_BUILD_HOOKS = normalizeHooks(state.USER_THEME?.postBuild)
|
|
393
394
|
state.THEME_PRE_BUNDLE_HOOKS = normalizeHooks(state.USER_THEME?.preBundle)
|
|
394
395
|
state.THEME_POST_BUNDLE_HOOKS = normalizeHooks(state.USER_THEME?.postBundle)
|
|
396
|
+
if (hasOwn(config, 'gfm')) {
|
|
397
|
+
state.GFM_ENABLED = config.gfm !== false
|
|
398
|
+
}
|
|
395
399
|
const starryNight = resolveStarryNightConfig(config.starryNight)
|
|
396
400
|
const cliCodeHighlighting = cli.CLI_CODE_HIGHLIGHTING
|
|
397
401
|
if (cliCodeHighlighting != null) {
|
|
@@ -448,6 +452,7 @@ export const resolveUserViteConfig = async (command) => {
|
|
|
448
452
|
if (state.RESOLVED_VITE_CONFIG !== undefined) {
|
|
449
453
|
return state.RESOLVED_VITE_CONFIG
|
|
450
454
|
}
|
|
455
|
+
|
|
451
456
|
const resolveConfig = async (config) => {
|
|
452
457
|
if (!config) return null
|
|
453
458
|
if (typeof config === 'function') {
|
|
@@ -463,9 +468,10 @@ export const resolveUserViteConfig = async (command) => {
|
|
|
463
468
|
}
|
|
464
469
|
return config || null
|
|
465
470
|
}
|
|
471
|
+
|
|
466
472
|
const themeConfig = await resolveConfig(state.USER_THEME.vite)
|
|
467
473
|
const userConfig = await resolveConfig(state.USER_VITE_CONFIG)
|
|
468
|
-
|
|
474
|
+
|
|
469
475
|
if (!themeConfig && !userConfig) {
|
|
470
476
|
if (state.SITE_BASE) {
|
|
471
477
|
state.RESOLVED_VITE_CONFIG = { base: state.SITE_BASE }
|
|
@@ -484,15 +490,20 @@ export const resolveUserViteConfig = async (command) => {
|
|
|
484
490
|
}
|
|
485
491
|
return state.RESOLVED_VITE_CONFIG
|
|
486
492
|
}
|
|
493
|
+
|
|
487
494
|
state.RESOLVED_VITE_CONFIG = themeConfig
|
|
488
495
|
? userConfig
|
|
489
496
|
? mergeConfig(themeConfig, userConfig)
|
|
490
497
|
: themeConfig
|
|
491
498
|
: userConfig
|
|
492
|
-
|
|
499
|
+
|
|
500
|
+
const userHasBase = userConfig && hasOwn(userConfig, 'base')
|
|
501
|
+
if (state.SITE_BASE && (cli.CLI_BASE || !userHasBase)) {
|
|
493
502
|
state.RESOLVED_VITE_CONFIG.base = state.SITE_BASE
|
|
494
503
|
}
|
|
504
|
+
|
|
495
505
|
state.VITE_BASE = normalizeViteBase(state.RESOLVED_VITE_CONFIG?.base || state.SITE_BASE || '/')
|
|
506
|
+
|
|
496
507
|
if (command === 'serve') {
|
|
497
508
|
if (state.VITE_BASE !== '/' || (state.SITE_BASE && state.SITE_BASE !== '/')) {
|
|
498
509
|
warnDevBase(state.RESOLVED_VITE_CONFIG?.base || state.SITE_BASE || '')
|
|
@@ -500,6 +511,7 @@ export const resolveUserViteConfig = async (command) => {
|
|
|
500
511
|
state.RESOLVED_VITE_CONFIG.base = '/'
|
|
501
512
|
state.VITE_BASE = '/'
|
|
502
513
|
}
|
|
514
|
+
|
|
503
515
|
return state.RESOLVED_VITE_CONFIG
|
|
504
516
|
}
|
|
505
517
|
|
package/src/dev-server.js
CHANGED
package/src/logger.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/* Copyright Yukino Song, SudoMaker Ltd.
|
|
2
|
+
*
|
|
3
|
+
* Licensed to the Apache Software Foundation (ASF) under one
|
|
4
|
+
* or more contributor license agreements. See the NOTICE file
|
|
5
|
+
* distributed with this work for additional information
|
|
6
|
+
* regarding copyright ownership. The ASF licenses this file
|
|
7
|
+
* to you under the Apache License, Version 2.0 (the
|
|
8
|
+
* "License"); you may not use this file except in compliance
|
|
9
|
+
* with the License. You may obtain a copy of the License at
|
|
10
|
+
*
|
|
11
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
12
|
+
*
|
|
13
|
+
* Unless required by applicable law or agreed to in writing,
|
|
14
|
+
* software distributed under the License is distributed on an
|
|
15
|
+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
16
|
+
* KIND, either express or implied. See the License for the
|
|
17
|
+
* specific language governing permissions and limitations
|
|
18
|
+
* under the License.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
const supportColor =
|
|
22
|
+
typeof process !== 'undefined' &&
|
|
23
|
+
process.stdout &&
|
|
24
|
+
(process.stdout.isTTY || process.env.FORCE_COLOR)
|
|
25
|
+
|
|
26
|
+
const formatter = (open, close, replace = open) =>
|
|
27
|
+
supportColor
|
|
28
|
+
? (input) => {
|
|
29
|
+
const string = '' + input
|
|
30
|
+
const index = string.indexOf(close, open.length)
|
|
31
|
+
return ~index
|
|
32
|
+
? open + getReplace(string, index, close, replace) + close
|
|
33
|
+
: open + string + close
|
|
34
|
+
}
|
|
35
|
+
: (input) => '' + input
|
|
36
|
+
|
|
37
|
+
const getReplace = (string, index, close, replace) => {
|
|
38
|
+
const head = string.substring(0, index) + replace
|
|
39
|
+
const tail = string.substring(index + close.length)
|
|
40
|
+
const next = tail.indexOf(close)
|
|
41
|
+
return ~next ? head + getReplace(tail, next, close, replace) : head + tail
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export const style = {
|
|
45
|
+
reset: formatter('\x1b[0m', '\x1b[0m'),
|
|
46
|
+
bold: formatter('\x1b[1m', '\x1b[22m', '\x1b[22m\x1b[1m'),
|
|
47
|
+
dim: formatter('\x1b[2m', '\x1b[22m', '\x1b[22m\x1b[2m'),
|
|
48
|
+
italic: formatter('\x1b[3m', '\x1b[23m'),
|
|
49
|
+
underline: formatter('\x1b[4m', '\x1b[24m'),
|
|
50
|
+
inverse: formatter('\x1b[7m', '\x1b[27m'),
|
|
51
|
+
hidden: formatter('\x1b[8m', '\x1b[28m'),
|
|
52
|
+
strikethrough: formatter('\x1b[9m', '\x1b[29m'),
|
|
53
|
+
|
|
54
|
+
black: formatter('\x1b[30m', '\x1b[39m'),
|
|
55
|
+
red: formatter('\x1b[31m', '\x1b[39m'),
|
|
56
|
+
green: formatter('\x1b[32m', '\x1b[39m'),
|
|
57
|
+
yellow: formatter('\x1b[33m', '\x1b[39m'),
|
|
58
|
+
blue: formatter('\x1b[34m', '\x1b[39m'),
|
|
59
|
+
magenta: formatter('\x1b[35m', '\x1b[39m'),
|
|
60
|
+
cyan: formatter('\x1b[36m', '\x1b[39m'),
|
|
61
|
+
white: formatter('\x1b[37m', '\x1b[39m'),
|
|
62
|
+
gray: formatter('\x1b[90m', '\x1b[39m'),
|
|
63
|
+
|
|
64
|
+
bgBlack: formatter('\x1b[40m', '\x1b[49m'),
|
|
65
|
+
bgRed: formatter('\x1b[41m', '\x1b[49m'),
|
|
66
|
+
bgGreen: formatter('\x1b[42m', '\x1b[49m'),
|
|
67
|
+
bgYellow: formatter('\x1b[43m', '\x1b[49m'),
|
|
68
|
+
bgBlue: formatter('\x1b[44m', '\x1b[49m'),
|
|
69
|
+
bgMagenta: formatter('\x1b[45m', '\x1b[49m'),
|
|
70
|
+
bgCyan: formatter('\x1b[46m', '\x1b[49m'),
|
|
71
|
+
bgWhite: formatter('\x1b[47m', '\x1b[49m')
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export const logger = {
|
|
75
|
+
info: (msg) => console.log(`${style.blue('ℹ')} ${msg}`),
|
|
76
|
+
success: (msg) => console.log(`${style.green('✔')} ${msg}`),
|
|
77
|
+
warn: (msg) => console.log(`${style.yellow('⚠')} ${msg}`),
|
|
78
|
+
error: (msg) => console.log(`${style.red('✖')} ${msg}`),
|
|
79
|
+
dim: (msg) => console.log(style.dim(msg))
|
|
80
|
+
}
|
package/src/main.js
CHANGED
|
@@ -26,6 +26,7 @@ import { runVitePreview } from './preview-server.js'
|
|
|
26
26
|
import { cli, state } from './state.js'
|
|
27
27
|
import { HTMLRenderer } from './renderer.js'
|
|
28
28
|
import { readFile } from 'fs/promises'
|
|
29
|
+
import { style, logger } from './logger.js'
|
|
29
30
|
|
|
30
31
|
const printBanner = async () => {
|
|
31
32
|
try {
|
|
@@ -107,6 +108,7 @@ const main = async () => {
|
|
|
107
108
|
return
|
|
108
109
|
}
|
|
109
110
|
if (isBuild) {
|
|
111
|
+
const startTime = performance.now()
|
|
110
112
|
await runHooks(state.USER_PRE_BUILD_HOOKS)
|
|
111
113
|
await runHooks(state.THEME_PRE_BUILD_HOOKS)
|
|
112
114
|
const { entry, htmlCache, pagesContext } = await buildHtmlEntries()
|
|
@@ -129,6 +131,11 @@ const main = async () => {
|
|
|
129
131
|
}
|
|
130
132
|
await runHooks(state.THEME_POST_BUILD_HOOKS, buildContext)
|
|
131
133
|
await runHooks(state.USER_POST_BUILD_HOOKS, buildContext)
|
|
134
|
+
const endTime = performance.now()
|
|
135
|
+
const duration = endTime - startTime
|
|
136
|
+
const timeString = duration > 1000 ? `${(duration / 1000).toFixed(2)}s` : `${Math.round(duration)}ms`
|
|
137
|
+
console.log()
|
|
138
|
+
logger.success(`Build completed in ${style.bold(timeString)}.`)
|
|
132
139
|
return
|
|
133
140
|
}
|
|
134
141
|
cli.showHelp()
|
package/src/mdx.js
CHANGED
|
@@ -25,6 +25,7 @@ import rehypeSlug from 'rehype-slug'
|
|
|
25
25
|
import extractToc from '@stefanprobst/rehype-extract-toc'
|
|
26
26
|
import withTocExport from '@stefanprobst/rehype-extract-toc/mdx'
|
|
27
27
|
import rehypeStarryNight from 'rehype-starry-night'
|
|
28
|
+
import remarkGfm from 'remark-gfm'
|
|
28
29
|
import { HTMLRenderer } from './renderer.js'
|
|
29
30
|
import { signal, computed, read, Suspense, nextTick } from 'refui'
|
|
30
31
|
import { createPortal } from 'refui/extras'
|
|
@@ -260,11 +261,21 @@ const resolveBaseMdxConfig = async () => {
|
|
|
260
261
|
jsxImportSource: 'refui',
|
|
261
262
|
development: state.CURRENT_MODE !== 'production',
|
|
262
263
|
elementAttributeNameCase: 'html',
|
|
263
|
-
rehypePlugins: [rehypeSlug, extractToc, [withTocExport, { name: 'toc' }]]
|
|
264
|
+
rehypePlugins: [rehypeSlug, extractToc, [withTocExport, { name: 'toc' }]],
|
|
265
|
+
remarkPlugins: []
|
|
264
266
|
}
|
|
267
|
+
|
|
268
|
+
if (state.GFM_ENABLED) {
|
|
269
|
+
baseMdxConfig.remarkPlugins.push(remarkGfm)
|
|
270
|
+
}
|
|
271
|
+
|
|
265
272
|
const mdxConfig = { ...baseMdxConfig, ...userMdxConfig }
|
|
266
273
|
const userRehypePlugins = Array.isArray(userMdxConfig.rehypePlugins) ? userMdxConfig.rehypePlugins : []
|
|
267
274
|
mdxConfig.rehypePlugins = [...baseMdxConfig.rehypePlugins, ...userRehypePlugins]
|
|
275
|
+
|
|
276
|
+
const userRemarkPlugins = Array.isArray(userMdxConfig.remarkPlugins) ? userMdxConfig.remarkPlugins : []
|
|
277
|
+
mdxConfig.remarkPlugins = [...baseMdxConfig.remarkPlugins, ...userRemarkPlugins]
|
|
278
|
+
|
|
268
279
|
mdxConfig.rehypePlugins.push(linkResolve)
|
|
269
280
|
mdxConfig.rehypePlugins.push(methanolCtx)
|
|
270
281
|
return (cachedMdxConfig = mdxConfig)
|
package/src/pagefind.js
CHANGED
|
@@ -22,7 +22,9 @@ import { access } from 'fs/promises'
|
|
|
22
22
|
import { constants } from 'fs'
|
|
23
23
|
import { join, delimiter } from 'path'
|
|
24
24
|
import { spawn } from 'child_process'
|
|
25
|
-
import { state } from './state.js'
|
|
25
|
+
import { state, cli } from './state.js'
|
|
26
|
+
import { createStageLogger } from './stage-logger.js'
|
|
27
|
+
import { logger } from './logger.js'
|
|
26
28
|
|
|
27
29
|
const resolvePagefindBin = async () => {
|
|
28
30
|
const binName = process.platform === 'win32' ? 'pagefind.cmd' : 'pagefind'
|
|
@@ -92,16 +94,25 @@ const runCommand = (command, args, options) =>
|
|
|
92
94
|
export const runPagefind = async () => {
|
|
93
95
|
const bin = await resolvePagefindBin()
|
|
94
96
|
if (!bin) {
|
|
95
|
-
|
|
97
|
+
logger.warn('Pagefind not found; skipping search indexing.')
|
|
96
98
|
return false
|
|
97
99
|
}
|
|
98
|
-
|
|
100
|
+
const logEnabled = state.CURRENT_MODE === 'production' && cli.command === 'build' && !cli.CLI_VERBOSE
|
|
101
|
+
const stageLogger = createStageLogger(logEnabled)
|
|
102
|
+
const token = stageLogger.start('Indexing search')
|
|
103
|
+
|
|
104
|
+
if (cli.CLI_VERBOSE) {
|
|
105
|
+
logger.info('Running Pagefind search indexing...')
|
|
106
|
+
}
|
|
107
|
+
|
|
99
108
|
const extraArgs = buildArgsFromOptions(state.PAGEFIND_BUILD)
|
|
100
109
|
const ok = await runCommand(bin, ['--site', state.DIST_DIR, ...extraArgs], {
|
|
101
|
-
cwd: state.PROJECT_ROOT
|
|
110
|
+
cwd: state.PROJECT_ROOT,
|
|
111
|
+
stdio: cli.CLI_VERBOSE ? 'inherit' : 'ignore'
|
|
102
112
|
})
|
|
103
113
|
if (!ok) {
|
|
104
|
-
|
|
114
|
+
logger.warn('Pagefind failed to build search index.')
|
|
105
115
|
}
|
|
116
|
+
stageLogger.end(token)
|
|
106
117
|
return ok
|
|
107
118
|
}
|
package/src/stage-logger.js
CHANGED
|
@@ -18,6 +18,8 @@
|
|
|
18
18
|
* under the License.
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
|
+
import { style } from './logger.js'
|
|
22
|
+
|
|
21
23
|
const now = () => (typeof performance !== 'undefined' ? performance.now() : Date.now())
|
|
22
24
|
|
|
23
25
|
export const createStageLogger = (enabled) => {
|
|
@@ -43,17 +45,18 @@ export const createStageLogger = (enabled) => {
|
|
|
43
45
|
}
|
|
44
46
|
const start = (label) => {
|
|
45
47
|
if (!enabled) return null
|
|
46
|
-
writeLine(`${label}...`, false)
|
|
48
|
+
writeLine(`${style.cyan('◼')} ${label}...`, false)
|
|
47
49
|
return { label, start: now() }
|
|
48
50
|
}
|
|
49
51
|
const update = (token, message) => {
|
|
50
52
|
if (!enabled || !token || !message) return
|
|
51
|
-
writeLine(message
|
|
53
|
+
writeLine(`${style.cyan('◼')} ${message}`, false)
|
|
52
54
|
}
|
|
53
55
|
const end = (token) => {
|
|
54
56
|
if (!enabled || !token) return
|
|
55
|
-
const duration =
|
|
56
|
-
|
|
57
|
+
const duration = now() - token.start
|
|
58
|
+
const timeString = duration > 1000 ? `${(duration / 1000).toFixed(2)}s` : `${Math.round(duration)}ms`
|
|
59
|
+
writeLine(`${style.green('✔')} ${token.label}\t${style.dim(timeString)}`, true)
|
|
57
60
|
}
|
|
58
61
|
return { start, update, end }
|
|
59
62
|
}
|
package/src/state.js
CHANGED
|
@@ -103,10 +103,9 @@ const withCommonOptions = (y) =>
|
|
|
103
103
|
})
|
|
104
104
|
.option('code-highlighting', {
|
|
105
105
|
describe: 'Enable or disable code highlighting',
|
|
106
|
-
type: '
|
|
106
|
+
type: 'boolean',
|
|
107
107
|
coerce: (value) => {
|
|
108
108
|
if (value == null) return null
|
|
109
|
-
if (value === true || value === '') return true
|
|
110
109
|
if (typeof value === 'boolean') return value
|
|
111
110
|
const normalized = String(value).trim().toLowerCase()
|
|
112
111
|
if (normalized === 'true') return true
|
|
@@ -114,6 +113,18 @@ const withCommonOptions = (y) =>
|
|
|
114
113
|
return null
|
|
115
114
|
}
|
|
116
115
|
})
|
|
116
|
+
.option('verbose', {
|
|
117
|
+
alias: 'v',
|
|
118
|
+
describe: 'Enable verbose output',
|
|
119
|
+
type: 'boolean',
|
|
120
|
+
default: false
|
|
121
|
+
})
|
|
122
|
+
.option('base', {
|
|
123
|
+
describe: 'Base URL override',
|
|
124
|
+
type: 'string',
|
|
125
|
+
requiresArg: true,
|
|
126
|
+
nargs: 1
|
|
127
|
+
})
|
|
117
128
|
|
|
118
129
|
const parser = yargs(hideBin(process.argv))
|
|
119
130
|
.scriptName('methanol')
|
|
@@ -141,7 +152,9 @@ export const cli = {
|
|
|
141
152
|
CLI_OUTPUT_DIR: argv.output || null,
|
|
142
153
|
CLI_CONFIG_PATH: argv.config || null,
|
|
143
154
|
CLI_SITE_NAME: argv['site-name'] || null,
|
|
144
|
-
CLI_CODE_HIGHLIGHTING: typeof argv['code-highlighting'] === 'boolean' ? argv['code-highlighting'] : null
|
|
155
|
+
CLI_CODE_HIGHLIGHTING: typeof argv['code-highlighting'] === 'boolean' ? argv['code-highlighting'] : null,
|
|
156
|
+
CLI_VERBOSE: Boolean(argv.verbose),
|
|
157
|
+
CLI_BASE: argv.base || null
|
|
145
158
|
}
|
|
146
159
|
|
|
147
160
|
export const state = {
|
|
@@ -180,6 +193,7 @@ export const state = {
|
|
|
180
193
|
THEME_POST_BUNDLE_HOOKS: [],
|
|
181
194
|
STARRY_NIGHT_ENABLED: false,
|
|
182
195
|
STARRY_NIGHT_OPTIONS: null,
|
|
196
|
+
GFM_ENABLED: true,
|
|
183
197
|
CURRENT_MODE: 'production',
|
|
184
198
|
RESOLVED_MDX_CONFIG: undefined,
|
|
185
199
|
RESOLVED_VITE_CONFIG: undefined
|
|
@@ -1735,6 +1735,47 @@ a {
|
|
|
1735
1735
|
justify-content: flex-end;
|
|
1736
1736
|
}
|
|
1737
1737
|
|
|
1738
|
+
/* --- Tables (GFM) --- */
|
|
1739
|
+
|
|
1740
|
+
.main-content table {
|
|
1741
|
+
width: 100%;
|
|
1742
|
+
border-collapse: collapse;
|
|
1743
|
+
margin: 1.5rem 0;
|
|
1744
|
+
font-size: 0.95rem;
|
|
1745
|
+
overflow-x: auto;
|
|
1746
|
+
display: block; /* Enables horizontal scroll for large tables */
|
|
1747
|
+
}
|
|
1748
|
+
|
|
1749
|
+
.main-content table thead tr {
|
|
1750
|
+
border-bottom: 2px solid var(--border);
|
|
1751
|
+
}
|
|
1752
|
+
|
|
1753
|
+
.main-content table th {
|
|
1754
|
+
text-align: left;
|
|
1755
|
+
padding: 0.75rem 1rem;
|
|
1756
|
+
font-weight: 600;
|
|
1757
|
+
color: var(--text);
|
|
1758
|
+
white-space: nowrap;
|
|
1759
|
+
}
|
|
1760
|
+
|
|
1761
|
+
.main-content table tbody tr {
|
|
1762
|
+
border-bottom: 1px solid var(--border);
|
|
1763
|
+
transition: background-color 0.1s ease;
|
|
1764
|
+
}
|
|
1765
|
+
|
|
1766
|
+
.main-content table tbody tr:last-child {
|
|
1767
|
+
border-bottom: none;
|
|
1768
|
+
}
|
|
1769
|
+
|
|
1770
|
+
.main-content table td {
|
|
1771
|
+
padding: 0.75rem 1rem;
|
|
1772
|
+
color: var(--muted);
|
|
1773
|
+
}
|
|
1774
|
+
|
|
1775
|
+
.main-content table tbody tr:hover {
|
|
1776
|
+
background-color: var(--hover-bg);
|
|
1777
|
+
}
|
|
1778
|
+
|
|
1738
1779
|
/* --- View Transitions --- */
|
|
1739
1780
|
|
|
1740
1781
|
@view-transition {
|
|
@@ -1747,3 +1788,151 @@ a {
|
|
|
1747
1788
|
view-transition-name: active-sidebar-bg;
|
|
1748
1789
|
contain: layout paint;
|
|
1749
1790
|
}
|
|
1791
|
+
|
|
1792
|
+
/* --- Print Styles --- */
|
|
1793
|
+
|
|
1794
|
+
@media print {
|
|
1795
|
+
:root {
|
|
1796
|
+
--bg: #ffffff;
|
|
1797
|
+
--surface: #ffffff;
|
|
1798
|
+
--surface-muted: #f4f4f5;
|
|
1799
|
+
--surface-elevated: #ffffff;
|
|
1800
|
+
--text: #09090b;
|
|
1801
|
+
--muted: #52525b;
|
|
1802
|
+
--border: #e4e4e7;
|
|
1803
|
+
--accent: #000000;
|
|
1804
|
+
--accent-soft: #f4f4f5;
|
|
1805
|
+
--hover-bg: transparent;
|
|
1806
|
+
}
|
|
1807
|
+
|
|
1808
|
+
body {
|
|
1809
|
+
background-color: white !important;
|
|
1810
|
+
background-image: none !important;
|
|
1811
|
+
color: black !important;
|
|
1812
|
+
width: 100% !important;
|
|
1813
|
+
margin: 0 !important;
|
|
1814
|
+
padding: 0 !important;
|
|
1815
|
+
overflow: visible !important;
|
|
1816
|
+
}
|
|
1817
|
+
|
|
1818
|
+
/* Hide UI Elements */
|
|
1819
|
+
.sidebar,
|
|
1820
|
+
.toc-panel,
|
|
1821
|
+
.nav-toggle-label,
|
|
1822
|
+
.toc-toggle-label,
|
|
1823
|
+
.search-toggle-label,
|
|
1824
|
+
.search-modal,
|
|
1825
|
+
.page-nav,
|
|
1826
|
+
.copy-btn,
|
|
1827
|
+
.heading-anchor,
|
|
1828
|
+
.theme-switch-wrapper,
|
|
1829
|
+
.lang-switch-wrapper,
|
|
1830
|
+
.page-meta {
|
|
1831
|
+
display: none !important;
|
|
1832
|
+
}
|
|
1833
|
+
|
|
1834
|
+
/* Layout Overrides */
|
|
1835
|
+
.layout-container,
|
|
1836
|
+
.layout-container.no-toc {
|
|
1837
|
+
display: block !important;
|
|
1838
|
+
max-width: none !important;
|
|
1839
|
+
width: 100% !important;
|
|
1840
|
+
margin: 0 !important;
|
|
1841
|
+
padding: 0 !important;
|
|
1842
|
+
}
|
|
1843
|
+
|
|
1844
|
+
.main-content {
|
|
1845
|
+
padding: 0 !important;
|
|
1846
|
+
width: 100% !important;
|
|
1847
|
+
max-width: none !important;
|
|
1848
|
+
}
|
|
1849
|
+
|
|
1850
|
+
/* Typography & Content */
|
|
1851
|
+
body {
|
|
1852
|
+
font-size: 11pt !important;
|
|
1853
|
+
line-height: 1.5 !important;
|
|
1854
|
+
}
|
|
1855
|
+
|
|
1856
|
+
.main-content {
|
|
1857
|
+
h1 {
|
|
1858
|
+
font-size: 24pt !important;
|
|
1859
|
+
margin-bottom: 1rem !important;
|
|
1860
|
+
}
|
|
1861
|
+
|
|
1862
|
+
h2 {
|
|
1863
|
+
font-size: 18pt !important;
|
|
1864
|
+
margin-top: 1.5rem !important;
|
|
1865
|
+
margin-bottom: 0.75rem !important;
|
|
1866
|
+
}
|
|
1867
|
+
|
|
1868
|
+
h3 {
|
|
1869
|
+
font-size: 14pt !important;
|
|
1870
|
+
margin-top: 1.25rem !important;
|
|
1871
|
+
margin-bottom: 0.5rem !important;
|
|
1872
|
+
}
|
|
1873
|
+
|
|
1874
|
+
p, li {
|
|
1875
|
+
font-size: 11pt !important;
|
|
1876
|
+
margin-bottom: 0.75rem !important;
|
|
1877
|
+
}
|
|
1878
|
+
|
|
1879
|
+
pre, code {
|
|
1880
|
+
font-size: 10pt !important;
|
|
1881
|
+
}
|
|
1882
|
+
}
|
|
1883
|
+
|
|
1884
|
+
h1, h2, h3, h4, h5, h6 {
|
|
1885
|
+
color: black !important;
|
|
1886
|
+
page-break-after: avoid;
|
|
1887
|
+
break-after: avoid;
|
|
1888
|
+
}
|
|
1889
|
+
|
|
1890
|
+
h2 {
|
|
1891
|
+
border-bottom: 1px solid #000 !important;
|
|
1892
|
+
}
|
|
1893
|
+
|
|
1894
|
+
p, li {
|
|
1895
|
+
orphans: 3;
|
|
1896
|
+
widows: 3;
|
|
1897
|
+
}
|
|
1898
|
+
|
|
1899
|
+
a {
|
|
1900
|
+
text-decoration: underline !important;
|
|
1901
|
+
color: black !important;
|
|
1902
|
+
}
|
|
1903
|
+
|
|
1904
|
+
/* Expand external links */
|
|
1905
|
+
a[href^="http"]::after {
|
|
1906
|
+
content: " (" attr(href) ")";
|
|
1907
|
+
font-size: 0.85em;
|
|
1908
|
+
color: #555;
|
|
1909
|
+
}
|
|
1910
|
+
|
|
1911
|
+
/* Clean up code blocks */
|
|
1912
|
+
pre {
|
|
1913
|
+
border: 1px solid #ccc !important;
|
|
1914
|
+
white-space: pre-wrap !important;
|
|
1915
|
+
break-inside: avoid;
|
|
1916
|
+
background: #fafafa !important;
|
|
1917
|
+
}
|
|
1918
|
+
|
|
1919
|
+
/* Blockquotes */
|
|
1920
|
+
blockquote {
|
|
1921
|
+
border-left: 3px solid #ccc !important;
|
|
1922
|
+
background: transparent !important;
|
|
1923
|
+
color: #333 !important;
|
|
1924
|
+
break-inside: avoid;
|
|
1925
|
+
}
|
|
1926
|
+
|
|
1927
|
+
/* Tables */
|
|
1928
|
+
table {
|
|
1929
|
+
break-inside: avoid;
|
|
1930
|
+
}
|
|
1931
|
+
|
|
1932
|
+
/* Page Setup */
|
|
1933
|
+
@page {
|
|
1934
|
+
margin: 2cm;
|
|
1935
|
+
size: auto;
|
|
1936
|
+
}
|
|
1937
|
+
}
|
|
1938
|
+
|