Skip to content

Commit

Permalink
Fix duplicate heading id. marked#1401
Browse files Browse the repository at this point in the history
  • Loading branch information
yahtnif committed Mar 15, 2019
1 parent 8c84c88 commit 75443c3
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 22 deletions.
2 changes: 1 addition & 1 deletion __tests__/base/footnote
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ footnote one[^1] and two[^two]

<p>footnote one<sup id="fnref:1"><a href="#fn:1" class="footnote-ref" role="doc-noteref">1</a></sup> and two<sup id="fnref:two"><a href="#fn:two" class="footnote-ref" role="doc-noteref">2</a></sup></p>
<div class="footnotes" role="doc-endnotes"><hr>
<ol><li id="fn:1" role="doc-endnote"><span class="cite-text">This is the first footnote.</span><a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#8617;</a></li><li id="fn:two" role="doc-endnote"><span class="cite-text">This is the second footnote.</span><a href="#fnref:two" class="footnote-backref" role="doc-backlink">&#8617;</a></li></ol></div>
<ol><li id="fn:1" role="doc-endnote"><span class="cite-text">This is the first footnote.</span><a href="#fnref:1" class="footnote-backref" role="doc-backlink">&#8617;</a></li><li id="fn:two" role="doc-endnote"><span class="cite-text">This is the second footnote.</span><a href="#fnref:two" class="footnote-backref" role="doc-backlink">&#8617;</a></li></ol></div>
2 changes: 1 addition & 1 deletion src/block-lexer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ export class BlockLexer {

const item: Token = {
type: TokenType.footnote,
refname: this.options.slug(execArr[1]),
refname: this.options.slug(execArr[1], false),
text: execArr[2]
}

Expand Down
55 changes: 41 additions & 14 deletions src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ export function escape(html: string, encode?: boolean): string {
return html.replace(escapeReplaceRegex, (ch: string) => replacements[ch])
}
} else if (escapeTestNoEncodeRegex.test(html)) {
return html.replace(escapeReplaceNoEncodeRegex, (ch: string) => replacements[ch])
return html.replace(
escapeReplaceNoEncodeRegex,
(ch: string) => replacements[ch]
)
}

return html
Expand All @@ -46,21 +49,41 @@ export function unescape(html: string): string {
}

const htmlTagsRegex: RegExp = /<(?:.|\n)*?>/gm
const specialCharsRegex: RegExp = /[!\"#$%&'\(\)\*\+,\/:;<=>\?\@\[\\\]\^`\{\|\}~]/g
const specialCharsRegex: RegExp = /[\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,./:;<=>?@[\]^`{|}~]/g
const dotSpaceRegex: RegExp = /(\s|\.)/g

export function slug(str: string): string {
return str
// Remove html tags
.replace(htmlTagsRegex, '')
// Remove special characters
.replace(specialCharsRegex, '')
// Replace dots and spaces with a separator
.replace(dotSpaceRegex, '-')
// Make the whole thing lowercase
.toLowerCase()
class Slugger {
seen: EmptyObject = {}

slug(value: string, isUnique?: boolean): string {
let slug = value
.trim()
// Remove html tags
.replace(htmlTagsRegex, '')
// Remove special characters
.replace(specialCharsRegex, '')
// Replace dots and spaces with a separator
.replace(dotSpaceRegex, '-')
// Make the whole thing lowercase
.toLowerCase()

if (isUnique !== false) {
if (this.seen.hasOwnProperty(slug)) {
const originalSlug = slug
do {
this.seen[originalSlug]++
slug = originalSlug + '-' + this.seen[originalSlug]
} while (this.seen.hasOwnProperty(slug))
}
this.seen[slug] = 0
}

return slug
}
}

export const slugger = new Slugger()

// Remove trailing 'c's. Equivalent to str.replace(/c*$/, '').
// /c*$/ is vulnerable to REDOS.
// invert: Remove suffix of non-c chars instead. Default falsey.
Expand Down Expand Up @@ -120,7 +143,11 @@ export function resolveUrl(base: string, href: string): string {
}
}

export function cleanUrl(sanitize: boolean, base: string, href: string): string {
export function cleanUrl(
sanitize: boolean,
base: string,
href: string
): string {
if (sanitize) {
let prot: string

Expand Down Expand Up @@ -202,4 +229,4 @@ export function isBlockRule(regExp: RegExp): boolean {
return regExp.source.indexOf('\\n') > -1
}

export const blockCommentRegex = /<!--(?!-?>)[\s\S]*?-->/
export const blockCommentRegex = /<!--(?!-?>)[\s\S]*?-->/
12 changes: 8 additions & 4 deletions src/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
escape,
resolveUrl,
rtrim,
slug,
slugger,
unescape
} from './helpers'
import { Renderer } from './renderer'
Expand Down Expand Up @@ -165,7 +165,7 @@ export class Options {
xhtml?: boolean = false
escape?: (html: string, encode?: boolean) => string = escape
unescape?: (html: string) => string = unescape
slug?: (str: string) => string = slug
slug?: (str: string, isUnique?: boolean) => string = (str: string, isUnique?: boolean): string => slugger.slug(str, isUnique)
rtrim?: (str: string, c: string, invert?: boolean) => string = rtrim
resolveUrl?: (base: string, href: string) => string = resolveUrl
cleanUrl?: (sanitize: boolean, base: string, href: string) => string = cleanUrl
Expand All @@ -187,7 +187,7 @@ export interface LexerReturns {
}

export interface EmptyObject {
[key: string]: string
[key: string]: any
}

export type NewRenderer = (execArr?: RegExpExecArray) => string
Expand Down Expand Up @@ -223,4 +223,8 @@ export interface BlockRule {
export interface TablecellFlags {
align?: Align
header?: boolean
}
}

export interface Footnotes {
[key: string]: string
}
4 changes: 2 additions & 2 deletions src/renderer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Options, TablecellFlags } from './interfaces'
import { Footnotes, Options, TablecellFlags } from './interfaces'

export class Renderer {
private _footnotes: string[] = []
Expand Down Expand Up @@ -46,7 +46,7 @@ ${quote}</blockquote>
`
}

footnote(footnotes: { [key: string]: string }): string {
footnote(footnotes: Footnotes): string {
let out: string = `<div class="footnotes" role="doc-endnotes">${this.hr()}<ol>`

for (const refname of this._footnotes) {
Expand Down

0 comments on commit 75443c3

Please sign in to comment.