@docubook/create 1.16.0 → 1.16.1
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
package/src/dist/app/page.tsx
CHANGED
|
@@ -25,7 +25,7 @@ export default function Home() {
|
|
|
25
25
|
)}
|
|
26
26
|
>
|
|
27
27
|
<AnimatedShinyText className="inline-flex items-center justify-center px-4 py-1 transition ease-out hover:text-neutral-100 hover:duration-300 hover:dark:text-neutral-200">
|
|
28
|
-
<span>🚀 New Version - Release v1.16.
|
|
28
|
+
<span>🚀 New Version - Release v1.16.1</span>
|
|
29
29
|
<ArrowRightIcon className="ml-1 size-3 transition-transform duration-300 ease-in-out group-hover:translate-x-0.5" />
|
|
30
30
|
</AnimatedShinyText>
|
|
31
31
|
</div>
|
|
@@ -1,19 +1,109 @@
|
|
|
1
|
-
import { ComponentProps } from "react";
|
|
1
|
+
import { type ComponentProps } from "react";
|
|
2
2
|
import Copy from "./CopyMdx";
|
|
3
|
+
import {
|
|
4
|
+
SiJavascript,
|
|
5
|
+
SiTypescript,
|
|
6
|
+
SiReact,
|
|
7
|
+
SiPython,
|
|
8
|
+
SiGo,
|
|
9
|
+
SiPhp,
|
|
10
|
+
SiRuby,
|
|
11
|
+
SiSwift,
|
|
12
|
+
SiKotlin,
|
|
13
|
+
SiHtml5,
|
|
14
|
+
SiCss3,
|
|
15
|
+
SiSass,
|
|
16
|
+
SiPostgresql,
|
|
17
|
+
SiGraphql,
|
|
18
|
+
SiYaml,
|
|
19
|
+
SiToml,
|
|
20
|
+
SiDocker,
|
|
21
|
+
SiNginx,
|
|
22
|
+
SiGit,
|
|
23
|
+
SiGnubash,
|
|
24
|
+
SiMarkdown,
|
|
25
|
+
} from "react-icons/si";
|
|
26
|
+
import { FaJava, FaCode } from "react-icons/fa";
|
|
27
|
+
import { TbJson } from "react-icons/tb";
|
|
28
|
+
|
|
29
|
+
type PreProps = ComponentProps<"pre"> & {
|
|
30
|
+
raw?: string;
|
|
31
|
+
"data-title"?: string;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// Component to display an icon based on the programming language
|
|
35
|
+
const LanguageIcon = ({ lang }: { lang: string }) => {
|
|
36
|
+
const iconProps = { className: "w-4 h-4" };
|
|
37
|
+
const languageToIconMap: Record<string, JSX.Element> = {
|
|
38
|
+
gitignore: <SiGit {...iconProps} />,
|
|
39
|
+
docker: <SiDocker {...iconProps} />,
|
|
40
|
+
dockerfile: <SiDocker {...iconProps} />,
|
|
41
|
+
nginx: <SiNginx {...iconProps} />,
|
|
42
|
+
sql: <SiPostgresql {...iconProps} />,
|
|
43
|
+
graphql: <SiGraphql {...iconProps} />,
|
|
44
|
+
yaml: <SiYaml {...iconProps} />,
|
|
45
|
+
yml: <SiYaml {...iconProps} />,
|
|
46
|
+
toml: <SiToml {...iconProps} />,
|
|
47
|
+
json: <TbJson {...iconProps} />,
|
|
48
|
+
md: <SiMarkdown {...iconProps} />,
|
|
49
|
+
markdown: <SiMarkdown {...iconProps} />,
|
|
50
|
+
bash: <SiGnubash {...iconProps} />,
|
|
51
|
+
sh: <SiGnubash {...iconProps} />,
|
|
52
|
+
shell: <SiGnubash {...iconProps} />,
|
|
53
|
+
swift: <SiSwift {...iconProps} />,
|
|
54
|
+
kotlin: <SiKotlin {...iconProps} />,
|
|
55
|
+
kt: <SiKotlin {...iconProps} />,
|
|
56
|
+
kts: <SiKotlin {...iconProps} />,
|
|
57
|
+
rb: <SiRuby {...iconProps} />,
|
|
58
|
+
ruby: <SiRuby {...iconProps} />,
|
|
59
|
+
php: <SiPhp {...iconProps} />,
|
|
60
|
+
go: <SiGo {...iconProps} />,
|
|
61
|
+
py: <SiPython {...iconProps} />,
|
|
62
|
+
python: <SiPython {...iconProps} />,
|
|
63
|
+
java: <FaJava {...iconProps} />,
|
|
64
|
+
tsx: <SiReact {...iconProps} />,
|
|
65
|
+
typescript: <SiTypescript {...iconProps} />,
|
|
66
|
+
ts: <SiTypescript {...iconProps} />,
|
|
67
|
+
jsx: <SiReact {...iconProps} />,
|
|
68
|
+
js: <SiJavascript {...iconProps} />,
|
|
69
|
+
javascript: <SiJavascript {...iconProps} />,
|
|
70
|
+
html: <SiHtml5 {...iconProps} />,
|
|
71
|
+
css: <SiCss3 {...iconProps} />,
|
|
72
|
+
scss: <SiSass {...iconProps} />,
|
|
73
|
+
sass: <SiSass {...iconProps} />,
|
|
74
|
+
};
|
|
75
|
+
return languageToIconMap[lang] || <FaCode {...iconProps} />;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
// Function to extract the language from className
|
|
79
|
+
function getLanguage(className: string = ""): string {
|
|
80
|
+
const match = className.match(/language-(\w+)/);
|
|
81
|
+
return match ? match[1] : "default";
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export default function Pre({ children, raw, ...rest }: PreProps) {
|
|
85
|
+
const { "data-title": title, className, ...restProps } = rest;
|
|
86
|
+
const language = getLanguage(className);
|
|
87
|
+
const hasTitle = !!title;
|
|
3
88
|
|
|
4
|
-
export default function Pre({
|
|
5
|
-
children,
|
|
6
|
-
raw,
|
|
7
|
-
...rest
|
|
8
|
-
}: ComponentProps<"pre"> & { raw?: string }) {
|
|
9
89
|
return (
|
|
10
|
-
<div className="
|
|
11
|
-
<div className="
|
|
12
|
-
<Copy content={raw
|
|
90
|
+
<div className="code-block-container">
|
|
91
|
+
<div className="code-block-actions">
|
|
92
|
+
{raw && <Copy content={raw} />}
|
|
13
93
|
</div>
|
|
14
|
-
|
|
15
|
-
<
|
|
94
|
+
{hasTitle && (
|
|
95
|
+
<div className="code-block-header">
|
|
96
|
+
<div className="flex items-center gap-2">
|
|
97
|
+
<LanguageIcon lang={language} />
|
|
98
|
+
<span>{title}</span>
|
|
99
|
+
</div>
|
|
100
|
+
</div>
|
|
101
|
+
)}
|
|
102
|
+
<div className="code-block-body">
|
|
103
|
+
<pre className={className} {...restProps}>
|
|
104
|
+
{children}
|
|
105
|
+
</pre>
|
|
16
106
|
</div>
|
|
17
107
|
</div>
|
|
18
108
|
);
|
|
19
|
-
}
|
|
109
|
+
}
|
package/src/dist/lib/markdown.ts
CHANGED
|
@@ -8,7 +8,7 @@ import rehypeSlug from "rehype-slug";
|
|
|
8
8
|
import rehypeCodeTitles from "rehype-code-titles";
|
|
9
9
|
import { page_routes, ROUTES } from "./routes-config";
|
|
10
10
|
import { visit } from "unist-util-visit";
|
|
11
|
-
import type { Node } from "unist";
|
|
11
|
+
import type { Node, Parent } from "unist";
|
|
12
12
|
import matter from "gray-matter";
|
|
13
13
|
|
|
14
14
|
// Type definitions for unist-util-visit
|
|
@@ -16,6 +16,7 @@ interface Element extends Node {
|
|
|
16
16
|
type: string;
|
|
17
17
|
tagName?: string;
|
|
18
18
|
properties?: Record<string, unknown> & {
|
|
19
|
+
className?: string[];
|
|
19
20
|
raw?: string;
|
|
20
21
|
};
|
|
21
22
|
children?: Node[];
|
|
@@ -77,6 +78,49 @@ const components = {
|
|
|
77
78
|
AccordionGroup
|
|
78
79
|
};
|
|
79
80
|
|
|
81
|
+
// helper function to handle rehype code titles, since by default we can't inject into the className of rehype-code-titles
|
|
82
|
+
const handleCodeTitles = () => (tree: Node) => {
|
|
83
|
+
visit(tree, "element", (node: Element, index: number | null, parent: Parent | null) => {
|
|
84
|
+
// Ensure the visited node is valid
|
|
85
|
+
if (!parent || index === null || node.tagName !== 'div') {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Check if this is the title div from rehype-code-titles
|
|
90
|
+
const isTitleDiv = node.properties?.className?.includes('rehype-code-title');
|
|
91
|
+
if (!isTitleDiv) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Find the next <pre> element, skipping over other nodes like whitespace text
|
|
96
|
+
let nextElement = null;
|
|
97
|
+
for (let i = index + 1; i < parent.children.length; i++) {
|
|
98
|
+
const sibling = parent.children[i];
|
|
99
|
+
if (sibling.type === 'element') {
|
|
100
|
+
nextElement = sibling as Element;
|
|
101
|
+
break;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// If the next element is a <pre>, move the title to it
|
|
106
|
+
if (nextElement && nextElement.tagName === 'pre') {
|
|
107
|
+
const titleNode = node.children?.[0] as TextNode;
|
|
108
|
+
if (titleNode && titleNode.type === 'text') {
|
|
109
|
+
if (!nextElement.properties) {
|
|
110
|
+
nextElement.properties = {};
|
|
111
|
+
}
|
|
112
|
+
nextElement.properties['data-title'] = titleNode.value;
|
|
113
|
+
|
|
114
|
+
// Remove the original title div
|
|
115
|
+
parent.children.splice(index, 1);
|
|
116
|
+
|
|
117
|
+
// Return the same index to continue visiting from the correct position
|
|
118
|
+
return index;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
};
|
|
123
|
+
|
|
80
124
|
// can be used for other pages like blogs, Guides etc
|
|
81
125
|
async function parseMdx<Frontmatter>(rawMdx: string) {
|
|
82
126
|
return await compileMDX<Frontmatter>({
|
|
@@ -87,6 +131,7 @@ async function parseMdx<Frontmatter>(rawMdx: string) {
|
|
|
87
131
|
rehypePlugins: [
|
|
88
132
|
preProcess,
|
|
89
133
|
rehypeCodeTitles,
|
|
134
|
+
handleCodeTitles,
|
|
90
135
|
rehypePrism,
|
|
91
136
|
rehypeSlug,
|
|
92
137
|
rehypeAutolinkHeadings,
|
package/src/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "docubook",
|
|
3
|
-
"version": "1.16.
|
|
3
|
+
"version": "1.16.1",
|
|
4
4
|
"private": true,
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "next dev",
|
|
@@ -30,13 +30,13 @@
|
|
|
30
30
|
"framer-motion": "^12.4.1",
|
|
31
31
|
"geist": "^1.3.1",
|
|
32
32
|
"gray-matter": "^4.0.3",
|
|
33
|
-
"install": "^0.13.0",
|
|
34
33
|
"lucide-react": "^0.511.0",
|
|
35
34
|
"next": "^14.2.6",
|
|
36
35
|
"next-mdx-remote": "^5.0.0",
|
|
37
36
|
"next-themes": "^0.3.0",
|
|
38
37
|
"react": "^18.3.1",
|
|
39
38
|
"react-dom": "^18.3.1",
|
|
39
|
+
"react-icons": "^5.5.0",
|
|
40
40
|
"rehype-autolink-headings": "^7.1.0",
|
|
41
41
|
"rehype-code-titles": "^1.2.0",
|
|
42
42
|
"rehype-prism-plus": "^2.0.0",
|
|
@@ -93,3 +93,87 @@
|
|
|
93
93
|
border: none;
|
|
94
94
|
border-radius: 8px; /* Sudut melengkung pada iframe */
|
|
95
95
|
}
|
|
96
|
+
|
|
97
|
+
/* ======================================================================== */
|
|
98
|
+
/* Custom styling for code blocks */
|
|
99
|
+
/* ======================================================================== */
|
|
100
|
+
|
|
101
|
+
.code-block-container {
|
|
102
|
+
position: relative;
|
|
103
|
+
margin: 1.5rem 0;
|
|
104
|
+
border: 1px solid hsl(var(--border));
|
|
105
|
+
overflow: hidden;
|
|
106
|
+
font-size: 0.875rem;
|
|
107
|
+
border-radius: 0.75rem;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
.code-block-header {
|
|
111
|
+
display: flex;
|
|
112
|
+
align-items: center;
|
|
113
|
+
gap: 0.5rem;
|
|
114
|
+
background-color: hsl(var(--muted));
|
|
115
|
+
padding: 0.5rem 1rem;
|
|
116
|
+
border-bottom: 1px solid hsl(var(--border));
|
|
117
|
+
color: hsl(var(--muted-foreground));
|
|
118
|
+
font-family: monospace;
|
|
119
|
+
font-size: 0.8rem;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.code-block-actions {
|
|
123
|
+
position: absolute;
|
|
124
|
+
top: 0.5rem;
|
|
125
|
+
right: 0.75rem;
|
|
126
|
+
z-index: 10;
|
|
127
|
+
}
|
|
128
|
+
.code-block-actions button {
|
|
129
|
+
color: hsl(var(--muted-foreground));
|
|
130
|
+
transition: color 0.2s ease-in-out;
|
|
131
|
+
}
|
|
132
|
+
.code-block-actions button:hover {
|
|
133
|
+
color: hsl(var(--foreground));
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
.code-block-body pre[class*="language-"] {
|
|
138
|
+
margin: 0 !important;
|
|
139
|
+
padding: 0 !important;
|
|
140
|
+
background: transparent !important;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.line-numbers-wrapper {
|
|
144
|
+
position: absolute;
|
|
145
|
+
top: 0;
|
|
146
|
+
left: 0;
|
|
147
|
+
width: 3rem;
|
|
148
|
+
padding-top: 1rem;
|
|
149
|
+
text-align: right;
|
|
150
|
+
color: var(--line-number-color);
|
|
151
|
+
user-select: none;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.line-highlight {
|
|
155
|
+
position: absolute;
|
|
156
|
+
left: 0;
|
|
157
|
+
right: 0;
|
|
158
|
+
background: hsl(var(--primary) / 0.1);
|
|
159
|
+
border-left: 2px solid hsl(var(--primary));
|
|
160
|
+
pointer-events: none;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.code-block-body pre[data-line-numbers="true"] .line-highlight {
|
|
164
|
+
padding-left: 3.5rem;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.code-block-body::-webkit-scrollbar {
|
|
168
|
+
height: 8px;
|
|
169
|
+
}
|
|
170
|
+
.code-block-body::-webkit-scrollbar-track {
|
|
171
|
+
background: transparent;
|
|
172
|
+
}
|
|
173
|
+
.code-block-body::-webkit-scrollbar-thumb {
|
|
174
|
+
background: hsl(var(--border));
|
|
175
|
+
border-radius: 4px;
|
|
176
|
+
}
|
|
177
|
+
.code-block-body::-webkit-scrollbar-thumb:hover {
|
|
178
|
+
background: hsl(var(--muted));
|
|
179
|
+
}
|