Skip to content

Commit f0de1f2

Browse files
committed
Support titles with trailing hashes, add UI to specify max ToC level
1 parent a134042 commit f0de1f2

File tree

2 files changed

+93
-9
lines changed

2 files changed

+93
-9
lines changed

index.html

Lines changed: 61 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,55 @@
5252
grid-column: 1 / 2;
5353
grid-row: 2 / 3;
5454
}
55+
.output-box {
56+
grid-column: 2 / 3;
57+
grid-row: 3 / 4;
58+
display: flex;
59+
flex-direction: column;
60+
}
61+
.output-level-bar {
62+
display: flex;
63+
flex-direction: row;
64+
border: 1px solid #666;
65+
border-radius: 5px;
66+
padding: 10px;
67+
margin-bottom: 10px;
68+
}
69+
.output-level-bar > * {
70+
margin-right: 4px;
71+
}
72+
.form-component {
73+
box-shadow: inset 0 1px 3px 0 #91b8b3;
74+
border: 1px solid #566963;
75+
border-radius: 5px;
76+
display: inline-block;
77+
font-size: 15px;
78+
font-weight: bold;
79+
padding: 4px 20px;
80+
}
81+
#levels-to-show {
82+
padding: 0 10px;
83+
width: 30px;
84+
}
85+
.button {
86+
background-color: #768d87;
87+
cursor: pointer;
88+
color: #ffffff;
89+
text-decoration: none;
90+
text-shadow: 0 -1px 0 #2b665e;
91+
}
92+
.button:hover {
93+
background-color: #6c7c7c;
94+
}
95+
.button:active {
96+
position: relative;
97+
top: 1px;
98+
}
99+
.label {
100+
display: flex;
101+
align-items: center;
102+
margin-right: 8px;
103+
}
55104
#output-header {
56105
grid-column: 2 / 3;
57106
grid-row: 2 / 3;
@@ -61,8 +110,7 @@
61110
grid-row: 3 / 4;
62111
}
63112
#output-area {
64-
grid-column: 2 / 3;
65-
grid-row: 3 / 4;
113+
height: 100%;
66114
}
67115
.footer {
68116
grid-column: 1 / 3;
@@ -111,9 +159,17 @@
111159
## Barbar
112160

113161
Praesent fringilla pulvinar pellentesque. Ut elementum ultrices tortor, ut hendrerit diam tempor vitae.
114-
</textarea>
115-
<textarea name="output-area" class="area" id="output-area" readonly></textarea>
116-
<div class="footer"><a href="//luciopaiva.com" target="_blank">Lucio Paiva</a> 2018</div>
162+
</textarea>
163+
<div class="output-box">
164+
<div class="output-level-bar">
165+
<label class="label" for="levels-to-show">How many levels to show:</label>
166+
<input name="levels-to-show" type="number" min="1" max="10" id="levels-to-show" class="form-component" value="2">
167+
<div class="form-component button" id="level-up"></div>
168+
<div class="form-component button" id="level-down"></div>
169+
</div>
170+
<textarea name="output-area" class="area" id="output-area" readonly></textarea>
171+
</div>
172+
<div class="footer"><a href="//luciopaiva.com" target="_blank">Lucio Paiva</a> 2018-2019</div>
117173
</div>
118174

119175
<script src="index.js"></script>

index.js

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,35 @@ class MarkdownToc {
44
constructor () {
55
this.inputArea = document.getElementById("input-area");
66
this.outputArea = document.getElementById("output-area");
7+
this.levelUpButton = document.getElementById("level-up");
8+
this.levelUpButton.addEventListener("click", this.changeLevel.bind(this, +1));
9+
this.levelDownButton = document.getElementById("level-down");
10+
this.levelDownButton.addEventListener("click", this.changeLevel.bind(this, -1));
11+
this.levelsToShowElement = document.getElementById("levels-to-show");
12+
this.levelsToShow = 2;
713

814
this.inputArea.addEventListener("input", this.process.bind(this));
915
this.process();
1016
}
1117

18+
changeLevel(delta) {
19+
this.levelsToShow += delta;
20+
if (this.levelsToShow < 1) {
21+
this.levelsToShow = 1;
22+
} else if (this.levelsToShow > 10) {
23+
this.levelsToShow = 10;
24+
} else if (typeof this.levelsToShow !== "number") {
25+
this.levelsToShow = 2;
26+
}
27+
this.levelsToShowElement.setAttribute("value", this.levelsToShow);
28+
this.process();
29+
}
30+
1231
process() {
1332
const input = this.inputArea.value;
1433
const menus = ["# Table of contents", ""];
1534
let isCodeBlock = false;
35+
let topLevel = NaN;
1636

1737
for (let line of input.split("\n")) {
1838

@@ -25,13 +45,21 @@ class MarkdownToc {
2545
}
2646

2747
if (line.startsWith("#")) {
28-
const match = line.match(/(#+)\s*(.*)/);
29-
const level = match[1].length - 1;
30-
const title = match[2];
48+
const match = line.match(/(#+)\s*(.*?)#*\s*$/);
49+
const level = match[1].length;
50+
if (isNaN(topLevel)) {
51+
topLevel = level;
52+
}
53+
54+
if (level - topLevel >= this.levelsToShow) {
55+
continue;
56+
}
57+
58+
const title = match[2].trim();
3159
const link = title.toLocaleLowerCase()
3260
.replace(/\s/g, "-")
3361
.replace(/[^A-Za-z0-9-]/g, "");
34-
const menu = `${" ".repeat(level)}- [${title}](#${link})`;
62+
const menu = `${" ".repeat(level - topLevel)}- [${title}](#${link})`;
3563
menus.push(menu);
3664
}
3765
}

0 commit comments

Comments
 (0)