Просмотр исходного кода

Id differentiator added. CSS improvements to playground. Fixes to footnote links.

main
Rocketsoup 1 год назад
Родитель
Сommit
3c35853b49
3 измененных файлов: 154 добавлений и 112 удалений
  1. 48
    50
      js/markdown.js
  2. 1
    1
      js/markdown.min.js
  3. 105
    61
      markdownjs.html

+ 48
- 50
js/markdown.js Просмотреть файл

578
 	/** @type {MDState|null} */
578
 	/** @type {MDState|null} */
579
 	#parent = null;
579
 	#parent = null;
580
 
580
 
581
-	/** @type {MDConfig} */
582
-	config;
583
-
584
 	/**
581
 	/**
585
 	 * Array of `MDReader`s sorted by block reading priority.
582
 	 * Array of `MDReader`s sorted by block reading priority.
586
 	 * @type {MDReader[]}
583
 	 * @type {MDReader[]}
600
 	readersBySubstitutePriority = [];
597
 	readersBySubstitutePriority = [];
601
 
598
 
602
 	/**
599
 	/**
600
+	 * Prefix to include in any generated `id` attributes on HTML elements.
601
+	 * Useful for keeping elements unique in multiple parsed documents in the
602
+	 * same HTML page.
603
+	 *
604
+	 * @type {string}
605
+	 */
606
+	elementIdPrefix = '';
607
+
608
+	/**
603
 	 * Mapping of reference symbols to URLs.
609
 	 * Mapping of reference symbols to URLs.
604
 	 * @type {object}
610
 	 * @type {object}
605
 	 */
611
 	 */
618
 
624
 
619
 	/**
625
 	/**
620
 	 * @param {string[]} lines - lines of markdown text
626
 	 * @param {string[]} lines - lines of markdown text
621
-	 * @param {MDConfig} config
622
-	 * @param {MDReader[]} readersByBlockPriority
623
-	 * @param {MDReader[]} readersByTokenPriority
624
-	 * @param {Array} readersBySubstitutePriority - tuple arrays of priority and MDReader
625
-	 */
626
-	constructor(lines,
627
-		config=null,
628
-		readersByBlockPriority=null,
629
-		readersByTokenPriority=null,
630
-		readersBySubstitutePriority=null,
631
-		tagFilter=null) {
627
+	 */
628
+	constructor(lines) {
632
 		this.#lines = lines;
629
 		this.#lines = lines;
633
-		this.config = config;
634
-		this.readersByBlockPriority = readersByBlockPriority
635
-		this.readersByTokenPriority = readersByTokenPriority
636
-		this.readersBySubstitutePriority = readersBySubstitutePriority
637
-		this.tagFilter = tagFilter;
638
 	}
630
 	}
639
 
631
 
640
 	/**
632
 	/**
647
 	copy(lines) {
639
 	copy(lines) {
648
 		let cp = new MDState(lines);
640
 		let cp = new MDState(lines);
649
 		cp.#parent = this;
641
 		cp.#parent = this;
650
-		cp.config = this.config;
651
 		return cp;
642
 		return cp;
652
 	}
643
 	}
653
 
644
 
2034
 }
2025
 }
2035
 
2026
 
2036
 class MDStrikethroughReader extends MDSimplePairInlineReader {
2027
 class MDStrikethroughReader extends MDSimplePairInlineReader {
2028
+	/** @type {boolean} */
2029
+	singleTildeEnabled = true;
2030
+	/** @type {boolean} */
2031
+	doubleTildeEnabled = true;
2032
+
2037
 	readToken(state, line) {
2033
 	readToken(state, line) {
2038
 		if (line.startsWith('~')) return new MDToken('~', MDTokenType.Tilde);
2034
 		if (line.startsWith('~')) return new MDToken('~', MDTokenType.Tilde);
2039
 		return null;
2035
 		return null;
2040
 	}
2036
 	}
2041
 
2037
 
