sdocs-dev 1.2.0 → 1.3.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/README.md +149 -0
- package/bin/sdocs-dev.js +282 -38
- package/package.json +13 -11
- package/public/sdocs-slugify.js +12 -0
- package/public/sdocs-styles.js +279 -353
- package/public/brotli-wasm.js +0 -519
- package/public/brotli_wasm_bg.wasm +0 -0
- package/public/css/layout.css +0 -241
- package/public/css/mobile.css +0 -189
- package/public/css/panel.css +0 -393
- package/public/css/rendered.css +0 -295
- package/public/css/tokens.css +0 -116
- package/public/css/write.css +0 -128
- package/public/default.md +0 -255
- package/public/fonts/inter-400.woff2 +0 -0
- package/public/fonts/inter-500.woff2 +0 -0
- package/public/fonts/inter-600.woff2 +0 -0
- package/public/images/examples.png +0 -0
- package/public/index.html +0 -600
- package/public/sdocs-app.js +0 -653
- package/public/sdocs-controls.js +0 -272
- package/public/sdocs-export.js +0 -212
- package/public/sdocs-state.js +0 -59
- package/public/sdocs-theme.js +0 -260
- package/public/sdocs-write.js +0 -737
- package/public/sw.js +0 -108
- package/public/vendor/marked.min.js +0 -6
- package/server.js +0 -128
package/public/css/tokens.css
DELETED
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
@font-face { font-family: 'Inter'; font-style: normal; font-weight: 400; font-display: swap; src: url('/public/fonts/inter-400.woff2') format('woff2'); }
|
|
2
|
-
@font-face { font-family: 'Inter'; font-style: normal; font-weight: 500; font-display: swap; src: url('/public/fonts/inter-500.woff2') format('woff2'); }
|
|
3
|
-
@font-face { font-family: 'Inter'; font-style: normal; font-weight: 600; font-display: swap; src: url('/public/fonts/inter-600.woff2') format('woff2'); }
|
|
4
|
-
|
|
5
|
-
:root {
|
|
6
|
-
--bg: #F7F5F2;
|
|
7
|
-
--bg-surface: #F1EDE8;
|
|
8
|
-
--bg-panel: #EDE8E2;
|
|
9
|
-
--bg-panel-deep: #E7E2DB;
|
|
10
|
-
--bg-input: #FFFFFF;
|
|
11
|
-
--bg-hover: #E8E3DD;
|
|
12
|
-
--bg-active: #E2DDD6;
|
|
13
|
-
|
|
14
|
-
--border: #D4CFC9;
|
|
15
|
-
--border-subtle: #DDD9D3;
|
|
16
|
-
--border-strong: #C5BFB8;
|
|
17
|
-
|
|
18
|
-
--text: #1C1917;
|
|
19
|
-
--text-2: #57534E;
|
|
20
|
-
--text-3: #A8A29E;
|
|
21
|
-
--text-inv: #FAFAF9;
|
|
22
|
-
|
|
23
|
-
--accent: #2563EB;
|
|
24
|
-
--accent-light: #EEF2FF;
|
|
25
|
-
--accent-text: #1D4ED8;
|
|
26
|
-
|
|
27
|
-
--radius-sm: 4px;
|
|
28
|
-
--radius: 6px;
|
|
29
|
-
--radius-md: 8px;
|
|
30
|
-
--radius-lg: 10px;
|
|
31
|
-
|
|
32
|
-
--shadow-sm: 0 1px 2px rgba(28,25,23,.06);
|
|
33
|
-
--shadow: 0 2px 6px rgba(28,25,23,.08), 0 1px 2px rgba(28,25,23,.04);
|
|
34
|
-
--shadow-md: 0 4px 12px rgba(28,25,23,.10), 0 2px 4px rgba(28,25,23,.06);
|
|
35
|
-
|
|
36
|
-
--font-ui: 'Inter', system-ui, -apple-system, sans-serif;
|
|
37
|
-
|
|
38
|
-
--md-h2-border: #EDE8E2;
|
|
39
|
-
--md-toc-border: #E7E2DB;
|
|
40
|
-
--md-pre-border: #E7E2DB;
|
|
41
|
-
--md-bq-bg: #F7F5F2;
|
|
42
|
-
--md-hr-border: #EDE8E2;
|
|
43
|
-
--md-table-border: #E2DDD6;
|
|
44
|
-
--md-table-header-bg: #F4F1ED;
|
|
45
|
-
--md-table-even-bg: #FAFAF8;
|
|
46
|
-
--md-copy-btn-border: rgba(0,0,0,0.12);
|
|
47
|
-
--md-copy-btn-hover: rgba(0,0,0,0.05);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/* ═══════════════════════════════════════════════════
|
|
51
|
-
DARK THEME
|
|
52
|
-
═══════════════════════════════════════════════════ */
|
|
53
|
-
html[data-theme="dark"] {
|
|
54
|
-
--bg: #1C1A17;
|
|
55
|
-
--bg-surface: #252320;
|
|
56
|
-
--bg-panel: #211F1D;
|
|
57
|
-
--bg-panel-deep: #1A1816;
|
|
58
|
-
--bg-input: #2C2926;
|
|
59
|
-
--bg-hover: #32302C;
|
|
60
|
-
--bg-active: #3A3733;
|
|
61
|
-
|
|
62
|
-
--border: #3D3935;
|
|
63
|
-
--border-subtle: #332F2B;
|
|
64
|
-
--border-strong: #4A453F;
|
|
65
|
-
|
|
66
|
-
--text: #E7E5E2;
|
|
67
|
-
--text-2: #A8A29E;
|
|
68
|
-
--text-3: #6B6560;
|
|
69
|
-
--text-inv: #1C1917;
|
|
70
|
-
|
|
71
|
-
--accent: #3B82F6;
|
|
72
|
-
--accent-light: #1E293B;
|
|
73
|
-
--accent-text: #60A5FA;
|
|
74
|
-
|
|
75
|
-
--shadow-sm: 0 1px 2px rgba(0,0,0,.20);
|
|
76
|
-
--shadow: 0 2px 6px rgba(0,0,0,.25), 0 1px 2px rgba(0,0,0,.15);
|
|
77
|
-
--shadow-md: 0 4px 12px rgba(0,0,0,.35), 0 2px 4px rgba(0,0,0,.20);
|
|
78
|
-
|
|
79
|
-
--md-h2-border: #3D3935;
|
|
80
|
-
--md-toc-border: #3D3935;
|
|
81
|
-
--md-pre-border: #3D3935;
|
|
82
|
-
--md-bq-bg: #252320;
|
|
83
|
-
--md-hr-border: #3D3935;
|
|
84
|
-
--md-table-border: #3D3935;
|
|
85
|
-
--md-table-header-bg: #2C2926;
|
|
86
|
-
--md-table-even-bg: #242220;
|
|
87
|
-
--md-copy-btn-border: rgba(255,255,255,0.12);
|
|
88
|
-
--md-copy-btn-hover: rgba(255,255,255,0.06);
|
|
89
|
-
}
|
|
90
|
-
html[data-theme="dark"] :is(#rendered, #write) {
|
|
91
|
-
--md-bg: #2c2a26;
|
|
92
|
-
--md-color: #e7e5e2;
|
|
93
|
-
--md-code-bg: #1a1816;
|
|
94
|
-
--md-code-color: #b8a99a;
|
|
95
|
-
--md-pre-bg: #1a1816;
|
|
96
|
-
--md-link-color: #60a5fa;
|
|
97
|
-
--md-bq-color: #a8a29e;
|
|
98
|
-
}
|
|
99
|
-
html[data-theme="dark"] .control-row select {
|
|
100
|
-
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' fill='none'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%236B6560' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/* Theme transitions */
|
|
104
|
-
body,
|
|
105
|
-
#left,
|
|
106
|
-
#right,
|
|
107
|
-
#export-panel,
|
|
108
|
-
#statusbar,
|
|
109
|
-
#left-toolbar,
|
|
110
|
-
#right-header,
|
|
111
|
-
#export-panel-header,
|
|
112
|
-
.panel-header,
|
|
113
|
-
.sub-header,
|
|
114
|
-
#raw {
|
|
115
|
-
transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
|
|
116
|
-
}
|
package/public/css/write.css
DELETED
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
/* ═══════════════════════════════════════════════════
|
|
2
|
-
WRITE MODE
|
|
3
|
-
═══════════════════════════════════════════════════ */
|
|
4
|
-
|
|
5
|
-
/* ── Write div ── */
|
|
6
|
-
#write {
|
|
7
|
-
display: none;
|
|
8
|
-
outline: none;
|
|
9
|
-
min-height: 100%;
|
|
10
|
-
cursor: text;
|
|
11
|
-
}
|
|
12
|
-
#write:empty::before {
|
|
13
|
-
content: 'Start typing\2026';
|
|
14
|
-
color: var(--text-3);
|
|
15
|
-
pointer-events: none;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/* ── Write toolbar ── */
|
|
19
|
-
#write-toolbar {
|
|
20
|
-
display: none;
|
|
21
|
-
align-items: center;
|
|
22
|
-
gap: 2px;
|
|
23
|
-
height: 0;
|
|
24
|
-
opacity: 0;
|
|
25
|
-
padding: 0 12px;
|
|
26
|
-
background: var(--bg);
|
|
27
|
-
border-bottom: 1px solid transparent;
|
|
28
|
-
flex-shrink: 0;
|
|
29
|
-
overflow: hidden;
|
|
30
|
-
transition: height .3s cubic-bezier(.4,0,.2,1),
|
|
31
|
-
opacity .22s ease,
|
|
32
|
-
border-color .3s ease,
|
|
33
|
-
padding .3s cubic-bezier(.4,0,.2,1);
|
|
34
|
-
}
|
|
35
|
-
body.write-mode #write-toolbar {
|
|
36
|
-
position: relative;
|
|
37
|
-
display: flex;
|
|
38
|
-
justify-content: center;
|
|
39
|
-
height: 34px;
|
|
40
|
-
opacity: 1;
|
|
41
|
-
border-bottom-color: var(--border-subtle);
|
|
42
|
-
padding: 0 12px;
|
|
43
|
-
overflow-x: auto;
|
|
44
|
-
overflow-y: hidden;
|
|
45
|
-
-webkit-overflow-scrolling: touch;
|
|
46
|
-
scrollbar-width: none;
|
|
47
|
-
}
|
|
48
|
-
body.write-mode #write-toolbar::-webkit-scrollbar {
|
|
49
|
-
display: none;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
.write-tb-btn {
|
|
53
|
-
position: relative;
|
|
54
|
-
display: inline-flex;
|
|
55
|
-
align-items: center;
|
|
56
|
-
justify-content: center;
|
|
57
|
-
min-width: 28px;
|
|
58
|
-
width: 28px;
|
|
59
|
-
height: 26px;
|
|
60
|
-
flex-shrink: 0;
|
|
61
|
-
border: none;
|
|
62
|
-
background: none;
|
|
63
|
-
color: var(--text-2);
|
|
64
|
-
cursor: pointer;
|
|
65
|
-
border-radius: var(--radius-sm);
|
|
66
|
-
padding: 0;
|
|
67
|
-
font-size: 12px;
|
|
68
|
-
font-family: var(--font-ui);
|
|
69
|
-
font-weight: 600;
|
|
70
|
-
transition: color .12s, background .12s;
|
|
71
|
-
}
|
|
72
|
-
.write-tb-btn:hover {
|
|
73
|
-
color: var(--text);
|
|
74
|
-
background: var(--bg-hover);
|
|
75
|
-
}
|
|
76
|
-
.write-tb-btn.active {
|
|
77
|
-
color: var(--text);
|
|
78
|
-
background: var(--bg-input);
|
|
79
|
-
box-shadow: var(--shadow-sm);
|
|
80
|
-
}
|
|
81
|
-
.write-tb-btn code {
|
|
82
|
-
font-size: 11px;
|
|
83
|
-
font-family: 'JetBrains Mono', monospace;
|
|
84
|
-
background: none;
|
|
85
|
-
padding: 0;
|
|
86
|
-
color: inherit;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
.write-tb-sep {
|
|
90
|
-
width: 1px;
|
|
91
|
-
height: 16px;
|
|
92
|
-
background: var(--border);
|
|
93
|
-
margin: 6px 0;
|
|
94
|
-
flex-shrink: 0;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/* ── Tooltips ── */
|
|
98
|
-
.write-tb-btn[data-tip]::after {
|
|
99
|
-
content: attr(data-tip);
|
|
100
|
-
position: absolute;
|
|
101
|
-
bottom: calc(100% + 6px);
|
|
102
|
-
left: 50%;
|
|
103
|
-
transform: translateX(-50%);
|
|
104
|
-
padding: 3px 8px;
|
|
105
|
-
background: var(--text);
|
|
106
|
-
color: var(--bg);
|
|
107
|
-
font-size: 11px;
|
|
108
|
-
font-weight: 500;
|
|
109
|
-
white-space: nowrap;
|
|
110
|
-
border-radius: 4px;
|
|
111
|
-
pointer-events: none;
|
|
112
|
-
opacity: 0;
|
|
113
|
-
transition: opacity .15s ease;
|
|
114
|
-
}
|
|
115
|
-
.write-tb-btn[data-tip]:hover::after {
|
|
116
|
-
opacity: 1;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/* ── Visibility rules ── */
|
|
120
|
-
body.write-mode #write {
|
|
121
|
-
display: block;
|
|
122
|
-
}
|
|
123
|
-
body.write-mode #rendered {
|
|
124
|
-
display: none;
|
|
125
|
-
}
|
|
126
|
-
body.write-mode #raw {
|
|
127
|
-
display: none;
|
|
128
|
-
}
|
package/public/default.md
DELETED
|
@@ -1,255 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
styles:
|
|
3
|
-
fontFamily: Inter
|
|
4
|
-
baseFontSize: 16
|
|
5
|
-
lineHeight: 1.75
|
|
6
|
-
h1: { fontSize: 2.1, fontWeight: 700 }
|
|
7
|
-
h2: { fontSize: 1.55, fontWeight: 600 }
|
|
8
|
-
h3: { fontSize: 1.2, fontWeight: 600 }
|
|
9
|
-
p: { lineHeight: 1.75, marginBottom: 1 }
|
|
10
|
-
light:
|
|
11
|
-
background: "#ffffff"
|
|
12
|
-
color: "#1c1917"
|
|
13
|
-
dark:
|
|
14
|
-
background: "#2c2a26"
|
|
15
|
-
color: "#e7e5e2"
|
|
16
|
-
---
|
|
17
|
-
|
|
18
|
-
# Say hello to SmallDocs: A markdown-first replacement for Word & GDocs
|
|
19
|
-
|
|
20
|
-
If you're working with agents, a document written in markdown is <ins>officially</ins>* 407 times more useful than a document locked inside a `.docx` or `.gdoc` file format. Because of this, I believe Word and GDocs' days are numbered. (*I am the official.)
|
|
21
|
-
|
|
22
|
-
But while markdown is great for agents, it's a bit annoying for humans. Quickly and elegantly reading a `.md` file requires you to open your code editor and enter "preview" mode. Sharing a markdown file requires you to actually send the file to someone. They then have to download it and find the least annoying way to read it.
|
|
23
|
-
|
|
24
|
-
SmallDocs is an [open source](https://github.com/JoshInLisbon/SDocs) attempt at something different. It lets you (or your agent) easily, elegantly and <ins>100% privately</ins> **read**, **format**, **share** and **export** `.md` files.
|
|
25
|
-
|
|
26
|
-
Reading a `.md` file in SmallDocs feels just like this (you're reading markdown right now). And by playing with the styles, it can feel like [this](https://sdocs.dev/#md=jZTdbuNGDIXv9RQHykWBrS1Ijp04LlAgSRF021wEmwC5piRKM_BoqJ0ZxdAWBfoQfcI-STFSfnc3Re8MknN4-JHycrlMgg6Gd0jvFOPcBUiDWyMHfGKqtW3TxIfRsN8lQCM2XFGnzbhDei2O0gQoyfOV2HCrv_AOxTYBjLb8K-tWhR2K7CwBFFPNzu_wx1uRG0NjQ9rhF-17Q2O6gK8o-imyYoGOXKvthYQg3Q55tsGfUax40pl7rrL1HF-9jRfZ6RTvY_itVJEdTymj7T5ma67EUdBid0itWE6ndGmk2n8eJHAsKsXV7O51HdQO68WrTnl2tnnUi0MnQORS7Vsng613SI8aak6aPJ0ylRhxMbiqVutiOwdfEXrOb8v1pjierbx4fU5Tvlmt6qf097xePpXWazo9oXTxtasNN3ySLl40T8oNrflJs5J6Vnv7KudtXb1-dUrrZlXNr2py--8RKLigYv0VAc7rTbV-n8Cj7_cI8LZab-l_EdiWJ2fF-hsCK1qtiu3rWcotbc_y_ybw7asXo8vlMkmO8M7nlCQfLQgHcaaG9EF3-gvXaMTB73XXadsuEBQ7hvYgfB40Bzgu2ZjpOt2sA2_kYMYsSY6OcK9G3PbMNX7XxnhcStc7Vmy9FpskPyN97I5mcFZ7xT72QKdtDbFmxEEHhY4CO03GR9N7KwfDdcs_QYfoJSht91EjKAroaM8eh_jzwJMpyOB8luKfv_7Gb6IsrqXac5JEEPTAjlpGz86Lnco9Vps8cqh9DEcvQ-BsnmP5NGUVRdmjd9JpzygWeZ7_mOFiiFA8k6sUKrFe-8A2mBFeycHPHksexdY4yXMc-i4u6xUW1E56jyCwTA5f2MkM8045Ztw4qoKu2MfYEYoMn3hyNYHryVHrqFdJcsGNOEYnD9Gv2MUMQwdQS9pm0yF4rqKTnryH4weOjCd2UazRzgeIjfvwnutsbrnKcO7agefdxEIaghKXJB8bjDKA2mh0yvIDuzEuqF3E1A-OYSU830pcyWOYSi-u1LbNcDN4Nd11hnO_x4eDGj889j7OcGnE89S2FNnPayzZv4gq6nu2HtQEdpMhH6TPcM3zWLpm8vAcguEM906HyZSazlAcyELJ4Gbo57jSlgzulAytCnO7hnyIHQ80xj0NNv49BLI1vHQ8K-lpha1-4Ig86I6z5F8&theme=light), [this](https://sdocs.dev/#md=jVTtbtpIFP0_T3Fl1D8RNh4DDvaPlfJBdiO1aupktdKqUhg81zDFnqEzYxJaKu1D7BP2Saqx8YbQZlsLieGce-85Plzb931ihS0xBe_s5hoyLFCjzBE2kUeM3ZZoUgJQKGmvWCXKbQrerap1jnDLpIGhRwDmzOCVkvZWfMIU6JgAlELiHygWS5sCDWIHLZFx1CaFz8_HZWqurPL6UDG9EPJcWauqFMJgCF9cG-062vFRi0bPURqMWnx4jNNxQ6wdfqyQNFSuOHZdKXhXQjN4o6TyGnZeqnz1sVa2qZkrzVH_JbhdphD1D5S6aaUw1lWaNcuFXDiCjvsgJEfZhBHty1w2BMDFl68WWtWSp-D1iubyGiZXpdIOjEZREu3Bgxz_4ymjGI1aw034q2d0mMQJZx3d3e-RblxMCub1n7qS8XAShl3Xj3K4OBLo_3RmPI75adzO5EyvfpRAyCmlp0cJ5AmnPHk5gSIs4iJ_MYHxhMVF8f8J0JjOo-jQbVGweHz6SwnsBY4T-H7mZJ6MEnQzfd8npAfHzx0h58wg_Jm9TmG2tHZt0sGArUWAj6xalxjkqhpsohkhvR6c1XaJ0oqcWaEkIWdlCRo_1misaQ5CIzA4R6ZRg1UrlCAk2CXCzPUqLT41rbN9qikhs9mMPOPSrt-s7kuxwfsgCJoq52Aq-VoJaY371YObt7d3MOAqrytswAuNzDoPEh-gw4NG5YNRknwmAF7zDvJS8N7VTFvU5RYyXCttvb6jC6UrZh1fMb3i6kG2eK6kRdkQPXhHIUNTl9a8l-9lhhuUNcJC4wNEw1dBEHjkS-v65CRDs1bS4MkJfP3nX5hFIYXWKJ8dWRPcjecqv588Rquk2Cu3xfetqyiMYj8c-jS5o2Eaus_fbV2tS1fw8t_4FNXgQKNz6hL9fXoY6CAVnJAMrRa4cbF2DMy3cH0ZEPIbZC7wUlTCvW_C8Gkh1qihErK22Bzd5q1wG7Q6l9PX07vpd1I3qCsmUdpyCxxLtGgOVAO4WwoDLHd7AjmTUlmYI9SSK4lBuyFaKw0XiqMhZNccYAdvkEkhF7AjO7-59l_uRHYwCkPYwbXcsFLw7g5grvgWWpq6GcIYN0NpEPvKdsXbkhHs4LKLxxkr3GPZklECu4OgAB9zRI6O_QY&theme=dark) or even [this](https://sdocs.dev/#md=jVRLbtxGEN3zFA-jhQFBQ8yM9Z1FANmAEBt2spAAxcsiu0h2ptlFdxc1mQQBcohcwuscwTfJSYJuzsSSP0GWrGpW1ftUzefzQq06XmN2z7xhb2A93thYiZ8VUXeO47oAGvF6Q711uzVmP4zeqswKoKLIN-L11v7KaywvCsBZz9-zbTtdY1lenhVAx2Q4xDV-e1rntURurMct-Tg7QawpDbIsF2cn6Cm01r8QVenXWJSnZ_g9lVoeqkwtV-X5FF89jS_38SGFn9ZalqucqpzUm_ejKKc3lQTD4d4a7dY4O3lUalFeTb1dBlUACXe9aYOM3qwxO2qapmrOZjlTi5OQgiuzulqdT8FHBPybrxfPr1bVLFfOrG2epFdXl4vq6pD-2qwvD0_54rR-Xs9OPp_KNKtmMTv5VPOiOa_OF4eatZip2tO_LpsFXz7-6_GghsLmawwsaXm-PP2MAb7khbn8NgP7ub_FwJkhw6v_xcB-xM8ZWNFqtXrCQLWgxdXlfzPw5V-fBp3P50VxhC9WpSjuusAMQ7tY4geBVes5UNiVeD1GBaG2uoN2pAi8pWAituQNB-vbsiiOjnATrKEd_v7jT1y7hnoqinsGhWAfOLfSjuFIGdQoBy_iQd5gS27DBlEDJYPCepX8VpzhqPBpGSsJnYgpcddxesqsERQYFQV2O2ytYbCXse3QSIBuBQPL4LjEGxq9CTt05NuIinXL7FGN1hnr21jihoygH6OtYYJtNEJGhTSQgT2MSIhlUXyHdzLCiH-meLDR6h5mmeMtK5zEND6snmRkia1nMWMZxHotJ0aU0QbrXAJNwVjPEZQoHhzVjK3VhGEMUKpcynkDL-jZjxN-2XoOqEJCq9h2pPzAAVuKaALHbtLjlnQMB0VesPv4oU8yM3oJ3voWUSkom6nh8fFAUT9-sBGG4Unp-DhNlYZvqJcxoqINJ0O843iS4-9HHjm3deLbfcJqjmwlaAebMKeerzl8_MvbXiLeiqeoHHawEVTFMRi3Q8U0qm1Gl8dNeHaIY2gSIzWFvYXekh85XWgYVrKuxD0jDuw1K97JGDLfgTNrtYzOoKOH5Bnascm8ZnqOJieNPrJmWfY2pAQlo0u-Ddh78U5CSE33RCZm2uRPn3tOsuT7Ch2DZzMh0C7xvKXQ53GiNFriFVRkg9MLDJ2oxBI_-onFNjl80m70B-Xe_IQbqlXCriiuUYt_4Kya9WaMGiw51NIPjn9BMzoHadZFMccLkU3sZIiTvFX6TCTUCWTjRDK0mq2zvi3muEYQaVSGtFGQBw5OZGP3XFTBmpaLOW7z6oGCQvxeJnog65JVD4IVc7yUpmGe7gXVOpJzO2jS3cDZDaPODzLYxN1dZuq6Sot3OEmv0vJ4UWjY5UEEth8Cx4idjCVy_ud0nY4rtr49frJ1aS3Q04ZjsmRPrWe19aRUHca-crmmdcnfNZmDqW0_SIw2wemsc_vopC0pzoc-y-LFczoRVpON6zGQsnk80-OL2dEwsI8JQcWfrF4WxatnzuUY1Zuy-Ac&theme=light):
|
|
27
|
-
|
|
28
|
-

|
|
29
|
-
|
|
30
|
-
Use SmallDoc's CLI for speed. Creating a SmallDoc for a `.md` file (+ automatically opening your browser to read it) is as simple as:
|
|
31
|
-
|
|
32
|
-
```
|
|
33
|
-
# npm i -g sdocs-dev
|
|
34
|
-
sdoc README.md
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
## How SmallDocs work
|
|
38
|
-
|
|
39
|
-
### URLs
|
|
40
|
-
|
|
41
|
-
The URL format for SmallDocs is:
|
|
42
|
-
|
|
43
|
-
```
|
|
44
|
-
https://sdocs.dev/#md={compressed & encoded .md}
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
Your entire document (content and styles) lives in the URL hash.
|
|
48
|
-
|
|
49
|
-
To keep URLs as short as possible, SmallDocs compresses your markdown using [deflate](https://en.wikipedia.org/wiki/Deflate) (a standard compression algorithm built into every browser) and then encodes the result with [base64url](https://en.wikipedia.org/wiki/Base64#URL_applications) (a URL-safe variant of base64 that avoids characters like `+`, `/`, and `=` which would otherwise need percent-encoding). Style properties that match built-in defaults (e.g. `fontFamily: Inter`, `baseFontSize: 16`) are omitted from the URL — only values that differ from defaults are included, which keeps URLs shorter.
|
|
50
|
-
|
|
51
|
-
The `mode` parameter controls which view opens. Valid values are `read` (clean reading view, style panel hidden), `style` (style panel visible), and `raw` (raw markdown editor). When sharing a link for someone to read, use `mode=read`:
|
|
52
|
-
|
|
53
|
-
```
|
|
54
|
-
https://sdocs.dev/#md=...&mode=read
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
You can also link directly to a section using the `sec` parameter. Click any heading's link icon to copy its section URL:
|
|
58
|
-
|
|
59
|
-
```
|
|
60
|
-
https://sdocs.dev/#md=...&sec=url-formatting
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
The `sec` value is the heading text slugified (lowercased, spaces become hyphens, special characters stripped). The page will scroll to that section on load.
|
|
64
|
-
|
|
65
|
-
The `theme` parameter forces a specific theme: `theme=light` or `theme=dark`. This is useful when sharing a link where the document looks best in a particular theme. The override is view-only — it applies for that view but won't change the reader's saved theme preference.
|
|
66
|
-
|
|
67
|
-
### Privacy
|
|
68
|
-
|
|
69
|
-
Because the SmallDocs url format is:
|
|
70
|
-
|
|
71
|
-
```
|
|
72
|
-
https://sdocs.dev/#md={compressed & encoded .md}
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
Your document never hits the SDocs server.
|
|
76
|
-
|
|
77
|
-
This layer of privacy is built into how HTTP works. The hash fragment (everything after the `#` in a URL) is never sent to the server by the browser. It always stays entirely client-side:
|
|
78
|
-
|
|
79
|
-
> "The fragment is not sent to the server when the URI is requested; it is processed by the client" - [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/URI/Reference/Fragment)
|
|
80
|
-
|
|
81
|
-
The [sdocs.dev](https://sdocs.dev) site is purely a rendering space. JavaScript reads `window.location.hash`, decompresses and decodes the content, and renders your `.md` locally. The server is about 60 lines of Node.js that serves static files — no database, no logging, no analytics.
|
|
82
|
-
|
|
83
|
-
### Formatting
|
|
84
|
-
|
|
85
|
-
SDocs adds basic styling to markdown files. You write your content in regular markdown and the styles live in a metadata block at the top of the file.
|
|
86
|
-
|
|
87
|
-
That metadata block is called [YAML front matter](https://jekyllrb.com/docs/front-matter/). It's a convention that started with [Jekyll](https://jekyllrb.com/) (the static site generator) back in 2008 and has since been adopted by [Hugo](https://gohugo.io/), [Gatsby](https://www.gatsbyjs.com/), [Obsidian](https://obsidian.md/), and most of the markdown ecosystem. It looks like a block of key-value pairs between two `---` lines at the top of your file:
|
|
88
|
-
|
|
89
|
-
```yaml
|
|
90
|
-
---
|
|
91
|
-
title: My Document
|
|
92
|
-
author: Someone
|
|
93
|
-
---
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
SDocs uses a `styles:` key with CSS properties written beneath it in YAML:
|
|
97
|
-
|
|
98
|
-
```yaml
|
|
99
|
-
---
|
|
100
|
-
styles:
|
|
101
|
-
fontFamily: Lora
|
|
102
|
-
baseFontSize: 17
|
|
103
|
-
h1: { fontSize: 2.3, fontWeight: 700 }
|
|
104
|
-
p: { lineHeight: 1.9, marginBottom: 1.2 }
|
|
105
|
-
...
|
|
106
|
-
---
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
(Click "**Raw**" — top left — to see the front matter for this file. See all available properties [here](https://sdocs.dev) or by running `npm i sdocs-dev; sdoc schema`.)
|
|
110
|
-
|
|
111
|
-
When a `Styled .md` file is rendered in the SmallDocs interface the specified styles are applied. If a plain `.md` file is rendered the default styles are applied.
|
|
112
|
-
|
|
113
|
-
#### Light & dark modes
|
|
114
|
-
|
|
115
|
-
You can nest styles in `light` and `dark` keys:
|
|
116
|
-
|
|
117
|
-
```
|
|
118
|
-
light:
|
|
119
|
-
background: "#fffaf5"
|
|
120
|
-
color: "#1a1a2e"
|
|
121
|
-
h1: { color: "#c0392b" }
|
|
122
|
-
dark:
|
|
123
|
-
background: "#1a1520"
|
|
124
|
-
color: "#e7e5e2"
|
|
125
|
-
h1: { color: "#ef6f5e" }
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
These will be used when you view the site in each mode.
|
|
129
|
-
|
|
130
|
-
Non-color properties (fonts, sizes, spacing) are shared across themes and live at the top level.
|
|
131
|
-
|
|
132
|
-
All color controls are in the **Colors** section of the style panel. The light/dark toggle at the top of that section lets you customize each theme independently. Colors cascade from general to specific — set `color` once and it flows to headings, paragraphs, and lists unless you override them individually.
|
|
133
|
-
|
|
134
|
-
### Drag & drop
|
|
135
|
-
|
|
136
|
-
Drag any `.md` file onto the editor to SmallDoc it instantly.
|
|
137
|
-
|
|
138
|
-
### Exports
|
|
139
|
-
|
|
140
|
-
SmallDocs can export your document in four formats:
|
|
141
|
-
|
|
142
|
-
- **Raw .md** — your markdown content with all front matter stripped. Plain markdown, compatible with anything.
|
|
143
|
-
- **PDF** — a styled PDF generated from the rendered view via the browser's print engine.
|
|
144
|
-
- **Word (.docx)** — a styled Word document generated from the rendered HTML.
|
|
145
|
-
- **Styled .md** — your markdown with the `styles:` front matter block included. This is the format SmallDocs reads back in, so your formatting is preserved.
|
|
146
|
-
|
|
147
|
-
### Collapsed headers
|
|
148
|
-
|
|
149
|
-
SmallDocs loads with all headers collapsed. This is done because it makes it easy to get an overview of the whole document.
|
|
150
|
-
|
|
151
|
-
If you expand a parent, all of its children expand too.
|
|
152
|
-
|
|
153
|
-
### Copy & paste
|
|
154
|
-
|
|
155
|
-
Every header has its own copy and paste button. This copies its content and all of its children's content. At the moment this is the fastest way to get SmallDoc content into your agent's context, but we're looking for novel ideas to make this better.
|
|
156
|
-
|
|
157
|
-
### Works offline
|
|
158
|
-
|
|
159
|
-
`https://sdocs.dev` uses extensive client side caching. If you've loaded the site once, you can visit it even when you're offline. If something has changed server side, we invalidate the cache and the next time you visit the site you'll get the latest version.
|
|
160
|
-
|
|
161
|
-
### Auto-save
|
|
162
|
-
|
|
163
|
-
Because the URL includes your full document and dynamically updates via JavaScript, every change you make is instantly preserved in the URL. This works when you're offline.
|
|
164
|
-
|
|
165
|
-
## The CLI
|
|
166
|
-
|
|
167
|
-
### Installation
|
|
168
|
-
|
|
169
|
-
SmallDocs has a command-line tool that lets you open, share, and style markdown files from the terminal. Install it once:
|
|
170
|
-
|
|
171
|
-
```
|
|
172
|
-
npm i -g sdocs-dev
|
|
173
|
-
```
|
|
174
|
-
|
|
175
|
-
This gives you the `sdoc` command.
|
|
176
|
-
|
|
177
|
-
### Open a file
|
|
178
|
-
|
|
179
|
-
```
|
|
180
|
-
sdoc README.md
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
Your browser opens with the document styled and readable. That's it — one command to go from `.md` file to formatted document.
|
|
184
|
-
|
|
185
|
-
### Share a link
|
|
186
|
-
|
|
187
|
-
```
|
|
188
|
-
sdoc share README.md
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
This copies a shareable link to your clipboard.
|
|
192
|
-
|
|
193
|
-
You can also combine it with options:
|
|
194
|
-
|
|
195
|
-
```
|
|
196
|
-
sdoc share report.md --section "Results" # deep-link to a heading
|
|
197
|
-
sdoc share notes.md --write # link opens in write mode
|
|
198
|
-
sdoc share notes.md --dark # link opens in dark theme
|
|
199
|
-
```
|
|
200
|
-
|
|
201
|
-
### Start a new document
|
|
202
|
-
|
|
203
|
-
```
|
|
204
|
-
sdoc new
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
Opens a blank document in write mode, ready to type a `h1`.
|
|
208
|
-
|
|
209
|
-
### Style schema
|
|
210
|
-
|
|
211
|
-
```
|
|
212
|
-
sdoc schema
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
Prints every available style property with its type, default value, and description. This is designed to be readable by both humans and LLMs — so your agent can write YAML front matter for you.
|
|
216
|
-
|
|
217
|
-
### Modes
|
|
218
|
-
|
|
219
|
-
By default, files open in read mode. You can open in any mode:
|
|
220
|
-
|
|
221
|
-
```
|
|
222
|
-
sdoc README.md # read mode (default)
|
|
223
|
-
sdoc README.md --write # write mode (contentEditable editor)
|
|
224
|
-
sdoc README.md --style # style mode (styling panel visible)
|
|
225
|
-
sdoc README.md --raw # raw mode (plain markdown source)
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
### Pipe from stdin
|
|
229
|
-
|
|
230
|
-
Any command that outputs markdown can be piped directly into SmallDocs:
|
|
231
|
-
|
|
232
|
-
```
|
|
233
|
-
cat notes.md | sdoc # open in browser
|
|
234
|
-
cat notes.md | sdoc share # pipe to clipboard link
|
|
235
|
-
your-agent --output md | sdoc # pipe agent output to browser
|
|
236
|
-
```
|
|
237
|
-
|
|
238
|
-
### Default styles
|
|
239
|
-
|
|
240
|
-
If you find a style you like, use the "Save as Default" panel in the Style view to generate a command that saves your preferences to `~/.sdocs/styles.yaml`. The CLI automatically applies these defaults to every file you open — unless the file has its own styles, which always take priority.
|
|
241
|
-
|
|
242
|
-
```
|
|
243
|
-
sdoc defaults # view your current defaults
|
|
244
|
-
sdoc defaults --reset # remove them
|
|
245
|
-
```
|
|
246
|
-
|
|
247
|
-
### For agents
|
|
248
|
-
|
|
249
|
-
The CLI is designed to work well in automated workflows. A few patterns:
|
|
250
|
-
|
|
251
|
-
- **Generate a styled doc**: have your agent write a `.md` file with YAML front matter, then `sdoc share file.md` to copy a shareable link
|
|
252
|
-
- **Learn the format**: `sdoc schema` gives your agent everything it needs to know about available style properties
|
|
253
|
-
- **Deep-link to context**: `sdoc share file.md --section "Heading"` creates a URL that scrolls straight to the relevant section
|
|
254
|
-
- **No auth, no API keys**: everything is client-side — the URL *is* the document
|
|
255
|
-
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|