Skip to content

Commit

Permalink
Correctly handle unicode in anchors.
Browse files Browse the repository at this point in the history
URL-encode all unicode characters.

Fixes #397
  • Loading branch information
nene committed Aug 1, 2013
1 parent 3ff90c4 commit 5c90fba
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 2 deletions.
9 changes: 8 additions & 1 deletion lib/jsduck/guide_anchors.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
require 'cgi'

module JsDuck

# Transforms in-page links so they won't break docs app #!-navigation.
Expand All @@ -9,7 +11,7 @@ class GuideAnchors

def self.transform(html, guide_name)
html.gsub(/(<a\s+(?:[^<>]*\s+)?href=['"]#)([^!\/].*?)(['"])/i) do |m|
"#{$1}!/guide/#{guide_name}-section-#{$2}#{$3}"
$1 + "!/guide/" + transform_id($2, guide_name) + $3

end.gsub(/(<a\s+(?:[^<>]*\s+)?name=['"])(.*?)(['"])/i) do |m|
$1 + transform_id($2, guide_name) + $3
Expand All @@ -23,6 +25,11 @@ def self.transform_id(id, guide_name)
if id =~ /^#{guide_name}-section-/
id
else
# Escape the ID if it's not already escaped. This check is
# needed to avoid re-escaping anchor-links created with
# Markdown - these get auto-escaped by RDiscount.
id = (id =~ /%[0-9A-F]{2}/) ? id : CGI::escape(id)

"#{guide_name}-section-#{id}"
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/jsduck/guide_toc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def self.inject(html, guide_name)
end

def self.title_to_id(title)
title.downcase.gsub(/[^\w]+/, "-")
CGI::escape(title.downcase.gsub(/ /, "-"))
end

end
Expand Down
16 changes: 16 additions & 0 deletions spec/guide_anchors_spec.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
require "jsduck/guide_anchors"

describe JsDuck::GuideAnchors do
Expand All @@ -21,6 +22,11 @@ def transform(html)
"Some\nlong\ntext\nhere...\n\n <a href='#!/guide/myguide-section-blah'>label</a>"
end

it "URL-encodes unicode anchors links" do
transform("<a href='#fäg'>label</a>").should ==
"<a href='#!/guide/myguide-section-f%C3%A4g'>label</a>"
end

it "doesn't transform normal links" do
transform("<a href='http://example.com'>label</a>").should ==
"<a href='http://example.com'>label</a>"
Expand All @@ -41,6 +47,11 @@ def transform(html)
"<a name='myguide-section-blah'>target</a>"
end

it "URL-encodes unicode in anchors" do
transform("<a name='fäg'>target</a>").should ==
"<a name='myguide-section-f%C3%A4g'>target</a>"
end

it "doesn't transform anchors already in target format" do
transform("<a name='myguide-section-blah'>target</a>").should ==
"<a name='myguide-section-blah'>target</a>"
Expand All @@ -51,6 +62,11 @@ def transform(html)
"<h1 id='myguide-section-blah'>target</h1>"
end

it "URL-encodes unicode in ID-s" do
transform("<h1 id='fäg'>target</h1>").should ==
"<h1 id='myguide-section-f%C3%A4g'>target</h1>"
end

it "doesn't transform ID-s already in target format" do
transform("<h1 id='myguide-section-blah'>target</h1>").should ==
"<h1 id='myguide-section-blah'>target</h1>"
Expand Down
14 changes: 14 additions & 0 deletions spec/guide_toc_spec.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
require "jsduck/guide_toc"

describe JsDuck::GuideToc do
Expand Down Expand Up @@ -30,13 +31,26 @@ def inject(html)
EOHTML
end

it "URL-encodes unicode in heading ID-s" do
inject(<<-EOHTML).should =~ /<h2 id='myguide-section-my-f%C3%A4pter'>My Fäpter/
<h2>My Fäpter</h2>
EOHTML
end

it "links to headings from TOC" do
inject(<<-EOHTML).should =~ /<a href='#!\/guide\/myguide-section-my-chapter'>/
<h2>My Chapter</h2>
<h2>Another Chapter</h2>
EOHTML
end

it "links to unicode headings from TOC" do
inject(<<-EOHTML).should =~ /<a href='#!\/guide\/myguide-section-my-f%C3%A4pter'>/
<h2>My Fäpter</h2>
<h2>Another Fäpter</h2>
EOHTML
end

it "adds ID-s to H2 headings even when no TOC" do
inject(<<-EOHTML).should =~ /<h2 id='myguide-section-my-chapter'>My Chapter/
<h2>My Chapter</h2>
Expand Down

0 comments on commit 5c90fba

Please sign in to comment.