2042
 	substituteTokens(state, pass, tokens) {
2038
 	substituteTokens(state, pass, tokens) {
2043
-		if (this.attemptPair(state, pass, tokens, MDStrikethroughNode, MDTokenType.Tilde, 2)) return true;
2044
-		if (state.config.strikethroughSingleTildeEnabled) {
2039
+		if (this.singleTildeEnabled) {
2040
+			if (this.attemptPair(state, pass, tokens, MDStrikethroughNode, MDTokenType.Tilde, 2)) return true;
2041
+		}
2042
+		if (this.doubleTildeEnabled) {
2045
 			if (this.attemptPair(state, pass, tokens, MDStrikethroughNode, MDTokenType.Tilde)) return true;
2043
 			if (this.attemptPair(state, pass, tokens, MDStrikethroughNode, MDTokenType.Tilde)) return true;
2046
 		}
2044
 		}
2047
 		return false;
2045
 		return false;
2266
 		return null;
2264
 		return null;
2267
 	}
2265
 	}
2268
 
2266
 
2269
-	preProcess(state) {
2270
-		// Causes a conflict
2271
-		state.config.strikethroughSingleTildeEnabled = false;
2272
-	}
2273
-
2274
 	substituteTokens(state, pass, tokens) {
2267
 	substituteTokens(state, pass, tokens) {
2275
 		return this.attemptPair(state, pass, tokens, MDSubscriptNode, MDTokenType.Tilde);
2268
 		return this.attemptPair(state, pass, tokens, MDSubscriptNode, MDTokenType.Tilde);
2276
 	}
2269
 	}
2747
 }
2740
 }
2748
 
2741
 
2749
 class MDFootnoteListNode extends MDBlockNode {
2742
 class MDFootnoteListNode extends MDBlockNode {
2743
+	/**
2744
+	 * @param {MDState} state
2745
+	 * @param {string} symbol
2746
+	 * @return {number}
2747
+	 */
2748
+	#footnoteId(state, symbol) {
2749
+		const lookup = state.root['footnoteIds'];
2750
+		if (!lookup) return null;
2751
+		return lookup[symbol] ?? null;
2752
+	}
2753
+
2750
 	toHTML(state) {
2754
 	toHTML(state) {
2751
 		const footnotes = state.footnotes;
2755
 		const footnotes = state.footnotes;
2752
 		var symbolOrder = Object.keys(footnotes);
2756
 		var symbolOrder = Object.keys(footnotes);
2759
 			/** @type {MDNode[]} */
2763
 			/** @type {MDNode[]} */
2760
 			let content = footnotes[symbol];
2764
 			let content = footnotes[symbol];
2761
 			if (!content) continue;
2765
 			if (!content) continue;
2766
+			let footnoteId = this.#footnoteId(state, symbol);
2762
 			const contentHTML = MDNode.toHTML(content, state);
2767
 			const contentHTML = MDNode.toHTML(content, state);
2763
-			html += `<li value="${symbol}" id="footnote_${symbol}">${contentHTML}`;
2768
+			html += `<li value="${symbol}" id="${state.root.elementIdPrefix}footnote_${footnoteId}">${contentHTML}`;
2764
 			const uniques = footnoteUniques[symbol];
2769
 			const uniques = footnoteUniques[symbol];
2765
 			if (uniques) {
2770
 			if (uniques) {
2766
 				for (const unique of uniques) {
2771
 				for (const unique of uniques) {
2767
-					html += ` <a href="#footnoteref_${unique}" class="footnote-backref">↩︎</a>`;
2772
+					html += ` <a href="#${state.root.elementIdPrefix}footnoteref_${unique}" class="footnote-backref">↩︎</a>`;
2768
 				}
2773
 				}
2769
 			}
2774
 			}
2770
 			html += `</li>\n`;
2775
 			html += `</li>\n`;
2908
 
2913
 
2909
 	toHTML(state) {
2914
 	toHTML(state) {
2910
 		if (this.differentiator !== null) {
2915
 		if (this.differentiator !== null) {
2911
-			return `<sup id="footnoteref_${this.occurrenceId}"${this._htmlAttributes()}><a href="#footnote_${this.footnoteId}">${MDUtils.escapeHTML(this.displaySymbol ?? this.symbol)}</a></sup>`;
2916
+			return `<sup id="${state.root.elementIdPrefix}footnoteref_${this.occurrenceId}"${this._htmlAttributes()}>` +
2917
+				`<a href="#${state.root.elementIdPrefix}footnote_${this.footnoteId}">${MDUtils.escapeHTML(this.displaySymbol ?? this.symbol)}</a></sup>`;
2912
 		}
2918
 		}
2913
 		return `<!--FNREF:{${this.symbol}}-->`;
2919
 		return `<!--FNREF:{${this.symbol}}-->`;
2914
 	}
2920
 	}
3747
 	}
3753
 	}
3748
 }
