doccupine 0.0.27 → 0.0.29

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/dist/index.js CHANGED
@@ -575,7 +575,15 @@ class MDXToNextJSGenerator {
575
575
  }
576
576
  const pageContent = `import { Metadata } from "next";
577
577
  import { Docs } from "@/components/Docs";
578
- import config from "@/config.json";
578
+ import configData from "@/config.json";
579
+
580
+ interface Config {
581
+ name?: string;
582
+ icon?: string;
583
+ preview?: string;
584
+ }
585
+
586
+ const config = configData as Config;
579
587
 
580
588
  const content = \`${mdxFile.content.replace(/`/g, "\\`")}\`;
581
589
 
@@ -621,7 +629,15 @@ export default function Page() {
621
629
  }
622
630
  const indexContent = `import { Metadata } from "next";
623
631
  import { Docs } from "@/components/Docs";
624
- import config from "@/config.json";
632
+ import configData from "@/config.json";
633
+
634
+ interface Config {
635
+ name?: string;
636
+ icon?: string;
637
+ preview?: string;
638
+ }
639
+
640
+ const config = configData as Config;
625
641
 
626
642
  ${indexMDX ? `const indexContent = \`${indexMDX.content.replace(/`/g, "\\`")}\`;` : `const indexContent = null;`}
627
643
 
