@limcpf/everything-is-a-markdown 0.6.3 → 0.6.4
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.ko.md +2 -1
- package/README.md +2 -1
- package/package.json +1 -1
- package/src/build.ts +1 -1
- package/src/runtime/app.css +6 -3
- package/src/runtime/app.js +15 -25
package/README.ko.md
CHANGED
|
@@ -193,7 +193,8 @@ flowchart LR
|
|
|
193
193
|
|
|
194
194
|
문서 전환 시에도 해당 블록을 다시 렌더링합니다.
|
|
195
195
|
Mermaid fence는 일반 코드 블록 UI와 분리된 전용 컨테이너(`.mermaid-block`)에서 렌더링되므로 코드 헤더/파일명/복사 버튼이 표시되지 않습니다.
|
|
196
|
-
렌더된 SVG는 데스크톱/모바일 모두에서
|
|
196
|
+
렌더된 SVG는 데스크톱/모바일 모두에서 중앙 정렬되며 `min(100%, 720px)` 기준으로 자동 축소됩니다.
|
|
197
|
+
본문 이미지도 동일한 폭 정책을 적용해 글 읽기 흐름을 유지합니다.
|
|
197
198
|
설정에서 Mermaid를 비활성화하거나 CDN 로드가 실패하면, 같은 컨테이너 안에서 소스 코드 텍스트를 유지하고 하단에 경고 메시지를 표시합니다.
|
|
198
199
|
|
|
199
200
|
`blog.config.ts`에서 설정:
|
package/README.md
CHANGED
|
@@ -193,7 +193,8 @@ flowchart LR
|
|
|
193
193
|
|
|
194
194
|
Rendering happens in the browser on first load and when navigating to another document.
|
|
195
195
|
Mermaid fences are rendered inside a dedicated diagram container (`.mermaid-block`) instead of the regular code block UI, so they do not show code headers, filenames, or copy buttons.
|
|
196
|
-
Rendered SVG output is centered and constrained to
|
|
196
|
+
Rendered SVG output is centered and automatically constrained to `min(100%, 720px)` on both desktop and mobile.
|
|
197
|
+
Regular content images inside the viewer follow the same width policy to keep reading flow stable.
|
|
197
198
|
If Mermaid is disabled in config or CDN loading fails, the source block is shown as-is in the same container and a warning message appears below it.
|
|
198
199
|
|
|
199
200
|
Configuration options (`blog.config.ts`):
|
package/package.json
CHANGED
package/src/build.ts
CHANGED
|
@@ -979,7 +979,7 @@ async function writeOutputIfChanged(
|
|
|
979
979
|
|
|
980
980
|
const outputPath = path.join(context.outDir, relOutputPath);
|
|
981
981
|
const unchanged = context.previousHashes[relOutputPath] === outputHash;
|
|
982
|
-
if (unchanged) {
|
|
982
|
+
if (unchanged && (await Bun.file(outputPath).exists())) {
|
|
983
983
|
return;
|
|
984
984
|
}
|
|
985
985
|
|
package/src/runtime/app.css
CHANGED
|
@@ -66,6 +66,7 @@
|
|
|
66
66
|
--mobile-toggle-fg: #ffffff;
|
|
67
67
|
--content-heading-accent-soft: rgba(136, 57, 239, 0.32);
|
|
68
68
|
--content-heading-subtle: var(--latte-subtext1);
|
|
69
|
+
--content-visual-max-width: 720px;
|
|
69
70
|
--desktop-sidebar-default: 420px;
|
|
70
71
|
--desktop-sidebar-min: 320px;
|
|
71
72
|
--desktop-viewer-min: 680px;
|
|
@@ -1135,8 +1136,8 @@ body.mobile-toggle-left .mobile-menu-toggle {
|
|
|
1135
1136
|
|
|
1136
1137
|
.viewer-content .mermaid-block pre.mermaid[data-mermaid-rendered="true"] svg {
|
|
1137
1138
|
display: block;
|
|
1138
|
-
width:
|
|
1139
|
-
max-width: 100
|
|
1139
|
+
width: auto;
|
|
1140
|
+
max-width: min(100%, var(--content-visual-max-width));
|
|
1140
1141
|
height: auto;
|
|
1141
1142
|
margin: 0 auto;
|
|
1142
1143
|
}
|
|
@@ -1200,8 +1201,10 @@ body.mobile-toggle-left .mobile-menu-toggle {
|
|
|
1200
1201
|
/* Images */
|
|
1201
1202
|
.viewer-content img {
|
|
1202
1203
|
display: block;
|
|
1203
|
-
|
|
1204
|
+
width: auto;
|
|
1205
|
+
max-width: min(100%, var(--content-visual-max-width));
|
|
1204
1206
|
height: auto;
|
|
1207
|
+
margin: 0 auto;
|
|
1205
1208
|
border-radius: 8px;
|
|
1206
1209
|
border: 1px solid var(--latte-surface0);
|
|
1207
1210
|
}
|
package/src/runtime/app.js
CHANGED
|
@@ -13,6 +13,7 @@ const DESKTOP_SPLITTER_STEP = 24;
|
|
|
13
13
|
const DEFAULT_BRANCH = "dev";
|
|
14
14
|
const DEFAULT_SITE_TITLE = "File-System Blog";
|
|
15
15
|
const BRANCH_KEY = "fsblog.branch";
|
|
16
|
+
const APP_READY_STATE_ATTR = "data-app-ready";
|
|
16
17
|
const FOCUSABLE_SELECTOR =
|
|
17
18
|
'a[href], button:not([disabled]), input:not([disabled]), textarea:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])';
|
|
18
19
|
const MERMAID_CDN = "https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.min.js";
|
|
@@ -103,28 +104,6 @@ function showMermaidError(preview, message) {
|
|
|
103
104
|
preview.parentElement.appendChild(createMermaidLoadError(message));
|
|
104
105
|
}
|
|
105
106
|
|
|
106
|
-
function parseSvgSize(value) {
|
|
107
|
-
const normalized = typeof value === "string" ? value.trim() : "";
|
|
108
|
-
if (!normalized) {
|
|
109
|
-
return null;
|
|
110
|
-
}
|
|
111
|
-
if (normalized.endsWith("%")) {
|
|
112
|
-
return null;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
const match = normalized.match(/^(\d+(?:\.\d+)?)/);
|
|
116
|
-
if (!match) {
|
|
117
|
-
return null;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
const parsed = Number(match[1]);
|
|
121
|
-
if (!Number.isFinite(parsed) || parsed <= 0) {
|
|
122
|
-
return null;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
return parsed;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
107
|
function normalizeRenderedMermaidSvg(block) {
|
|
129
108
|
if (!(block instanceof HTMLElement)) {
|
|
130
109
|
return;
|
|
@@ -135,12 +114,11 @@ function normalizeRenderedMermaidSvg(block) {
|
|
|
135
114
|
return;
|
|
136
115
|
}
|
|
137
116
|
|
|
138
|
-
const intrinsicWidth = parseSvgSize(svg.getAttribute("width"));
|
|
139
117
|
svg.style.display = "block";
|
|
140
|
-
svg.style.width = "
|
|
118
|
+
svg.style.width = "auto";
|
|
141
119
|
svg.style.height = "auto";
|
|
142
120
|
svg.style.margin = "0 auto";
|
|
143
|
-
svg.style.maxWidth =
|
|
121
|
+
svg.style.maxWidth = "min(100%, var(--content-visual-max-width, 720px))";
|
|
144
122
|
}
|
|
145
123
|
|
|
146
124
|
function parseMermaidNodes() {
|
|
@@ -1101,7 +1079,16 @@ function renderBacklinks(doc, pathBase) {
|
|
|
1101
1079
|
return html;
|
|
1102
1080
|
}
|
|
1103
1081
|
|
|
1082
|
+
function setAppReadyState(state) {
|
|
1083
|
+
if (!(document.documentElement instanceof HTMLElement)) {
|
|
1084
|
+
return;
|
|
1085
|
+
}
|
|
1086
|
+
document.documentElement.setAttribute(APP_READY_STATE_ATTR, state);
|
|
1087
|
+
}
|
|
1088
|
+
|
|
1104
1089
|
async function start() {
|
|
1090
|
+
setAppReadyState("booting");
|
|
1091
|
+
|
|
1105
1092
|
const treeRoot = document.getElementById("tree-root");
|
|
1106
1093
|
const appRoot = document.querySelector(".app-root");
|
|
1107
1094
|
const splitter = document.getElementById("app-splitter");
|
|
@@ -1922,6 +1909,7 @@ async function start() {
|
|
|
1922
1909
|
const initialRoute = currentRoute === "/" ? pickHomeRoute(view) : currentRoute;
|
|
1923
1910
|
handleLayoutChange();
|
|
1924
1911
|
await state.navigate(initialRoute, currentRoute === "/" && initialRoute !== "/");
|
|
1912
|
+
setAppReadyState("ready");
|
|
1925
1913
|
|
|
1926
1914
|
window.addEventListener("popstate", async () => {
|
|
1927
1915
|
await state.navigate(resolveRouteFromLocation(view.routeMap, pathBase), false);
|
|
@@ -1929,6 +1917,8 @@ async function start() {
|
|
|
1929
1917
|
}
|
|
1930
1918
|
|
|
1931
1919
|
start().catch((error) => {
|
|
1920
|
+
setAppReadyState("error");
|
|
1921
|
+
|
|
1932
1922
|
const contentEl = document.getElementById("viewer-content");
|
|
1933
1923
|
if (contentEl) {
|
|
1934
1924
|
const message = error instanceof Error ? error.message : String(error);
|