3754
 }
3749
 
3755
 
3750
-class MDConfig {
3751
-	strikethroughSingleTildeEnabled = true;
3752
-}
3753
-
3754
 class Markdown {
3756
 class Markdown {
3755
 	/**
3757
 	/**
3756
 	 * Set of standard readers.
3758
 	 * Set of standard readers.
3808
 	static completeParser = new Markdown(this.allReaders);
3810
 	static completeParser = new Markdown(this.allReaders);
3809
 
3811
 
3810
 	/**
3812
 	/**
3811
-	 * @type {MDConfig}
3812
-	 */
3813
-	config;
3814
-
3815
-	/**
3816
 	 * Filter for what non-markdown HTML is permitted. HTML generated as a
3813
 	 * Filter for what non-markdown HTML is permitted. HTML generated as a
3817
 	 * result of markdown is unaffected.
3814
 	 * result of markdown is unaffected.
3818
 	 */
3815
 	 */
3831
 	 * Creates a Markdown parser with the given syntax readers.
3828
 	 * Creates a Markdown parser with the given syntax readers.
3832
 	 *
3829
 	 *
3833
 	 * @param {MDReader[]} readers
3830
 	 * @param {MDReader[]} readers
3834
-	 * @param {MDConfig} config
3835
 	 */
3831
 	 */
3836
-	constructor(readers=Markdown.allReaders, config=new MDConfig()) {
3832
+	constructor(readers=Markdown.allReaders) {
3837
 		this.#readers = readers;
3833
 		this.#readers = readers;
3838
-		this.config = config;
3839
 		this.#readersByBlockPriority = MDReader.sortReaderForBlocks(readers);
3834
 		this.#readersByBlockPriority = MDReader.sortReaderForBlocks(readers);
3840
 		this.#readersByTokenPriority = MDReader.sortReadersForTokenizing(readers);
3835
 		this.#readersByTokenPriority = MDReader.sortReadersForTokenizing(readers);
3841
 		this.#readersBySubstitutePriority = MDReader.sortReadersForSubstitution(readers);
3836
 		this.#readersBySubstitutePriority = MDReader.sortReadersForSubstitution(readers);
3844
 	/**
3839
 	/**
3845
 	 * Converts a markdown string to an HTML string.
3840
 	 * Converts a markdown string to an HTML string.
3846
 	 *
3841
 	 *
3847
-	 * @param  {string} markdown
3842
+	 * @param {string} markdown
3843
+	 * @param {string} elementIdPrefix - Optional prefix for generated element
3844
+	 *   `id`s and links to them. For differentiating multiple markdown docs in
3845
+	 *   the same HTML page.
3848
 	 * @returns {string} HTML
3846
 	 * @returns {string} HTML
3849
 	 */
3847
 	 */
3850
-	toHTML(markdown) {
3848
+	toHTML(markdown, elementIdPrefix='') {
3851
 		const lines = markdown.split(/(?:\n|\r|\r\n)/);
3849
 		const lines = markdown.split(/(?:\n|\r|\r\n)/);
3852
-		const state = new MDState(lines,
3853
-			this.config,
3854
-			this.#readersByBlockPriority,
3855
-			this.#readersByTokenPriority,
3856
-			this.#readersBySubstitutePriority,
3857
-			this.tagFilter);
3850
+		const state = new MDState(lines);
3851
+		state.readersByBlockPriority = this.#readersByBlockPriority;
3852
+		state.readersByTokenPriority = this.#readersByTokenPriority
3853
+		state.readersBySubstitutePriority = this.#readersBySubstitutePriority
3854
+		state.tagFilter = this.tagFilter;
3855
+		state.elementIdPrefix = elementIdPrefix;
3858
 		for (const reader of this.#readers) {
3856
 		for (const reader of this.#readers) {
3859
 			reader.preProcess(state);
3857
 			reader.preProcess(state);
3860
 		}
3858
 		}

+ 1
- 1
js/markdown.min.js
Разница между файлами не показана из-за своего большого размера
Просмотреть файл


+ 105
- 61
markdownjs.html Просмотреть файл

5
 		<title>Markdown Test</title>
5
 		<title>Markdown Test</title>
6
 		<link rel="icon" href="data:;base64,iVBORw0KGgo=">
6
 		<link rel="icon" href="data:;base64,iVBORw0KGgo=">
7
 		<style type="text/css">
7
 		<style type="text/css">
8
+			/* Structural style */
8
 			:root {
9
 			:root {
9
-				--color-background: #fffff8;
10
-				--color-text: #111;
11
-				--color-editor-background: #0000aa;
10
+				--color-editor-background: #00a;
12
 				--color-editor-text: white;
11
 				--color-editor-text: white;
13
-				--color-table-header: #ddd;
14
-				--color-table-border: black;
15
-				--color-calculated-background: #eee;
12
+				--toolbar-background: #ccc;
13
+				--toolbar-text: #000;
14
+			}
15
+			@media (prefers-color-scheme: dark) {
16
+				:root {
17
+					--toolbar-background: #aaa;
18
+				}
16
 			}
19
 			}
17
 			:root, body {
20
 			:root, body {
18
 				width: 100%;
21
 				width: 100%;
47
 			.toolbar {
50
 			.toolbar {
48
 				position: absolute;
51
 				position: absolute;
49
 				z-index: 1;
52
 				z-index: 1;
50
-				background-color: #eee;
53
+				background-color: var(--toolbar-background);
54
+				color: var(--toolbar-text);
51
 				min-height: 32px;
55
 				min-height: 32px;
52
 				/* max-height: 300px; */
56
 				/* max-height: 300px; */
53
 				width: 100%;
57
 				width: 100%;
54
-				color: black;
55
 				border-bottom: 1px solid black;
58
 				border-bottom: 1px solid black;
56
 				box-sizing: border-box;
59
 				box-sizing: border-box;
57
 				padding: 4px 20px;
60
 				padding: 4px 20px;
61
+				font-family: sans-serif;
58
 			}
62
 			}
59
 			#readercontainer {
63
 			#readercontainer {
60
 				overflow-y: scroll;
64
 				overflow-y: scroll;
71
 			}
75
 			}
72
 			#markdowninput {
76
 			#markdowninput {
73
 				position: absolute;
77
 				position: absolute;
78
+				box-sizing: border-box;
74
 				top: 32px;
79
 				top: 32px;
75
-				margin-top: 32px;
76
 				width: 100%;
80
 				width: 100%;
77
 				height: calc(100% - 32px);
81
 				height: calc(100% - 32px);
78
-				box-sizing: border-box;
79
 				margin: 0;
82
 				margin: 0;
80
-				padding: 0.5em;
83
+				padding: 1em 2em;
81
 				border: 0;
84
 				border: 0;
82
 				background-color: var(--color-editor-background);
85
 				background-color: var(--color-editor-background);
83
 				color: var(--color-editor-text);
86
 				color: var(--color-editor-text);
84
-				box-sizing: border-box;
85
 			}
87
 			}
86
 			.calculated {
88
 			.calculated {
87
 				background-color: var(--color-calculated-background);
89
 				background-color: var(--color-calculated-background);
92
 			.spreadsheet-type-percent {
94
 			.spreadsheet-type-percent {
93
 				text-align: right;
95
 				text-align: right;
94
 			}
96
 			}
95
-			table {
96
-				border-collapse: collapse;
97
-			}
98
-			table th {
99
-				background-color: var(--color-table-header);
100
-			}
101
-			table td, table th {
102
-				border: 1px solid var(--color-table-border);
103
-				padding: 0.2em 0.5em;
97
+		</style>
98
+		<style type="text/css">
99
+			/* Document styling */
100
+			/* From https://github.com/edwardtufte/tufte-css/blob/gh-pages/tufte.css */
101
+			:root {
102
+				--color-background: #fffff8;
103
+				--color-text: #111;
104
+				--color-table-header: #ddd;
105
+				--color-table-border: black;
106
+				--color-calculated-background: #eee;
107
+				--color-highlight: #ff0;
108
+				--color-highlight-text: #111;
104
 			}
109
 			}
105
 			@media (prefers-color-scheme: dark) {
110
 			@media (prefers-color-scheme: dark) {
106
 				:root {
111
 				:root {
109
 					--color-table-header: #333;
114
 					--color-table-header: #333;
110
 					--color-table-border: #ccc;
115
 					--color-table-border: #ccc;
111
 					--color-calculated-background: #444;
116
 					--color-calculated-background: #444;
117
+					--color-highlight: #88f;
118
+					--color-highlight-text: #ddd;
112
 				}
119
 				}
113
 			}
120
 			}
114
-		</style>
115
-		<style type="text/css">
116
-			/* From https://github.com/edwardtufte/tufte-css/blob/gh-pages/tufte.css */
117
 			html {
121
 			html {
118
 				font-size: 15px;
122
 				font-size: 15px;
119
 			}
123
 			}
124
 				margin-right: auto;
128
 				margin-right: auto;
125
 				padding-left: 12.5%; */
129
 				padding-left: 12.5%; */
126
 				font-family: et-book, Palatino, "Palatino Linotype", "Palatino LT STD", "Book Antiqua", Georgia, serif;
130
 				font-family: et-book, Palatino, "Palatino Linotype", "Palatino LT STD", "Book Antiqua", Georgia, serif;
127
-				background-color: #fffff8;
128
-				color: #111;
131
+				background-color: var(--color-background);
132
+				color: var(--color-text);
129
 				/* max-width: 1400px; */
133
 				/* max-width: 1400px; */
130
 				counter-reset: sidenote-counter;
134
 				counter-reset: sidenote-counter;
131
 			}
135
 			}
132
 
136
 
133
-			/* Adds dark mode */
134
-			@media (prefers-color-scheme: dark) {
135
-				body {
136
-					background-color: #151515;
137
-					color: #ddd;
138
-				}
139
-			}
140
 			h1 {
137
 			h1 {
141
 				font-weight: 400;
138
 				font-weight: 400;
142
 				margin-top: 4rem;
139
 				margin-top: 4rem;
160
 				margin-bottom: 1.4rem;
157
 				margin-bottom: 1.4rem;
161
 				line-height: 1;
158
 				line-height: 1;
162
 			}
159
 			}
160
+			.subtext {
161
+				font-size: 1rem;
162
+				color: #888;
163
+				margin-top: 0.25em;
164
+				margin-bottom: 0.5em;
165
+			}
166
+			mark {
167
+				background-color: var(--color-highlight);
168
+				color: var(--color-highlight-text);
169
+			}
170
+			table {
171
+				margin-top: 1em;
172
+				margin-bottom: 1em;
173
+				border-collapse: collapse;
174
+			}
175
+			td, th {
176
+				padding: 0.4em 0.8em;
177
+				font-size: 1rem;
178
+			}
179
+			th {
180
+				background-color: var(--color-table-header);
181
+				border-bottom: 2px solid var(--color-text);
182
+			}
183
+			tr:not(:last-child) td {
184
+				border-bottom: 1px solid var(--color-text);
185
+			}
186
+			tr td:not(:last-child) {
187
+				border-right: 1px solid var(--color-table-header);
188
+			}
163
 			hr {
189
 			hr {
164
 				display: block;
190
 				display: block;
165
 				height: 1px;
191
 				height: 1px;
177
 				padding-bottom: 1rem;
203
 				padding-bottom: 1rem;
178
 			}
204
 			}
179
 			p,
205
 			p,
180
-			dl,
181
 			ol,
206
 			ol,
182
 			ul {
207
 			ul {
183
 				font-size: 1.4rem;
208
 				font-size: 1.4rem;
214
 			li:not(:first-child) {
239
 			li:not(:first-child) {
215
 				margin-top: 0.25rem;
240
 				margin-top: 0.25rem;
216
 			}
241
 			}
242
+			dt, dd {
243
+				font-size: 1.2rem;
244
+			}
245
+			dt {
246
+				font-weight: bold;
247
+			}
248
+			.footnotes, .footnotes li {
249
+				font-size: 80%;
250
+			}
251
+			.footnotes li:target, sup:target a {
252
+				background-color: var(--color-highlight);
253
+				color: var(--color-highlight-text);
254
+			}
217
 
255
 
218
 		</style>
256
 		</style>
219
 		<script src="js/markdown.js"></script>
257
 		<script src="js/markdown.js"></script>
227
 			}
265
 			}
228
 			function onMarkdownChange() {
266
 			function onMarkdownChange() {
229
 				let markdown = document.getElementById('markdowninput').value;
267
 				let markdown = document.getElementById('markdowninput').value;
230
-				let html = parser.toHTML(markdown);
268
+				let html = parser.toHTML(markdown, 'foo-');
231
 				document.getElementById('preview').innerHTML = html;
269
 				document.getElementById('preview').innerHTML = html;
232
 			}
270
 			}
233
 			var blockReaderClasses = {
271
 			var blockReaderClasses = {
334
 			</div>
372
 			</div>
335
 			<textarea id="markdowninput">## Block Formats {#top}
373
 			<textarea id="markdowninput">## Block Formats {#top}
336
 
374
 
375
+				A regular paragraph.
376
+
377
+				-# Sub text
378
+
337
 				* Unordered
379
 				* Unordered
338
 				* Lists
380
 				* Lists
339
 				  * Sub list
381
 				  * Sub list
340
-				
382
+
341
 				1. Ordered
383
 				1. Ordered
342
 				2. Lists
384
 				2. Lists
343
 				  6. Sub list
385
 				  6. Sub list
344
-				
345
-				&gt; A block quote lorem ipsum dolor sit amet
346
-				
347
-				A regular paragraph
348
-				
386
+
387
+				A blockquote:
388
+
389
+				&gt; "The only thing we have to fear is fear itself—nameless, unreasoning, unjustified terror which paralyzes needed efforts to convert retreat into advance." - Franklin D. Roosevelt's First Inaugural Address
390
+
391
+				Some definitions:
392
+
349
 				word
393
 				word
350
 				: a unit of meaning in a sentence
394
 				: a unit of meaning in a sentence
351
 				sentence
395
 				sentence
352
 				: a collection of words
396
 				: a collection of words
353
-				
397
+
398
+				Code:
399
+
354
 				```javascript
400
 				```javascript
355
 				function foo() {
401
 				function foo() {
356
-					return 'Fenced code block';
402
+					return 'Hello world';
357
 				}
403
 				}
358
 				```
404
 				```
359
-				
405
+
360
 					function bar() {
406
 					function bar() {
361
 						return 'Indented code';
407
 						return 'Indented code';
362
 					}
408
 					}
363
-				
409
+
364
 				### Heading, hash style
410
 				### Heading, hash style
365
-				
411
+
366
 				Heading, underline style
412
 				Heading, underline style
367
 				---
413
 				---
368
-				
414
+
369
 				### Modified Heading {style=color:red;}
415
 				### Modified Heading {style=color:red;}
370
-				
371
-				-# Sub text
372
-				
416
+
373
 				| Unit Price | Qty | Subtotal |
417
 				| Unit Price | Qty | Subtotal |
374
 				| ---: | ---: | ---: |
418
 				| ---: | ---: | ---: |
375
 				| $1.23 | 2 | =A*B FILL |
419
 				| $1.23 | 2 | =A*B FILL |
376
 				| $4.99 | 6 | |
420
 				| $4.99 | 6 | |
377
 				| Total | | =SUM(C:C) |
421
 				| Total | | =SUM(C:C) |
378
-				
422
+
379
 				---
423
 				---
380
-				
424
+
381
 				## Inline Formats
425
 				## Inline Formats
382
-				
426
+
383
 				Normal, **double asterisk,** __double underscore,__ *asterisks,* _underscores,_ ~~double tildes,~~ ~single tildes,~ ^carets,^ ==double equals==, ``double backticks``, `single backticks`.
427
 				Normal, **double asterisk,** __double underscore,__ *asterisks,* _underscores,_ ~~double tildes,~~ ~single tildes,~ ^carets,^ ==double equals==, ``double backticks``, `single backticks`.
384
-				
428
+
385
 				Lorem ipsum dolor sit amet,[^1] consectetur adipiscing elit.[^abc] Sed sodales in odio eget porta. Proin et erat sit amet erat semper mollis vitae ut turpis.[^foo] Ut ipsum dui, maximus sit amet suscipit at, dictum id nulla.[^bar] Aenean efficitur rhoncus nulla non fermentum.
429
 				Lorem ipsum dolor sit amet,[^1] consectetur adipiscing elit.[^abc] Sed sodales in odio eget porta. Proin et erat sit amet erat semper mollis vitae ut turpis.[^foo] Ut ipsum dui, maximus sit amet suscipit at, dictum id nulla.[^bar] Aenean efficitur rhoncus nulla non fermentum.
386
-				
430
+
387
 				[^1]: Donec ut felis volutpat, gravida ipsum scelerisque, accumsan est.
431
 				[^1]: Donec ut felis volutpat, gravida ipsum scelerisque, accumsan est.
388
 				[^abc]: Cras dictum rutrum quam.
432
 				[^abc]: Cras dictum rutrum quam.
389
 				[^foo]: Donec maximus bibendum lorem.
433
 				[^foo]: Donec maximus bibendum lorem.
390
 				[^bar]: Praesent consectetur tristique leo. Morbi nec nisi sit amet quam imperdiet vehicula eu feugiat tortor. 
434
 				[^bar]: Praesent consectetur tristique leo. Morbi nec nisi sit amet quam imperdiet vehicula eu feugiat tortor. 
391
-				
435
+
392
 				The HTML on the WWW is often full of JS and CSS.
436
 				The HTML on the WWW is often full of JS and CSS.
393
-				
437
+
394
 				*[HTML]: Hypertext Markup Language
438
 				*[HTML]: Hypertext Markup Language
395
 				*[WWW]: World Wide Web
439
 				*[WWW]: World Wide Web
396
 				*[JS]: JavaScript
440
 				*[JS]: JavaScript
397
 				*[CSS]: Cascading Style Sheets
441
 				*[CSS]: Cascading Style Sheets
398
-				
442
+
399
 				Click [here](#top) to return to the top. Referenced link to [Google][google title="I prefer Duck Duck Go"].
443
 				Click [here](#top) to return to the top. Referenced link to [Google][google title="I prefer Duck Duck Go"].
400
-				
444
+
401
 				![alt text](https://picsum.photos/100/75) ![alt text](https://picsum.photos/101/75 "With a title") ![][testimage]
445
 				![alt text](https://picsum.photos/100/75) ![alt text](https://picsum.photos/101/75 "With a title") ![][testimage]
402
-				
446
+
403
 				[testimage]: https://picsum.photos/102/75
447
 				[testimage]: https://picsum.photos/102/75
404
 				[google]: https://google.com
448
 				[google]: https://google.com
405
-				
449
+
406
 				Some verbatim &lt;span style="color:green;"&gt;HTML&lt;/span&gt;. A script tag will be ignored. &lt;script&gt;&lt;/script&gt;
450
 				Some verbatim &lt;span style="color:green;"&gt;HTML&lt;/span&gt;. A script tag will be ignored. &lt;script&gt;&lt;/script&gt;
407
 			</textarea>
451
 			</textarea>
408
 		</div>
452
 		</div>

Загрузка…
Отмена
Сохранить