@@ -837,7 +853,7 @@ export default function Home() {
837
853
  program
838
854
  .name("doccupine")
839
855
  .description("Watch MDX files and generate Next.js documentation pages automatically")
840
- .version("0.0.27");
856
+ .version("0.0.29");
841
857
  program
842
858
  .command("watch", { isDefault: true })
843
859
  .description("Watch a directory for MDX changes and generate Next.js app")
@@ -1 +1 @@
1
- export declare const codeTemplate = "\"use client\";\nimport { useState, useCallback } from \"react\";\nimport styled from \"styled-components\";\nimport { Theme, styledCode } from \"cherry-styled-components/src/lib\";\nimport { rgba } from \"polished\";\nimport { unified } from \"unified\";\nimport rehypeParse from \"rehype-parse\";\nimport rehypeHighlight from \"rehype-highlight\";\nimport rehypeStringify from \"rehype-stringify\";\nimport { editableContent } from \"@/components/layout/SharedStyled\";\nimport { Icon } from \"@/components/layout/Icon\";\n\ninterface CodeProps extends React.HTMLAttributes<HTMLDivElement> {\n code: string;\n language?: string;\n theme?: Theme;\n}\n\nconst CodeWrapper = styled.span<{ theme: Theme }>`\n position: relative;\n z-index: 2;\n display: block;\n width: 100%;\n border-radius: ${({ theme }) => theme.spacing.radius.lg};\n border: solid 1px\n ${({ theme }) =>\n theme.isDark ? rgba(theme.colors.dark, 0.2) : rgba(theme.colors.dark, 0)};\n`;\n\nconst TopBar = styled.div<{ theme: Theme }>`\n background: #0d1117;\n border-top-left-radius: ${({ theme }) => theme.spacing.radius.lg};\n border-top-right-radius: ${({ theme }) => theme.spacing.radius.lg};\n border-bottom: solid 1px ${rgba(\"#ffffff\", 0.1)};\n height: 33px;\n width: 100%;\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 5px;\n padding: 0 10px;\n`;\n\nconst DotsContainer = styled.div`\n display: flex;\n gap: 5px;\n`;\n\nconst Dot = styled.span<{ theme: Theme }>`\n width: 10px;\n height: 10px;\n border-radius: 50%;\n background: ${rgba(\"#ffffff\", 0.1)};\n`;\n\nconst CopyButton = styled.button<{ theme: Theme; $copied: boolean }>`\n background: ${({ $copied }) =>\n $copied ? rgba(\"#7ee787\", 0.2) : \"transparent\"};\n border: solid 1px\n ${({ $copied }) => ($copied ? \"#7ee787\" : rgba(\"#ffffff\", 0.1))};\n color: ${({ $copied }) => ($copied ? \"#7ee787\" : \"#c9d1d9\")};\n border-radius: ${({ theme }) => theme.spacing.radius.xs};\n padding: 4px 8px;\n font-size: 12px;\n font-family: ${({ theme }) => theme.fonts.mono};\n cursor: pointer;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n gap: 4px;\n margin-right: -6px;\n\n & svg.lucide {\n color: ${({ $copied }) => ($copied ? \"#7ee787\" : \"#c9d1d9\")};\n }\n\n &:hover {\n background: ${({ $copied }) =>\n $copied ? rgba(\"#7ee787\", 0.3) : rgba(\"#ffffff\", 0.1)};\n border-color: ${({ $copied }) =>\n $copied ? \"#7ee787\" : rgba(\"#ffffff\", 0.2)};\n }\n\n &:active {\n transform: scale(0.95);\n }\n`;\n\nconst Body = styled.div<{ theme: Theme }>`\n background: #0d1117;\n border-bottom-left-radius: ${({ theme }) => theme.spacing.radius.lg};\n border-bottom-right-radius: ${({ theme }) => theme.spacing.radius.lg};\n color: #ffffff;\n padding: 20px;\n font-family: ${({ theme }) => theme.fonts.mono};\n text-align: left;\n overflow-x: auto;\n overflow-y: auto;\n max-height: calc(100svh - 400px);\n ${({ theme }) => styledCode(theme)};\n\n &[contenteditable=\"true\"] {\n ${editableContent};\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n }\n\n & .hljs {\n color: #c9d1d9;\n background: #0d1117;\n }\n\n & .hljs-doctag,\n & .hljs-keyword,\n & .hljs-meta .hljs-keyword,\n & .hljs-template-tag,\n & .hljs-template-variable,\n & .hljs-type,\n & .hljs-variable.language_ {\n color: #ff7b72;\n }\n\n & .hljs-title,\n & .hljs-title.class_,\n & .hljs-title.class_.inherited__,\n & .hljs-title.function_ {\n color: #d2a8ff;\n }\n\n & .hljs-attr,\n & .hljs-attribute,\n & .hljs-literal,\n & .hljs-meta,\n & .hljs-number,\n & .hljs-operator,\n & .hljs-selector-attr,\n & .hljs-selector-class,\n & .hljs-selector-id,\n & .hljs-variable {\n color: #79c0ff;\n }\n\n & .hljs-meta .hljs-string,\n & .hljs-regexp,\n & .hljs-string {\n color: #a5d6ff;\n }\n\n & .hljs-built_in,\n & .hljs-symbol {\n color: #ffa657;\n }\n\n & .hljs-code,\n & .hljs-comment,\n & .hljs-formula {\n color: #8b949e;\n }\n\n & .hljs-name,\n & .hljs-quote,\n & .hljs-selector-pseudo,\n & .hljs-selector-tag {\n color: #7ee787;\n }\n\n & .hljs-subst {\n color: #c9d1d9;\n }\n\n & .hljs-section {\n color: #1f6feb;\n font-weight: 700;\n }\n\n & .hljs-bullet {\n color: #f2cc60;\n }\n\n & .hljs-emphasis {\n color: #c9d1d9;\n font-style: italic;\n }\n\n & .hljs-strong {\n color: #c9d1d9;\n font-weight: 700;\n }\n\n & .hljs-addition {\n color: #aff5b4;\n background-color: #033a16;\n }\n\n & .hljs-deletion {\n color: #ffdcd7;\n background-color: #67060c;\n }\n`;\n\nconst escapeHtml = (unsafe: string): string => {\n return unsafe\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#039;\");\n};\n\nconst highlightCode = (code: string, language: string): string => {\n const escapedCode = escapeHtml(code);\n const result = unified()\n .use(rehypeParse, { fragment: true })\n .use(rehypeHighlight, {\n detect: true,\n ignoreMissing: true,\n })\n .use(rehypeStringify)\n .processSync(\n `<pre><code class=\"language-${language}\">${escapedCode}</code></pre>`,\n );\n\n return String(result);\n};\n\nfunction Code({ code, language = \"javascript\", ...props }: CodeProps) {\n const [copied, setCopied] = useState(false);\n const highlightedCode = highlightCode(code, language);\n\n const handleCopy = useCallback(async () => {\n try {\n await navigator.clipboard.writeText(code);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n } catch (err) {\n console.error(\"Failed to copy code:\", err);\n }\n }, [code]);\n\n return (\n <CodeWrapper className=\"code-wrapper\">\n <TopBar>\n <DotsContainer>\n <Dot />\n <Dot />\n <Dot />\n </DotsContainer>\n <CopyButton onClick={handleCopy} $copied={copied}>\n {copied ? (\n <>\n <Icon name=\"check\" size={12} />\n <span>Copied!</span>\n </>\n ) : (\n <>\n <Icon name=\"copy\" size={12} />\n <span>Copy</span>\n </>\n )}\n </CopyButton>\n </TopBar>\n <Body dangerouslySetInnerHTML={{ __html: highlightedCode }} {...props} />\n </CodeWrapper>\n );\n}\n\nexport { Code };\n";
1
+ export declare const codeTemplate = "\"use client\";\nimport { useState, useCallback } from \"react\";\nimport styled from \"styled-components\";\nimport { Theme, styledCode } from \"cherry-styled-components/src/lib\";\nimport { rgba } from \"polished\";\nimport { unified } from \"unified\";\nimport rehypeParse from \"rehype-parse\";\nimport rehypeHighlight from \"rehype-highlight\";\nimport rehypeStringify from \"rehype-stringify\";\nimport { editableContent } from \"@/components/layout/SharedStyled\";\nimport { Icon } from \"@/components/layout/Icon\";\n\ninterface CodeProps extends React.HTMLAttributes<HTMLDivElement> {\n code: string;\n language?: string;\n theme?: Theme;\n}\n\nconst CodeWrapper = styled.span<{ theme: Theme }>`\n position: relative;\n z-index: 2;\n display: block;\n width: 100%;\n border-radius: ${({ theme }) => theme.spacing.radius.lg};\n border: solid 1px\n ${({ theme }) =>\n theme.isDark\n ? rgba(theme.colors.dark, 0.2)\n : rgba(theme.colors.dark, 0.1)};\n`;\n\nconst TopBar = styled.div<{ theme: Theme }>`\n background: ${({ theme }) => (theme.isDark ? \"#0d1117\" : \"#f6f8fa\")};\n border-top-left-radius: ${({ theme }) => theme.spacing.radius.lg};\n border-top-right-radius: ${({ theme }) => theme.spacing.radius.lg};\n border-bottom: solid 1px\n ${({ theme }) =>\n theme.isDark ? rgba(\"#ffffff\", 0.1) : rgba(\"#000000\", 0.1)};\n height: 33px;\n width: 100%;\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 5px;\n padding: 0 10px;\n`;\n\nconst DotsContainer = styled.div`\n display: flex;\n gap: 5px;\n`;\n\nconst Dot = styled.span<{ theme: Theme }>`\n width: 10px;\n height: 10px;\n border-radius: 50%;\n background: ${({ theme }) =>\n theme.isDark ? rgba(\"#ffffff\", 0.1) : rgba(\"#000000\", 0.1)};\n`;\n\nconst CopyButton = styled.button<{ theme: Theme; $copied: boolean }>`\n background: ${({ theme, $copied }) =>\n $copied\n ? theme.isDark\n ? rgba(\"#7ee787\", 0.2)\n : rgba(\"#2da44e\", 0.1)\n : \"transparent\"};\n border: solid 1px\n ${({ theme, $copied }) =>\n $copied\n ? theme.isDark\n ? \"#7ee787\"\n : \"#2da44e\"\n : theme.isDark\n ? rgba(\"#ffffff\", 0.1)\n : rgba(\"#000000\", 0.1)};\n color: ${({ theme, $copied }) =>\n $copied\n ? theme.isDark\n ? \"#7ee787\"\n : \"#2da44e\"\n : theme.isDark\n ? \"#c9d1d9\"\n : \"#57606a\"};\n border-radius: ${({ theme }) => theme.spacing.radius.xs};\n padding: 4px 8px;\n font-size: 12px;\n font-family: ${({ theme }) => theme.fonts.mono};\n cursor: pointer;\n transition: all 0.2s ease;\n display: flex;\n align-items: center;\n gap: 4px;\n margin-right: -6px;\n\n & svg.lucide {\n color: ${({ theme, $copied }) =>\n $copied\n ? theme.isDark\n ? \"#7ee787\"\n : \"#2da44e\"\n : theme.isDark\n ? \"#c9d1d9\"\n : \"#57606a\"};\n }\n\n &:hover {\n background: ${({ theme, $copied }) =>\n $copied\n ? theme.isDark\n ? rgba(\"#7ee787\", 0.3)\n : rgba(\"#2da44e\", 0.2)\n : theme.isDark\n ? rgba(\"#ffffff\", 0.1)\n : rgba(\"#000000\", 0.05)};\n border-color: ${({ theme, $copied }) =>\n $copied\n ? theme.isDark\n ? \"#7ee787\"\n : \"#2da44e\"\n : theme.isDark\n ? rgba(\"#ffffff\", 0.2)\n : rgba(\"#000000\", 0.2)};\n }\n\n &:active {\n transform: scale(0.95);\n }\n`;\n\nconst Body = styled.div<{ theme: Theme }>`\n background: ${({ theme }) => (theme.isDark ? \"#0d1117\" : \"#ffffff\")};\n border-bottom-left-radius: ${({ theme }) => theme.spacing.radius.lg};\n border-bottom-right-radius: ${({ theme }) => theme.spacing.radius.lg};\n color: ${({ theme }) => (theme.isDark ? \"#ffffff\" : \"#24292f\")};\n padding: 20px;\n font-family: ${({ theme }) => theme.fonts.mono};\n text-align: left;\n overflow-x: auto;\n overflow-y: auto;\n max-height: calc(100svh - 400px);\n ${({ theme }) => styledCode(theme)};\n\n &[contenteditable=\"true\"] {\n ${editableContent};\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n }\n\n /* Dark mode syntax highlighting (GitHub Dark) */\n ${({ theme }) =>\n theme.isDark &&\n `\n & .hljs {\n color: #c9d1d9;\n background: #0d1117;\n }\n\n & .hljs-doctag,\n & .hljs-keyword,\n & .hljs-meta .hljs-keyword,\n & .hljs-template-tag,\n & .hljs-template-variable,\n & .hljs-type,\n & .hljs-variable.language_ {\n color: #ff7b72;\n }\n\n & .hljs-title,\n & .hljs-title.class_,\n & .hljs-title.class_.inherited__,\n & .hljs-title.function_ {\n color: #d2a8ff;\n }\n\n & .hljs-attr,\n & .hljs-attribute,\n & .hljs-literal,\n & .hljs-meta,\n & .hljs-number,\n & .hljs-operator,\n & .hljs-selector-attr,\n & .hljs-selector-class,\n & .hljs-selector-id,\n & .hljs-variable {\n color: #79c0ff;\n }\n\n & .hljs-meta .hljs-string,\n & .hljs-regexp,\n & .hljs-string {\n color: #a5d6ff;\n }\n\n & .hljs-built_in,\n & .hljs-symbol {\n color: #ffa657;\n }\n\n & .hljs-code,\n & .hljs-comment,\n & .hljs-formula {\n color: #8b949e;\n }\n\n & .hljs-name,\n & .hljs-quote,\n & .hljs-selector-pseudo,\n & .hljs-selector-tag {\n color: #7ee787;\n }\n\n & .hljs-subst {\n color: #c9d1d9;\n }\n\n & .hljs-section {\n color: #1f6feb;\n font-weight: 700;\n }\n\n & .hljs-bullet {\n color: #f2cc60;\n }\n\n & .hljs-emphasis {\n color: #c9d1d9;\n font-style: italic;\n }\n\n & .hljs-strong {\n color: #c9d1d9;\n font-weight: 700;\n }\n\n & .hljs-addition {\n color: #aff5b4;\n background-color: #033a16;\n }\n\n & .hljs-deletion {\n color: #ffdcd7;\n background-color: #67060c;\n }\n `}\n\n /* Light mode syntax highlighting (GitHub Light) */\n ${({ theme }) =>\n !theme.isDark &&\n `\n & .hljs {\n color: #24292f;\n background: #ffffff;\n }\n\n & .hljs-doctag,\n & .hljs-keyword,\n & .hljs-meta .hljs-keyword,\n & .hljs-template-tag,\n & .hljs-template-variable,\n & .hljs-type,\n & .hljs-variable.language_ {\n color: #cf222e;\n }\n\n & .hljs-title,\n & .hljs-title.class_,\n & .hljs-title.class_.inherited__,\n & .hljs-title.function_ {\n color: #8250df;\n }\n\n & .hljs-attr,\n & .hljs-attribute,\n & .hljs-literal,\n & .hljs-meta,\n & .hljs-number,\n & .hljs-operator,\n & .hljs-selector-attr,\n & .hljs-selector-class,\n & .hljs-selector-id,\n & .hljs-variable {\n color: #0550ae;\n }\n\n & .hljs-meta .hljs-string,\n & .hljs-regexp,\n & .hljs-string {\n color: #0a3069;\n }\n\n & .hljs-built_in,\n & .hljs-symbol {\n color: #953800;\n }\n\n & .hljs-code,\n & .hljs-comment,\n & .hljs-formula {\n color: #6e7781;\n }\n\n & .hljs-name,\n & .hljs-quote,\n & .hljs-selector-pseudo,\n & .hljs-selector-tag {\n color: #116329;\n }\n\n & .hljs-subst {\n color: #24292f;\n }\n\n & .hljs-section {\n color: #0550ae;\n font-weight: 700;\n }\n\n & .hljs-bullet {\n color: #953800;\n }\n\n & .hljs-emphasis {\n color: #24292f;\n font-style: italic;\n }\n\n & .hljs-strong {\n color: #24292f;\n font-weight: 700;\n }\n\n & .hljs-addition {\n color: #116329;\n background-color: #dafbe1;\n }\n\n & .hljs-deletion {\n color: #82071e;\n background-color: #ffebe9;\n }\n `}\n`;\n\nconst escapeHtml = (unsafe: string): string => {\n return unsafe\n .replace(/&/g, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#039;\");\n};\n\nconst highlightCode = (code: string, language: string): string => {\n const escapedCode = escapeHtml(code);\n const result = unified()\n .use(rehypeParse, { fragment: true })\n .use(rehypeHighlight, {\n detect: true,\n ignoreMissing: true,\n })\n .use(rehypeStringify)\n .processSync(\n `<pre><code class=\"language-${language}\">${escapedCode}</code></pre>`,\n );\n\n return String(result);\n};\n\nfunction Code({ code, language = \"javascript\", ...props }: CodeProps) {\n const [copied, setCopied] = useState(false);\n const highlightedCode = highlightCode(code, language);\n\n const handleCopy = useCallback(async () => {\n try {\n await navigator.clipboard.writeText(code);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n } catch (err) {\n console.error(\"Failed to copy code:\", err);\n }\n }, [code]);\n\n return (\n <CodeWrapper className=\"code-wrapper\">\n <TopBar>\n <DotsContainer>\n <Dot />\n <Dot />\n <Dot />\n </DotsContainer>\n <CopyButton onClick={handleCopy} $copied={copied}>\n {copied ? (\n <>\n <Icon name=\"check\" size={12} />\n <span>Copied!</span>\n </>\n ) : (\n <>\n <Icon name=\"copy\" size={12} />\n <span>Copy</span>\n </>\n )}\n </CopyButton>\n </TopBar>\n <Body dangerouslySetInnerHTML={{ __html: highlightedCode }} {...props} />\n </CodeWrapper>\n );\n}\n\nexport { Code };\n";
@@ -24,14 +24,18 @@ const CodeWrapper = styled.span<{ theme: Theme }>\`
24
24
  border-radius: \${({ theme }) => theme.spacing.radius.lg};
25
25
  border: solid 1px
26
26
  \${({ theme }) =>
27
- theme.isDark ? rgba(theme.colors.dark, 0.2) : rgba(theme.colors.dark, 0)};
27
+ theme.isDark
28
+ ? rgba(theme.colors.dark, 0.2)
29
+ : rgba(theme.colors.dark, 0.1)};
28
30
  \`;
29
31
 
30
32
  const TopBar = styled.div<{ theme: Theme }>\`
31
- background: #0d1117;
33
+ background: \${({ theme }) => (theme.isDark ? "#0d1117" : "#f6f8fa")};
32
34
  border-top-left-radius: \${({ theme }) => theme.spacing.radius.lg};
33
35
  border-top-right-radius: \${({ theme }) => theme.spacing.radius.lg};
34
- border-bottom: solid 1px \${rgba("#ffffff", 0.1)};
36
+ border-bottom: solid 1px
37
+ \${({ theme }) =>
38
+ theme.isDark ? rgba("#ffffff", 0.1) : rgba("#000000", 0.1)};
35
39
  height: 33px;
36
40
  width: 100%;
37
41
  display: flex;
@@ -50,15 +54,34 @@ const Dot = styled.span<{ theme: Theme }>\`
50
54
  width: 10px;
51
55
  height: 10px;
52
56
  border-radius: 50%;
53
- background: \${rgba("#ffffff", 0.1)};
57
+ background: \${({ theme }) =>
58
+ theme.isDark ? rgba("#ffffff", 0.1) : rgba("#000000", 0.1)};
54
59
  \`;
55
60
 
56
61
  const CopyButton = styled.button<{ theme: Theme; $copied: boolean }>\`
57
- background: \${({ $copied }) =>
58
- $copied ? rgba("#7ee787", 0.2) : "transparent"};
62
+ background: \${({ theme, $copied }) =>
63
+ $copied
64
+ ? theme.isDark
65
+ ? rgba("#7ee787", 0.2)
66
+ : rgba("#2da44e", 0.1)
67
+ : "transparent"};
59
68
  border: solid 1px
60
- \${({ $copied }) => ($copied ? "#7ee787" : rgba("#ffffff", 0.1))};
61
- color: \${({ $copied }) => ($copied ? "#7ee787" : "#c9d1d9")};
69
+ \${({ theme, $copied }) =>
70
+ $copied
71
+ ? theme.isDark
72
+ ? "#7ee787"
73
+ : "#2da44e"
74
+ : theme.isDark
75
+ ? rgba("#ffffff", 0.1)
76
+ : rgba("#000000", 0.1)};
77
+ color: \${({ theme, $copied }) =>
78
+ $copied
79
+ ? theme.isDark
80
+ ? "#7ee787"
81
+ : "#2da44e"
82
+ : theme.isDark
83
+ ? "#c9d1d9"
84
+ : "#57606a"};
62
85
  border-radius: \${({ theme }) => theme.spacing.radius.xs};
63
86
  padding: 4px 8px;
64
87
  font-size: 12px;
@@ -71,14 +94,33 @@ const CopyButton = styled.button<{ theme: Theme; $copied: boolean }>\`
71
94
  margin-right: -6px;
72
95
 
73
96
  & svg.lucide {
74
- color: \${({ $copied }) => ($copied ? "#7ee787" : "#c9d1d9")};
97
+ color: \${({ theme, $copied }) =>
98
+ $copied
99
+ ? theme.isDark
100
+ ? "#7ee787"
101
+ : "#2da44e"
102
+ : theme.isDark
103
+ ? "#c9d1d9"
104
+ : "#57606a"};
75
105
  }
76
106
 
77
107
  &:hover {
78
- background: \${({ $copied }) =>
79
- $copied ? rgba("#7ee787", 0.3) : rgba("#ffffff", 0.1)};
80
- border-color: \${({ $copied }) =>
81
- $copied ? "#7ee787" : rgba("#ffffff", 0.2)};
108
+ background: \${({ theme, $copied }) =>
109
+ $copied
110
+ ? theme.isDark
111
+ ? rgba("#7ee787", 0.3)
112
+ : rgba("#2da44e", 0.2)
113
+ : theme.isDark
114
+ ? rgba("#ffffff", 0.1)
115
+ : rgba("#000000", 0.05)};
116
+ border-color: \${({ theme, $copied }) =>
117
+ $copied
118
+ ? theme.isDark
119
+ ? "#7ee787"
120
+ : "#2da44e"
121
+ : theme.isDark
122
+ ? rgba("#ffffff", 0.2)
123
+ : rgba("#000000", 0.2)};
82
124
  }
83
125
 
84
126
  &:active {
@@ -87,10 +129,10 @@ const CopyButton = styled.button<{ theme: Theme; $copied: boolean }>\`
87
129
  \`;
88
130
 
89
131
  const Body = styled.div<{ theme: Theme }>\`
90
- background: #0d1117;
132
+ background: \${({ theme }) => (theme.isDark ? "#0d1117" : "#ffffff")};
91
133
  border-bottom-left-radius: \${({ theme }) => theme.spacing.radius.lg};
92
134
  border-bottom-right-radius: \${({ theme }) => theme.spacing.radius.lg};
93
- color: #ffffff;
135
+ color: \${({ theme }) => (theme.isDark ? "#ffffff" : "#24292f")};
94
136
  padding: 20px;
95
137
  font-family: \${({ theme }) => theme.fonts.mono};
96
138
  text-align: left;
@@ -105,97 +147,199 @@ const Body = styled.div<{ theme: Theme }>\`
105
147
  border-top-right-radius: 0;
106
148
  }
107
149
 
108
- & .hljs {
109
- color: #c9d1d9;
110
- background: #0d1117;
111
- }
150
+ /* Dark mode syntax highlighting (GitHub Dark) */
151
+ \${({ theme }) =>
152
+ theme.isDark &&
153
+ \`
154
+ & .hljs {
155
+ color: #c9d1d9;
156
+ background: #0d1117;
157
+ }
112
158
 
113
- & .hljs-doctag,
114
- & .hljs-keyword,
115
- & .hljs-meta .hljs-keyword,
116
- & .hljs-template-tag,
117
- & .hljs-template-variable,
118
- & .hljs-type,
119
- & .hljs-variable.language_ {
120
- color: #ff7b72;
121
- }
159
+ & .hljs-doctag,
160
+ & .hljs-keyword,
161
+ & .hljs-meta .hljs-keyword,
162
+ & .hljs-template-tag,
163
+ & .hljs-template-variable,
164
+ & .hljs-type,
165
+ & .hljs-variable.language_ {
166
+ color: #ff7b72;
167
+ }
122
168
 
123
- & .hljs-title,
124
- & .hljs-title.class_,
125
- & .hljs-title.class_.inherited__,
126
- & .hljs-title.function_ {
127
- color: #d2a8ff;
128
- }
169
+ & .hljs-title,
170
+ & .hljs-title.class_,
171
+ & .hljs-title.class_.inherited__,
172
+ & .hljs-title.function_ {
173
+ color: #d2a8ff;
174
+ }
129
175
 
130
- & .hljs-attr,
131
- & .hljs-attribute,
132
- & .hljs-literal,
133
- & .hljs-meta,
134
- & .hljs-number,
135
- & .hljs-operator,
136
- & .hljs-selector-attr,
137
- & .hljs-selector-class,
138
- & .hljs-selector-id,
139
- & .hljs-variable {
140
- color: #79c0ff;
141
- }
176
+ & .hljs-attr,
177
+ & .hljs-attribute,
178
+ & .hljs-literal,
179
+ & .hljs-meta,
180
+ & .hljs-number,
181
+ & .hljs-operator,
182
+ & .hljs-selector-attr,
183
+ & .hljs-selector-class,
184
+ & .hljs-selector-id,
185
+ & .hljs-variable {
186
+ color: #79c0ff;
187
+ }
142
188
 
143
- & .hljs-meta .hljs-string,
144
- & .hljs-regexp,
145
- & .hljs-string {
146
- color: #a5d6ff;
147
- }
189
+ & .hljs-meta .hljs-string,
190
+ & .hljs-regexp,
191
+ & .hljs-string {
192
+ color: #a5d6ff;
193
+ }
148
194
 
149
- & .hljs-built_in,
150
- & .hljs-symbol {
151
- color: #ffa657;
152
- }
195
+ & .hljs-built_in,
196
+ & .hljs-symbol {
197
+ color: #ffa657;
198
+ }
153
199
 
154
- & .hljs-code,
155
- & .hljs-comment,
156
- & .hljs-formula {
157
- color: #8b949e;
158
- }
200
+ & .hljs-code,
201
+ & .hljs-comment,
202
+ & .hljs-formula {
203
+ color: #8b949e;
204
+ }
159
205
 
160
- & .hljs-name,
161
- & .hljs-quote,
162
- & .hljs-selector-pseudo,
163
- & .hljs-selector-tag {
164
- color: #7ee787;
165
- }
206
+ & .hljs-name,
207
+ & .hljs-quote,
208
+ & .hljs-selector-pseudo,
209
+ & .hljs-selector-tag {
210
+ color: #7ee787;
211
+ }
166
212
 
167
- & .hljs-subst {
168
- color: #c9d1d9;
169
- }
213
+ & .hljs-subst {
214
+ color: #c9d1d9;
215
+ }
170
216
 
171
- & .hljs-section {
172
- color: #1f6feb;
173
- font-weight: 700;
174
- }
217
+ & .hljs-section {
218
+ color: #1f6feb;
219
+ font-weight: 700;
220
+ }
175
221
 
176
- & .hljs-bullet {
177
- color: #f2cc60;
178
- }
222
+ & .hljs-bullet {
223
+ color: #f2cc60;
224
+ }
179
225
 
180
- & .hljs-emphasis {
181
- color: #c9d1d9;
182
- font-style: italic;
183
- }
226
+ & .hljs-emphasis {
227
+ color: #c9d1d9;
228
+ font-style: italic;
229
+ }
184
230
 
185
- & .hljs-strong {
186
- color: #c9d1d9;
187
- font-weight: 700;
188
- }
231
+ & .hljs-strong {
232
+ color: #c9d1d9;
233
+ font-weight: 700;
234
+ }
189
235
 
190
- & .hljs-addition {
191
- color: #aff5b4;
192
- background-color: #033a16;
193
- }
236
+ & .hljs-addition {
237
+ color: #aff5b4;
238
+ background-color: #033a16;
239
+ }
194
240
 
195
- & .hljs-deletion {
196
- color: #ffdcd7;
197
- background-color: #67060c;
198
- }
241
+ & .hljs-deletion {
242
+ color: #ffdcd7;
243
+ background-color: #67060c;
244
+ }
245
+ \`}
246
+
247
+ /* Light mode syntax highlighting (GitHub Light) */
248
+ \${({ theme }) =>
249
+ !theme.isDark &&
250
+ \`
251
+ & .hljs {
252
+ color: #24292f;
253
+ background: #ffffff;
254
+ }
255
+
256
+ & .hljs-doctag,
257
+ & .hljs-keyword,
258
+ & .hljs-meta .hljs-keyword,
259
+ & .hljs-template-tag,
260
+ & .hljs-template-variable,
261
+ & .hljs-type,
262
+ & .hljs-variable.language_ {
263
+ color: #cf222e;
264
+ }
265
+
266
+ & .hljs-title,
267
+ & .hljs-title.class_,
268
+ & .hljs-title.class_.inherited__,
269
+ & .hljs-title.function_ {
270
+ color: #8250df;
271
+ }
272
+
273
+ & .hljs-attr,
274
+ & .hljs-attribute,
275
+ & .hljs-literal,
276
+ & .hljs-meta,
277
+ & .hljs-number,
278
+ & .hljs-operator,
279
+ & .hljs-selector-attr,
280
+ & .hljs-selector-class,
281
+ & .hljs-selector-id,
282
+ & .hljs-variable {
283
+ color: #0550ae;
284
+ }
285
+
286
+ & .hljs-meta .hljs-string,
287
+ & .hljs-regexp,
288
+ & .hljs-string {
289
+ color: #0a3069;
290
+ }
291
+
292
+ & .hljs-built_in,
293
+ & .hljs-symbol {
294
+ color: #953800;
295
+ }
296
+
297
+ & .hljs-code,
298
+ & .hljs-comment,
299
+ & .hljs-formula {
300
+ color: #6e7781;
301
+ }
302
+
303
+ & .hljs-name,
304
+ & .hljs-quote,
305
+ & .hljs-selector-pseudo,
306
+ & .hljs-selector-tag {
307
+ color: #116329;
308
+ }
309
+
310
+ & .hljs-subst {
311
+ color: #24292f;
312
+ }
313
+
314
+ & .hljs-section {
315
+ color: #0550ae;
316
+ font-weight: 700;
317
+ }
318
+
319
+ & .hljs-bullet {
320
+ color: #953800;
321
+ }
322
+
323
+ & .hljs-emphasis {
324
+ color: #24292f;
325
+ font-style: italic;
326
+ }
327
+
328
+ & .hljs-strong {
329
+ color: #24292f;
330
+ font-weight: 700;
331
+ }
332
+
333
+ & .hljs-addition {
334
+ color: #116329;
335
+ background-color: #dafbe1;
336
+ }
337
+
338
+ & .hljs-deletion {
339
+ color: #82071e;
340
+ background-color: #ffebe9;
341
+ }
342
+ \`}
199
343
  \`;
200
344
 
201
345
  const escapeHtml = (unsafe: string): string => {
@@ -1 +1 @@
1
- export declare const indexMdxTemplate = "---\ntitle: \"Getting Started\"\ndescription: \"Doccupine is a free and open-source document management system that allows you to store, organize, and share your documentation with ease.\"\ndate: \"2025-01-15\"\ncategory: \"General\"\ncategoryOrder: 0\norder: 0\n---\n# Welcome to Doccupine\nUsing Doccupine, you simply create your documentation in MDX files with traditional Markdown syntax, Doccupine monitors your changes automatically generating a beautiful, modern documentation website.\n\n## Features\n\n<Columns cols={2}>\n <Card>\n <img src=\"https://doccupine.com/mdx.svg\" alt=\"Markdown-based content\" className=\"full-width\" />\n <Space $size={12} />\n Markdown-based content\n </Card>\n <Card>\n <img src=\"https://doccupine.com/structure.svg\" alt=\"Built-in file structure\" className=\"full-width\" />\n <Space $size={12} />\n Built-in file structure\n </Card>\n <Card>\n <img src=\"https://doccupine.com/live-reload.svg\" alt=\"Live Preview & Auto-Update\" className=\"full-width\" />\n <Space $size={12} />\n Live Preview & Auto-Update\n </Card>\n <Card>\n <img src=\"https://doccupine.com/deployment.svg\" alt=\"Easy Deployment\" className=\"full-width\" />\n <Space $size={12} />\n Easy Deployment\n </Card>\n</Columns>\n\n## Getting Started\n\nTo get started with Doccupine, make sure you have [Node.js](https://nodejs.org) and npm installed on your machine. Then, follow these steps:\n\n- **Run Doccupine CLI:**\n\nCreate a new directory for your project and navigate to it in your terminal. Run the following command to create a new Doccupine project:\n\n```bash\nnpx doccupine\n```\n\nOnce you run the command, Doccupine will ask you to select a directory to store your MDX files. Choose the directory where you want to create your documentation files.\nAfter selecting the directory, Doccupine will ask you to enter the name of the directory for the generated website. Enter the name of the directory where you want to create your website.\n\nThis will start the development server on port 3000. Open your browser and navigate to http://localhost:3000 to view your documentation.\n\n## Start documenting\nStart documenting your project by editing the **index.mdx** file in the choosen MDX directory.\n\nIn your MDX directory, you can structure your content using folders and files. Doccupine will automatically generate a navigation menu based on the configured categories and order.\n";
1
+ export declare const indexMdxTemplate = "---\ntitle: \"Getting Started\"\ndescription: \"Doccupine is a free and open-source document management system that allows you to store, organize, and share your documentation with ease.\"\ndate: \"2025-01-15\"\ncategory: \"General\"\ncategoryOrder: 0\norder: 0\n---\n# Welcome to Doccupine\nUsing Doccupine, you simply create your documentation in MDX files with traditional Markdown syntax, Doccupine monitors your changes automatically generating a beautiful, modern documentation website.\n\n## Getting Started\n\nTo get started with Doccupine, make sure you have [Node.js](https://nodejs.org) and npm installed on your machine. Then, follow these steps:\n\n- **Run Doccupine CLI:**\n\nCreate a new directory for your project and navigate to it in your terminal. Run the following command to create a new Doccupine project:\n\n```bash\nnpx doccupine\n```\n\nOnce you run the command, Doccupine will ask you to select a directory to store your MDX files. Choose the directory where you want to create your documentation files.\nAfter selecting the directory, Doccupine will ask you to enter the name of the directory for the generated website. Enter the name of the directory where you want to create your website.\n\nThis will start the development server on port 3000. Open your browser and navigate to http://localhost:3000 to view your documentation.\n\n## Start documenting\nStart documenting your project by editing the **index.mdx** file in the choosen MDX directory.\n\nIn your MDX directory, you can structure your content using folders and files. Doccupine will automatically generate a navigation menu based on the configured categories and order.\n";
@@ -9,31 +9,6 @@ order: 0
9
9
  # Welcome to Doccupine
10
10
  Using Doccupine, you simply create your documentation in MDX files with traditional Markdown syntax, Doccupine monitors your changes automatically generating a beautiful, modern documentation website.
11
11
 
12
- ## Features
13
-
14
- <Columns cols={2}>
15
- <Card>
16
- <img src="https://doccupine.com/mdx.svg" alt="Markdown-based content" className="full-width" />
17
- <Space $size={12} />
18
- Markdown-based content
19
- </Card>
20
- <Card>
21
- <img src="https://doccupine.com/structure.svg" alt="Built-in file structure" className="full-width" />
22
- <Space $size={12} />
23
- Built-in file structure
24
- </Card>
25
- <Card>
26
- <img src="https://doccupine.com/live-reload.svg" alt="Live Preview & Auto-Update" className="full-width" />
27
- <Space $size={12} />
28
- Live Preview & Auto-Update
29
- </Card>
30
- <Card>
31
- <img src="https://doccupine.com/deployment.svg" alt="Easy Deployment" className="full-width" />
32
- <Space $size={12} />
33
- Easy Deployment
34
- </Card>
35
- </Columns>
36
-
37
12
  ## Getting Started
38
13
 
39
14
  To get started with Doccupine, make sure you have [Node.js](https://nodejs.org) and npm installed on your machine. Then, follow these steps:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "doccupine",
3
- "version": "0.0.27",
3
+ "version": "0.0.29",
4
4
  "description": "Generate beautiful, ready-to-use documentation with just one CLI command – fast, simple, and open source.",
5
5
  "main": "dist/index.js",
6
6
  "bin": {