@tdocs/tdocs 1.0.0 → 1.0.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/build/compiler.js +38 -0
- package/package.json +3 -1
- package/templates/layout.ejs +20 -19
- package/templates/style.css +34 -6
package/build/compiler.js
CHANGED
|
@@ -7,6 +7,44 @@ exports.compileMarkdown = compileMarkdown;
|
|
|
7
7
|
const marked_1 = require("marked");
|
|
8
8
|
const marked_highlight_1 = require("marked-highlight");
|
|
9
9
|
const highlight_js_1 = __importDefault(require("highlight.js"));
|
|
10
|
+
// Custom Markdown Attribute Parser
|
|
11
|
+
// Looks for `{.class1 .class2 #id}` at the end of text
|
|
12
|
+
// We override the renderer to apply classes/ids parsed from the text
|
|
13
|
+
// We override the renderer to apply classes/ids parsed from the text
|
|
14
|
+
const renderer = new marked_1.marked.Renderer();
|
|
15
|
+
const applyAttributes = (text, renderDefault) => {
|
|
16
|
+
const match = text.match(/\{([^}]+)\}\s*$/);
|
|
17
|
+
if (!match)
|
|
18
|
+
return renderDefault(text);
|
|
19
|
+
const attrs = match[1].trim().split(/\s+/);
|
|
20
|
+
const classes = [];
|
|
21
|
+
let id = '';
|
|
22
|
+
attrs.forEach(attr => {
|
|
23
|
+
if (attr.startsWith('.'))
|
|
24
|
+
classes.push(attr.slice(1));
|
|
25
|
+
if (attr.startsWith('#'))
|
|
26
|
+
id = attr.slice(1);
|
|
27
|
+
});
|
|
28
|
+
const cleanText = text.replace(/\{([^}]+)\}\s*$/, '').trim();
|
|
29
|
+
let html = renderDefault(cleanText);
|
|
30
|
+
// Inject into the first opening tag
|
|
31
|
+
if (classes.length > 0) {
|
|
32
|
+
html = html.replace(/^<([^\s>]+)/, `<$1 class="${classes.join(' ')}"`);
|
|
33
|
+
}
|
|
34
|
+
if (id) {
|
|
35
|
+
html = html.replace(/^<([^\s>]+)/, `<$1 id="${id}"`);
|
|
36
|
+
}
|
|
37
|
+
return html;
|
|
38
|
+
};
|
|
39
|
+
renderer.heading = function ({ tokens, depth }) {
|
|
40
|
+
const text = this.parser.parseInline(tokens);
|
|
41
|
+
return applyAttributes(text, (t) => `<h${depth}>${t}</h${depth}>\n`);
|
|
42
|
+
};
|
|
43
|
+
renderer.paragraph = function ({ tokens }) {
|
|
44
|
+
const text = this.parser.parseInline(tokens);
|
|
45
|
+
return applyAttributes(text, (t) => `<p>${t}</p>\n`);
|
|
46
|
+
};
|
|
47
|
+
marked_1.marked.use({ renderer });
|
|
10
48
|
marked_1.marked.use((0, marked_highlight_1.markedHighlight)({
|
|
11
49
|
langPrefix: 'hljs language-',
|
|
12
50
|
highlight(code, lang) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tdocs/tdocs",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Custom Static Site Generator for rapid documentation prototyping",
|
|
5
5
|
"main": "./build/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -21,6 +21,8 @@
|
|
|
21
21
|
"ejs": "^5.0.1",
|
|
22
22
|
"highlight.js": "^11.11.1",
|
|
23
23
|
"marked": "^17.0.4",
|
|
24
|
+
"marked-custom-heading-id": "^2.0.9",
|
|
25
|
+
"marked-extended-attributes": "^1.0.1",
|
|
24
26
|
"marked-highlight": "^2.2.3"
|
|
25
27
|
},
|
|
26
28
|
"keywords": [],
|
package/templates/layout.ejs
CHANGED
|
@@ -6,36 +6,31 @@
|
|
|
6
6
|
<title><%= config.title || 'Documentation' %></title>
|
|
7
7
|
<link rel="stylesheet" href="style.css">
|
|
8
8
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github-dark.min.css">
|
|
9
|
-
<style>
|
|
10
|
-
.nav-item { margin-left: var(--indent, 0px); padding: 5px 0; cursor: pointer; color: var(--accent-color); }
|
|
11
|
-
.nav-item:hover { text-decoration: underline; }
|
|
12
|
-
.nav-item.active { font-weight: bold; color: var(--text-color); }
|
|
13
|
-
</style>
|
|
14
9
|
</head>
|
|
15
|
-
<body>
|
|
16
|
-
<header>
|
|
17
|
-
<h1><%= config.header || 'TDoc Site' %></h1>
|
|
10
|
+
<body class="tdoc-body">
|
|
11
|
+
<header class="tdoc-header">
|
|
12
|
+
<h1 class="tdoc-site-title"><%= config.header || 'TDoc Site' %></h1>
|
|
18
13
|
</header>
|
|
19
14
|
|
|
20
|
-
<div class="layout">
|
|
21
|
-
<aside class="sidebar" id="sidebar">
|
|
15
|
+
<div class="tdoc-layout">
|
|
16
|
+
<aside class="tdoc-sidebar" id="tdoc-sidebar-container">
|
|
22
17
|
<!-- Sidebar navigation populated by JS -->
|
|
23
18
|
</aside>
|
|
24
19
|
|
|
25
|
-
<main class="content" id="content-area">
|
|
20
|
+
<main class="tdoc-content" id="tdoc-content-area">
|
|
26
21
|
<!-- Main documentation content will go here -->
|
|
27
22
|
</main>
|
|
28
23
|
</div>
|
|
29
24
|
|
|
30
|
-
<footer>
|
|
31
|
-
<p><%= config.footer || 'Generated with TDoc' %></p>
|
|
25
|
+
<footer class="tdoc-footer">
|
|
26
|
+
<p class="tdoc-footer-text"><%= config.footer || 'Generated with TDoc' %></p>
|
|
32
27
|
</footer>
|
|
33
28
|
|
|
34
29
|
<script>
|
|
35
30
|
const tree = <%- serializeTree(tree) %>;
|
|
36
31
|
|
|
37
|
-
const sidebar = document.getElementById('sidebar');
|
|
38
|
-
const contentArea = document.getElementById('content-area');
|
|
32
|
+
const sidebar = document.getElementById('tdoc-sidebar-container');
|
|
33
|
+
const contentArea = document.getElementById('tdoc-content-area');
|
|
39
34
|
|
|
40
35
|
// Flatten tree to a map for easy lookup
|
|
41
36
|
const nodeMap = {};
|
|
@@ -45,12 +40,18 @@
|
|
|
45
40
|
nodeMap[node.id] = node;
|
|
46
41
|
|
|
47
42
|
const div = document.createElement('div');
|
|
48
|
-
div.className = 'nav-item';
|
|
49
|
-
div.
|
|
43
|
+
div.className = 'tdoc-nav-item';
|
|
44
|
+
div.setAttribute('data-level', node.level);
|
|
45
|
+
div.style.setProperty('--tdoc-indent', `${node.level * 15}px`);
|
|
46
|
+
|
|
47
|
+
if (node.children && node.children.length > 0) {
|
|
48
|
+
div.classList.add('tdoc-has-children');
|
|
49
|
+
}
|
|
50
|
+
|
|
50
51
|
div.textContent = node.title;
|
|
51
52
|
div.onclick = () => {
|
|
52
|
-
document.querySelectorAll('.nav-item').forEach(el => el.classList.remove('active'));
|
|
53
|
-
div.classList.add('active');
|
|
53
|
+
document.querySelectorAll('.tdoc-nav-item').forEach(el => el.classList.remove('tdoc-active'));
|
|
54
|
+
div.classList.add('tdoc-active');
|
|
54
55
|
contentArea.innerHTML = node.htmlContent;
|
|
55
56
|
};
|
|
56
57
|
|
package/templates/style.css
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
--accent-color: #0066cc;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
body {
|
|
10
|
+
.tdoc-body {
|
|
11
11
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
|
12
12
|
margin: 0;
|
|
13
13
|
padding: 0;
|
|
@@ -18,34 +18,62 @@ body {
|
|
|
18
18
|
min-height: 100vh;
|
|
19
19
|
}
|
|
20
20
|
|
|
21
|
-
header {
|
|
21
|
+
.tdoc-header {
|
|
22
22
|
background-color: var(--header-bg);
|
|
23
23
|
color: var(--header-text);
|
|
24
24
|
padding: 1rem 2rem;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
.
|
|
27
|
+
.tdoc-site-title {
|
|
28
|
+
margin: 0;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.tdoc-layout {
|
|
28
32
|
display: flex;
|
|
29
33
|
flex: 1;
|
|
30
34
|
}
|
|
31
35
|
|
|
32
|
-
.sidebar {
|
|
36
|
+
.tdoc-sidebar {
|
|
33
37
|
width: 250px;
|
|
34
38
|
background-color: var(--sidebar-bg);
|
|
35
39
|
padding: 2rem 1rem;
|
|
36
40
|
border-right: 1px solid #e0e0e0;
|
|
37
41
|
}
|
|
38
42
|
|
|
39
|
-
.
|
|
43
|
+
.tdoc-nav-item {
|
|
44
|
+
margin-left: var(--tdoc-indent, 0px);
|
|
45
|
+
padding: 5px 0;
|
|
46
|
+
cursor: pointer;
|
|
47
|
+
color: var(--accent-color);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.tdoc-nav-item:hover {
|
|
51
|
+
text-decoration: underline;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.tdoc-nav-item.tdoc-active {
|
|
55
|
+
font-weight: bold;
|
|
56
|
+
color: var(--text-color);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
.tdoc-nav-item.tdoc-has-children {
|
|
60
|
+
/* Give users a target to add an accordion arrow or bolding if they want */
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.tdoc-content {
|
|
40
64
|
flex: 1;
|
|
41
65
|
padding: 2rem 4rem;
|
|
42
66
|
max-width: 900px;
|
|
43
67
|
}
|
|
44
68
|
|
|
45
|
-
footer {
|
|
69
|
+
.tdoc-footer {
|
|
46
70
|
padding: 1rem 2rem;
|
|
47
71
|
text-align: center;
|
|
48
72
|
border-top: 1px solid #e0e0e0;
|
|
49
73
|
font-size: 0.9rem;
|
|
50
74
|
color: #666;
|
|
51
75
|
}
|
|
76
|
+
|
|
77
|
+
.tdoc-footer-text {
|
|
78
|
+
margin: 0;
|
|
79
|
+
}
|