commit
dfbc9a1efd
@ -953,13 +953,13 @@ Renderer.prototype.html = function(html) {
|
||||
return html;
|
||||
};
|
||||
|
||||
Renderer.prototype.heading = function(text, level, raw) {
|
||||
Renderer.prototype.heading = function(text, level, raw, slugger) {
|
||||
if (this.options.headerIds) {
|
||||
return '<h'
|
||||
+ level
|
||||
+ ' id="'
|
||||
+ this.options.headerPrefix
|
||||
+ raw.toLowerCase().replace(/[^\w]+/g, '-')
|
||||
+ slugger.slug(raw)
|
||||
+ '">'
|
||||
+ text
|
||||
+ '</h'
|
||||
@ -1108,6 +1108,7 @@ function Parser(options) {
|
||||
this.options.renderer = this.options.renderer || new Renderer();
|
||||
this.renderer = this.options.renderer;
|
||||
this.renderer.options = this.options;
|
||||
this.slugger = new Slugger();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1186,7 +1187,8 @@ Parser.prototype.tok = function() {
|
||||
return this.renderer.heading(
|
||||
this.inline.output(this.token.text),
|
||||
this.token.depth,
|
||||
unescape(this.inlineText.output(this.token.text)));
|
||||
unescape(this.inlineText.output(this.token.text)),
|
||||
this.slugger);
|
||||
}
|
||||
case 'code': {
|
||||
return this.renderer.code(this.token.text,
|
||||
@ -1283,6 +1285,37 @@ Parser.prototype.tok = function() {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Slugger generates header id
|
||||
*/
|
||||
|
||||
function Slugger () {
|
||||
this.seen = {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert string to unique id
|
||||
*/
|
||||
|
||||
Slugger.prototype.slug = function (value) {
|
||||
var slug = value
|
||||
.toLowerCase()
|
||||
.trim()
|
||||
.replace(/[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g, '')
|
||||
.replace(/\s/g, '-');
|
||||
|
||||
if (this.seen.hasOwnProperty(slug)) {
|
||||
var originalSlug = slug;
|
||||
do {
|
||||
this.seen[originalSlug]++;
|
||||
slug = originalSlug + '-' + this.seen[originalSlug];
|
||||
} while (this.seen.hasOwnProperty(slug));
|
||||
}
|
||||
this.seen[slug] = 0;
|
||||
|
||||
return slug;
|
||||
};
|
||||
|
||||
/**
|
||||
* Helpers
|
||||
*/
|
||||
@ -1617,6 +1650,8 @@ marked.lexer = Lexer.lex;
|
||||
marked.InlineLexer = InlineLexer;
|
||||
marked.inlineLexer = InlineLexer.output;
|
||||
|
||||
marked.Slugger = Slugger;
|
||||
|
||||
marked.parse = marked;
|
||||
|
||||
if (typeof module !== 'undefined' && typeof exports === 'object') {
|
||||
|
@ -11,7 +11,7 @@ baz</p>
|
||||
<p>The spaces after the <code>></code> characters can be omitted:</p>
|
||||
|
||||
<blockquote>
|
||||
<h1 id="foo">Foo</h1>
|
||||
<h1 id="bar">Bar</h1>
|
||||
<p>bar
|
||||
baz</p>
|
||||
</blockquote>
|
||||
@ -21,7 +21,7 @@ baz</p>
|
||||
<p>The <code>></code> characters can be indented 1-3 spaces:</p>
|
||||
|
||||
<blockquote>
|
||||
<h1 id="foo">Foo</h1>
|
||||
<h1 id="baz">Baz</h1>
|
||||
<p>bar
|
||||
baz</p>
|
||||
</blockquote>
|
||||
@ -30,7 +30,7 @@ baz</p>
|
||||
|
||||
<p>Four spaces gives us a code block:</p>
|
||||
|
||||
<pre><code>> # Foo
|
||||
<pre><code>> # Qux
|
||||
> bar
|
||||
> baz</code></pre>
|
||||
|
||||
@ -39,7 +39,7 @@ baz</p>
|
||||
<p>The Laziness clause allows us to omit the <code>></code> before paragraph continuation text:</p>
|
||||
|
||||
<blockquote>
|
||||
<h1 id="foo">Foo</h1>
|
||||
<h1 id="quux">Quux</h1>
|
||||
<p>bar
|
||||
baz</p>
|
||||
</blockquote>
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
The spaces after the `>` characters can be omitted:
|
||||
|
||||
># Foo
|
||||
># Bar
|
||||
>bar
|
||||
> baz
|
||||
|
||||
@ -16,7 +16,7 @@ The spaces after the `>` characters can be omitted:
|
||||
|
||||
The `>` characters can be indented 1-3 spaces:
|
||||
|
||||
> # Foo
|
||||
> # Baz
|
||||
> bar
|
||||
> baz
|
||||
|
||||
@ -24,7 +24,7 @@ The `>` characters can be indented 1-3 spaces:
|
||||
|
||||
Four spaces gives us a code block:
|
||||
|
||||
> # Foo
|
||||
> # Qux
|
||||
> bar
|
||||
> baz
|
||||
|
||||
@ -32,7 +32,7 @@ Four spaces gives us a code block:
|
||||
|
||||
The Laziness clause allows us to omit the `>` before paragraph continuation text:
|
||||
|
||||
> # Foo
|
||||
> # Quux
|
||||
> bar
|
||||
baz
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
<h1 id="how-are-you">how are you</h1>
|
||||
|
||||
<p>paragraph before head with equals</p>
|
||||
<h1 id="how-are-you">how are you</h1>
|
||||
<h1 id="how-are-you-again">how are you again</h1>
|
||||
|
||||
<p>paragraph before blockquote</p>
|
||||
<blockquote><p>text for blockquote</p></blockquote>
|
||||
|
@ -17,7 +17,7 @@ paragraph before head with hash
|
||||
# how are you
|
||||
|
||||
paragraph before head with equals
|
||||
how are you
|
||||
how are you again
|
||||
===========
|
||||
|
||||
paragraph before blockquote
|
||||
|
@ -1,4 +1,4 @@
|
||||
<h1>Markdown: Basics</h1>
|
||||
<h1 id="markdown-basics">Markdown: Basics</h1>
|
||||
|
||||
<ul id="ProjectSubmenu">
|
||||
<li><a href="/projects/markdown/" title="Markdown Project Page">Main</a></li>
|
||||
@ -8,7 +8,7 @@
|
||||
<li><a href="/projects/markdown/dingus" title="Online Markdown Web Form">Dingus</a></li>
|
||||
</ul>
|
||||
|
||||
<h2>Getting the Gist of Markdown's Formatting Syntax</h2>
|
||||
<h2 id="getting-the-gist-of-markdowns-formatting-syntax">Getting the Gist of Markdown's Formatting Syntax</h2>
|
||||
|
||||
<p>This page offers a brief overview of what it's like to use Markdown.
|
||||
The <a href="/projects/markdown/syntax" title="Markdown Syntax">syntax page</a> provides complete, detailed documentation for
|
||||
@ -24,7 +24,7 @@ and translate it to XHTML.</p>
|
||||
<p><strong>Note:</strong> This document is itself written using Markdown; you
|
||||
can <a href="/projects/markdown/basics.text">see the source for it by adding '.text' to the URL</a>.</p>
|
||||
|
||||
<h2>Paragraphs, Headers, Blockquotes</h2>
|
||||
<h2 id="paragraphs-headers-blockquotes">Paragraphs, Headers, Blockquotes</h2>
|
||||
|
||||
<p>A paragraph is simply one or more consecutive lines of text, separated
|
||||
by one or more blank lines. (A blank line is any line that looks like a
|
||||
@ -88,7 +88,7 @@ dog's back.</p>
|
||||
</blockquote>
|
||||
</code></pre>
|
||||
|
||||
<h3>Phrase Emphasis</h3>
|
||||
<h3 id="phrase-emphasis">Phrase Emphasis</h3>
|
||||
|
||||
<p>Markdown uses asterisks and underscores to indicate spans of emphasis.</p>
|
||||
|
||||
@ -110,7 +110,7 @@ Some of these words <em>are emphasized also</em>.</p>
|
||||
Or, if you prefer, <strong>use two underscores instead</strong>.</p>
|
||||
</code></pre>
|
||||
|
||||
<h2>Lists</h2>
|
||||
<h2 id="lists">Lists</h2>
|
||||
|
||||
<p>Unordered (bulleted) lists use asterisks, pluses, and hyphens (<code>*</code>,
|
||||
<code>+</code>, and <code>-</code>) as list markers. These three markers are
|
||||
@ -181,7 +181,7 @@ the paragraphs by 4 spaces or 1 tab:</p>
|
||||
</ul>
|
||||
</code></pre>
|
||||
|
||||
<h3>Links</h3>
|
||||
<h3 id="links">Links</h3>
|
||||
|
||||
<p>Markdown supports two styles for creating links: <em>inline</em> and
|
||||
<em>reference</em>. With both styles, you use square brackets to delimit the
|
||||
@ -244,7 +244,7 @@ numbers and spaces, but are <em>not</em> case sensitive:</p>
|
||||
<a href="http://www.nytimes.com/">The New York Times</a>.</p>
|
||||
</code></pre>
|
||||
|
||||
<h3>Images</h3>
|
||||
<h3 id="images">Images</h3>
|
||||
|
||||
<p>Image syntax is very much like link syntax.</p>
|
||||
|
||||
@ -265,7 +265,7 @@ numbers and spaces, but are <em>not</em> case sensitive:</p>
|
||||
<pre><code><img src="/path/to/img.jpg" alt="alt text" title="Title" />
|
||||
</code></pre>
|
||||
|
||||
<h3>Code</h3>
|
||||
<h3 id="code">Code</h3>
|
||||
|
||||
<p>In a regular paragraph, you can create code span by wrapping text in
|
||||
backtick quotes. Any ampersands (<code>&</code>) and angle brackets (<code><</code> or
|
||||
|
@ -2,8 +2,9 @@ var marked = require('../../lib/marked.js');
|
||||
|
||||
describe('Test heading ID functionality', function() {
|
||||
it('should add id attribute by default', function() {
|
||||
var renderer = new marked.Renderer(marked.defaults);
|
||||
var header = renderer.heading('test', 1, 'test');
|
||||
var renderer = new marked.Renderer();
|
||||
var slugger = new marked.Slugger();
|
||||
var header = renderer.heading('test', 1, 'test', slugger);
|
||||
expect(header).toBe('<h1 id="test">test</h1>\n');
|
||||
});
|
||||
|
||||
@ -14,6 +15,51 @@ describe('Test heading ID functionality', function() {
|
||||
});
|
||||
});
|
||||
|
||||
describe('Test slugger functionality', function() {
|
||||
it('should use lowercase slug', function() {
|
||||
var slugger = new marked.Slugger();
|
||||
expect(slugger.slug('Test')).toBe('test');
|
||||
});
|
||||
|
||||
it('should be unique to avoid collisions 1280', function() {
|
||||
var slugger = new marked.Slugger();
|
||||
expect(slugger.slug('test')).toBe('test');
|
||||
expect(slugger.slug('test')).toBe('test-1');
|
||||
expect(slugger.slug('test')).toBe('test-2');
|
||||
});
|
||||
|
||||
it('should be unique when slug ends with number', function() {
|
||||
var slugger = new marked.Slugger();
|
||||
expect(slugger.slug('test 1')).toBe('test-1');
|
||||
expect(slugger.slug('test')).toBe('test');
|
||||
expect(slugger.slug('test')).toBe('test-2');
|
||||
});
|
||||
|
||||
it('should be unique when slug ends with hyphen number', function() {
|
||||
var slugger = new marked.Slugger();
|
||||
expect(slugger.slug('foo')).toBe('foo');
|
||||
expect(slugger.slug('foo')).toBe('foo-1');
|
||||
expect(slugger.slug('foo 1')).toBe('foo-1-1');
|
||||
expect(slugger.slug('foo-1')).toBe('foo-1-2');
|
||||
expect(slugger.slug('foo')).toBe('foo-2');
|
||||
});
|
||||
|
||||
it('should allow non-latin chars', function() {
|
||||
var slugger = new marked.Slugger();
|
||||
expect(slugger.slug('привет')).toBe('привет');
|
||||
});
|
||||
|
||||
it('should remove ampersands 857', function() {
|
||||
var slugger = new marked.Slugger();
|
||||
expect(slugger.slug('This & That Section')).toBe('this--that-section');
|
||||
});
|
||||
|
||||
it('should remove periods', function() {
|
||||
var slugger = new marked.Slugger();
|
||||
expect(slugger.slug('file.txt')).toBe('filetxt');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Test paragraph token type', function () {
|
||||
it('should use the "paragraph" type on top level', function () {
|
||||
const md = 'A Paragraph.\n\n> A blockquote\n\n- list item\n';
|
||||
|
Loading…
x
Reference in New Issue
Block a user