2 new revisions:

Revision: c987c472da41
Branch:   default
Author:   Pekka Klärck
Date:     Tue Apr 22 10:24:07 2014 UTC
Log: Libdoc: Better test data for manually testing encoding/escaping links....
http://code.google.com/p/robotframework/source/detail?r=c987c472da41

Revision: 08b120e0dc78
Branch:   default
Author:   Pekka Klärck
Date:     Tue Apr 22 10:32:06 2014 UTC
Log:      Libdoc: Encode and escape internal links correctly...
http://code.google.com/p/robotframework/source/detail?r=08b120e0dc78

==============================================================================
Revision: c987c472da41
Branch:   default
Author:   Pekka Klärck
Date:     Tue Apr 22 10:24:07 2014 UTC
Log: Libdoc: Better test data for manually testing encoding/escaping links.

Update issue 1678
Better test data for manually testing generated docs. The file to use is visible here:
https://robotframework.googlecode.com/hg/src/robot/htmldata/libdoc/libdoc.html
http://code.google.com/p/robotframework/source/detail?r=c987c472da41

Modified:
 /src/robot/htmldata/testdata/libdoc.js
 /src/robot/htmldata/testdata/libdoc.txt

=======================================
--- /src/robot/htmldata/testdata/libdoc.js      Wed May 30 10:57:08 2012 UTC
+++ /src/robot/htmldata/testdata/libdoc.js      Tue Apr 22 10:24:07 2014 UTC
@@ -1,2 +1,1 @@
-libdoc = {"doc":"<p><b>URL:</b> <a href=\"http://robotframework.org\";>http://robotframework.org</a></p>\n<p><i>Image:</i> <img src=\"http://code.google.com/p/robotframework/logo?ext.png\"; title=\"http://code.google.com/p/robotframework/logo?ext.png\";></p>\n<hr>\n<table>\n<tr>\n<td><b>My</b></td>\n<td><b>Table</b></td>\n</tr>\n<tr>\n<td>1</td>\n<td>2</td>\n</tr>\n<tr>\n<td>foo</td>\n<td></td>\n</tr>\n</table>\n<p>regular line</p>\n<pre>\nblock formatted\n content\t\tand whitespaces\n</pre>","generated":"2012-05-30 13:55:22","inits":[],"keywords":[{"args":"","doc":"<hr>\n<hr>\n<hr>","name":"HR","shortdoc":"---"},{"args":"","doc":"<p><img src=\"http://code.google.com/p/robotframework/logo?ext.png\"; title=\"http://code.google.com/p/robotframework/logo?ext.png\";></p>\n<p>Images are <img src=\"http://code.google.com/p/robotframework/logo?ext.png\"; title=\"title\"> inside paragraphs. This one is also a link: <a href=\"http://code.google.com/p/robotframework/logo?ext.png\";><img src=\"http://code.google.com/p/robotframework/logo?ext.png\"; title=\"http://code.google.com/p/robotframework/logo?ext.png\";></a></p>","name":"Images","shortdoc":"http://code.google.com/p/robotframework/logo?ext.png"},{"args":"","doc":";<ul>\n<li>first</li>\n<li>second</li>\n</ul>\n<ul>\n<li>another</li>\n</ul>","name":"Lists","shortdoc":"- first"},{"args":"","doc":"<p>Hell, world!</p>\n<p>Second paragraph <b>has formatting</b> and <a href=\"http://example.com\";>link</a>. This is still part of second paragraph.</p>\n<p>Third paragraph is <i>short</i>.</p>","name":"Multiple paragraps","shortdoc":"Hell, world!"},{"args":"","doc":"<p>Hello, world!</p>","name":"One paragraph","shortdoc":"Hello, world!"},{"args":"","doc":"<pre>\nFirst block\nhas two lines\n</pre>\n<pre>\nSecond has only one\n</pre>","name":"Preformatted","shortdoc":"| First block"},{"args":"","doc":"<table>\n<tr>\n<td><b>a</b></td>\n<td><b>b</b></td>\n<td><b>c</b></td>\n</tr>\n<tr>\n<td>1st</td>\n<td>table</td>\n<td>here</td>\n</tr>\n</table>\n<table>\n<tr>\n<td>2nd</td>\n<td>table</td>\n<td>has</td>\n<td>only</td>\n<td>one</td>\n<td>row</td>\n</tr>\n</table>","name":"Tables alone","shortdoc":"| *a* | *b* | *c* |"}],"name":"libdoc","named_args":true,"scope":"","version":""};
-
+libdoc = {"doc":"<p><b>URL:\x3c/b> <a href=\"http://robotframework.org\";>http://robotframework.org\x3c/a>\x3c/p>\n<p><i>Image:\x3c/i> <img src=\"http://code.google.com/p/robotframework/logo?ext.png\"; title=\"http://code.google.com/p/robotframework/logo?ext.png\";>\x3c/p>\n<p><i><b>Cross linking\x3c/b>\x3c/i>: <a href=\"#Links\" class=\"name\">Links\x3c/a>, <a href=\"#One%20paragraph\" class=\"name\">One Paragraph\x3c/a>, <a href=\"#HR\" class=\"name\">HR\x3c/a>, <a href=\"#HR\" class=\"name\">hr\x3c/a>. <a href=\"#Section\" class=\"name\">section\x3c/a>, <a href=\"#N%C3%B6n-%C3%84SC%C3%8F%C3%8F\" class=\"name\">Nön-ÄSCÏÏ\x3c/a>, <a href=\"#Special%20%C2%BD!%22%23%C2%A4%25%26%2F()%3D%3F%3C%7C%3E%2B-_.!~*'()%20chars\" class=\"name\">Special ½!\"#¤%&amp;/()=?&lt;|&gt;+-_.!~*'() chars\x3c/a>\x3c/p>\n<hr>\n<h2 id=\"Section\">Section\x3c/h2>\n<h3 id=\"Subsection with Ääkköset\">Subsection with Ääkköset\x3c/h3>\n<table border=\"1\">\n<tr>\n<td><b>My\x3c/b>\x3c/td>\n<td><b>Table\x3c/b>\x3c/td>\n\x3c/tr>\n<tr>\n<td>1\x3c/td>\n<td>2\x3c/td>\n\x3c/tr>\n<tr>\n<td>foo\x3c/td>\n<td>\x3c/td>\n\x3c/tr>\n\x3c/table>\n<p>regular line\x3c/p>\n<pre>\nblock formatted\n content\t\tand whitespaces\n\x3c/pre>","generated":"2014-04-22 12:41:21","inits":[],"keywords":[{"args":"","doc":"<hr>\n<hr>\n<hr>","name":"HR","shortdoc":"---"},{"args":"","doc":"<p><img src=\"http://code.google.com/p/robotframework/logo?ext.png\"; title=\"http://code.google.com/p/robotframework/logo?ext.png\";>\x3c/p>\n<p>Images are <img src=\"http://code.google.com/p/robotframework/logo?ext.png\"; title=\"title\"> inside paragraphs. This one is also a link: <a href=\"http://code.google.com/p/robotframework/logo?ext.png\";><img src=\"http://code.google.com/p/robotframework/logo?ext.png\"; title=\"http://code.google.com/p/robotframework/logo?ext.png\";>\x3c/a>\x3c/p>","name":"Images","shortdoc":"http://code.google.com/p/robotframework/logo?ext.png"},{"args":"","doc":";<ul>\n<li><a href=\"#Lists\" class=\"name\">Lists\x3c/a>, <a href=\"#One%20paragraph\" class=\"name\">One Paragraph\x3c/a>, <a href=\"#HR\" class=\"name\">HR\x3c/a>, <a href=\"#HR\" class=\"name\">hr\x3c/a>, <a href=\"#N%C3%B6n-%C3%84SC%C3%8F%C3%8F\" class=\"name\">nön-äscïï\x3c/a>, <a href=\"#Special%20%C2%BD!%22%23%C2%A4%25%26%2F()%3D%3F%3C%7C%3E%2B-_.!~*'()%20chars\" class=\"name\">Special ½!\"#¤%&amp;/()=?&lt;|&gt;+-_.!~*'() chars\x3c/a>\x3c/li>\n<li><a href=\"#Section\" class=\"name\">Section\x3c/a>, <a href=\"#Subsection%20with%20%C3%84%C3%A4kk%C3%B6set\" class=\"name\">Sub section with ääkköset\x3c/a>\x3c/li>\n<li><a href=\"#Shortcuts\" class=\"name\">Shortcuts\x3c/a>, <a href=\"#Keywords\" class=\"name\">keywords\x3c/a>, <a href=\"#Introduction\" class=\"name\">LIBRARY intro duct ion\x3c/a>\x3c/li>\n<li><a href=\"http://robotframework.org\";>http://robotframework.org\x3c/a>\x3c/li>\n<li><a href=\"http://robotframework.org\";>Robot Framework\x3c/a>\x3c/li>\n\x3c/ul>","name":"Links","shortdoc":"- `Lists`, `One Paragraph`, `HR`, `hr`, `nön-äscïï`, `Special ½!\"#¤%&/()=?<|
+-_.!~*'()
chars`"},{"args":"","doc":"<ul>\n<li>first\x3c/li>\n<li>second\x3c/li>\n\x3c/ul>\n<ul>\n<li>another\x3c/li>\n\x3c/ul>","name":"Lists","shortdoc":"- first"},{"args":"","doc":"<p>Hell, world!\x3c/p>\n<p>Second paragraph <b>has formatting\x3c/b> and <a href=\"http://example.com\";>link\x3c/a>. This is still part of second paragraph.\x3c/p>\n<p>Third paragraph is <i>short\x3c/i>.\x3c/p>","name":"Multiple paragraps","shortdoc":"Hell, world!"},{"args":"","doc":"<p>Älsö döc häs nön-äscïï stüff. Ïnclüdïng ☃.\x3c/p>","name":"Nön-ÄSCÏÏ","shortdoc":"Älsö döc häs nön-äscïï stüff. Ïnclüdïng ☃."},{"args":"","doc":"<p>Hello, world!\x3c/p>","name":"One paragraph","shortdoc":"Hello, world!"},{"args":"","doc":"<pre>\nFirst block\nhas two lines\n\x3c/pre>\n<pre>\nSecond has only one\n\x3c/pre>","name":"Preformatted","shortdoc":"| First block"},{"args":"","doc":"<p>Also has has ½!\"#¤%&amp;/()=?&lt;| &gt;+-_.!~*'()\x3c/p>","name":"Special ½!\"#¤%&/()=?<|>+-_.!~*'() chars","shortdoc":"Also has has ½!\"#¤%&/()=?<|
+-_.!~*'()"},{"args":"","doc":"<table
border=\"1\">\n<tr>\n<td><b>a\x3c/b>\x3c/td>\n<td><b>b\x3c/b>\x3c/td>\n<td><b>c\x3c/b>\x3c/td>\n\x3c/tr>\n<tr>\n<td>1st\x3c/td>\n<td>table\x3c/td>\n<td>here\x3c/td>\n\x3c/tr>\n\x3c/table>\n<table border=\"1\">\n<tr>\n<td>2nd\x3c/td>\n<td>table\x3c/td>\n<td>has\x3c/td>\n<td>only\x3c/td>\n<td>one\x3c/td>\n<td>row\x3c/td>\n\x3c/tr>\n\x3c/table>","name":"Tables alone","shortdoc":"| *a* | *b* | *c* |"},{"args":"","doc":"<p>Last keyword has a bit longer documentation to make sure page moves when testing linking to keywords.\x3c/p>\n<ul>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n<li>- -\x3c/li>\n\x3c/ul>","name":"ZZZ - Long documentation","shortdoc":"Last keyword has a bit longer documentation to make sure page moves"}],"name":"libdoc","named_args":true,"scope":"","version":""};
=======================================
--- /src/robot/htmldata/testdata/libdoc.txt     Wed May 30 10:57:08 2012 UTC
+++ /src/robot/htmldata/testdata/libdoc.txt     Tue Apr 22 10:24:07 2014 UTC
@@ -3,8 +3,14 @@
 ...
... _Image:_ http://code.google.com/p/robotframework/logo?ext.png
 ...
+...            _*Cross linking*_: `Links`, `One Paragraph`, `HR`, `hr`.
+... `section`, `Nön-ÄSCÏÏ`, `Special ½!"#¤%&/()=?<|>+-_.!~*'() chars`
+...
 ...            ----------------------------
 ...
+...            = Section =
+...            == Subsection with Ääkköset ==
+...
 ...            | *My* | *Table* |
 ...            | 1    | 2       |
 ...            | foo  |
@@ -53,6 +59,14 @@
     ...
     ...    ---------------

+Links
+    [Documentation]
+ ... - `Lists`, `One Paragraph`, `HR`, `hr`, `nön-äscïï`, `Special ½!"#¤%&/()=?<|>+-_.!~*'() chars`
+    ...    - `Section`, `Sub section with ääkköset`
+    ...    - `Shortcuts`, `keywords`, `LIBRARY intro duct ion`
+    ...    - http://robotframework.org
+    ...    - [http://robotframework.org|Robot Framework]
+
 Images
     [Documentation]
     ...    http://code.google.com/p/robotframework/logo?ext.png
@@ -60,3 +74,82 @@
... Images are [http://code.google.com/p/robotframework/logo?ext.png|title]
     ...    inside paragraphs. This one is also a link:
... [http://code.google.com/p/robotframework/logo?ext.png| http://code.google.com/p/robotframework/logo?ext.png]
+
+Nön-ÄSCÏÏ
+    [Documentation]
+    ...    Älsö döc häs nön-äscïï stüff. Ïnclüdïng \u2603.
+
+Special ½!"#¤%&/()=?<|>+-_.!~*'() chars
+    [Documentation]
+    ...    Also has has ½!"#¤%&/()=?<|>+-_.!~*'()
+
+ZZZ - Long documentation
+    [Documentation]
+ ... Last keyword has a bit longer documentation to make sure page moves
+    ...    when testing linking to keywords.
+    ...
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -
+    ...   - - -

==============================================================================
Revision: 08b120e0dc78
Branch:   default
Author:   Pekka Klärck
Date:     Tue Apr 22 10:32:06 2014 UTC
Log:      Libdoc: Encode and escape internal links correctly

Update issue 1678
Status: Done
This commit contains follawing changes:
- Links to keywords in Shortcuts section are percent encoded using encodeURIComponent in HTML template. - Cross-reference links are percent encoded in Python by emulating encodeURIComponent using urllib.quote. - Cross-reference matching when target name contains HTML entities (&<>) is fixed.
http://code.google.com/p/robotframework/source/detail?r=08b120e0dc78

Modified:
 /atest/robot/libdoc/internal_linking.txt
 /atest/testdata/libdoc/InternalLinking.py
 /src/robot/htmldata/libdoc/libdoc.html
 /src/robot/libdocpkg/htmlwriter.py

=======================================
--- /atest/robot/libdoc/internal_linking.txt    Mon Jun 10 02:25:23 2013 UTC
+++ /atest/robot/libdoc/internal_linking.txt    Tue Apr 22 10:32:06 2014 UTC
@@ -15,47 +15,59 @@

 Linking to sections in importing and keywords
     ${MODEL['inits'][0]}       Introduction    introduction
-    ${MODEL['keywords'][0]}    Importing       Importing
-    ${MODEL['keywords'][1]}    Shortcuts       shortcuts
+    ${MODEL['keywords'][1]}    Importing       Importing
+    ${MODEL['keywords'][2]}    Shortcuts       shortcuts

 Linking to keywords in introduction
     ${MODEL}    Keyword           Keyword
-    ${MODEL}    Second Keyword    secoNd kEywoRD
+    ${MODEL}    Second%20Keyword    secoNd kEywoRD

 Linking to keywords in importing and keywords
     ${MODEL['inits'][0]}       Keyword           keyword
-    ${MODEL['keywords'][0]}    Second Keyword    Second Keyword
+    ${MODEL['keywords'][1]}    Second%20Keyword    Second Keyword

 Non-matching text in backticks gets formatting
     [Template]    Doc Should Contain Name
     ${MODEL}    backticks
-    ${MODEL['keywords'][1]}    arg
-    ${MODEL['keywords'][1]}    no link
+    ${MODEL['keywords'][2]}    arg
+    ${MODEL['keywords'][2]}    no link

 Linking to first level headers in introduction
     [Template]    NONE
- Doc Should Contain Link ${MODEL} Linking to headers linking to headers - Doc Should Contain Link ${MODEL} First = Level = first = level = + Doc Should Contain Link ${MODEL} Linking%20to%20headers linking to headers + Doc Should Contain Link ${MODEL} First%20%3D%20Level%20%3D first = level = Doc Should Contain ${MODEL} <h2 id="Linking to headers">Linking to headers</h2> Doc Should Contain ${MODEL} <h2 id="First = Level =">First = Level =</h2>

 Linking to first level headers in importing and keywords
     ${MODEL['inits'][0]}       Formatting            formatting
-    ${MODEL['keywords'][1]}    Linking to headers    linking to headers
+    ${MODEL['keywords'][2]}    Linking%20to%20headers    linking to headers

 Linking to second and third level headers
     [Template]    NONE
- Doc Should Contain Link ${MODEL} Second level Second level - Doc Should Contain Link ${MODEL} Third level third level - Doc Should Contain Link ${MODEL['keywords'][1]} Second level Second LEVEL + Doc Should Contain Link ${MODEL} Second%20level Second level + Doc Should Contain Link ${MODEL} Third%20level third level + Doc Should Contain Link ${MODEL['keywords'][2]} Second%20level Second LEVEL Doc Should Contain ${MODEL} <h3 id="Second level">Second level</h3>
     Doc Should Contain    ${MODEL}    <h4 id="Third level">Third level</h4>

 Only headers in introduction are linkable
     [Template]    NONE
-    Doc Should Contain Name    ${MODEL['keywords'][1]}    not linkable
-    Doc Should Contain    ${MODEL['keywords'][1]}    <h2>Not linkable</h2>
+    Doc Should Contain Name    ${MODEL['keywords'][2]}    not linkable
+    Doc Should Contain    ${MODEL['keywords'][2]}    <h2>Not linkable</h2>
+
+Special characters are percent encoded
+    ${MODEL['keywords'][0]}
+    ...    Percent%20encoding%3A%20!%22%23%25%2F()%3D%3F%7C%2B-_.!~*'()
+    ...    Percent encoding: !"#%/()=?|+-_.!~*'()
+
+HTML entities are escaped also in name
+    ${MODEL['keywords'][0]}
+    ...    HTML%20entities%3A%20%26%3C%3E    HTML entities: &amp;&lt;&gt;

+Non-ASCII is encoded
+    ${MODEL['keywords'][0]}
+    ...   Non-ASCII%3A%20%C3%A4%E2%98%83    Non-ASCII: ä\u2603

 *** Keywords ***

@@ -70,4 +82,3 @@
 Doc Should Contain
     [Arguments]    ${object}    ${text}
     Doc Should Contain In HTML    ${object}    ${text}
-
=======================================
--- /atest/testdata/libdoc/InternalLinking.py   Mon Jun 10 02:25:23 2013 UTC
+++ /atest/testdata/libdoc/InternalLinking.py   Tue Apr 22 10:32:06 2014 UTC
@@ -1,5 +1,5 @@
 class InternalLinking:
-    """Library for testing libdoc's internal linking.
+    u"""Library for testing libdoc's internal linking.

     = Linking to sections =

@@ -33,6 +33,14 @@

     === Third level ===

+    = Escaping =
+
+    == Percent encoding: !"#%/()=?|+-_.!~*'() ==
+
+    == HTML entities: &<> ==
+
+    == Non-ASCII: \xe4\u2603 ==
+
     = Formatting =

     Non-matching `backticks` just get special formatting.
@@ -51,3 +59,10 @@

We are `linking to headers` and `shortcuts` but not to `not linkable`.
         """
+
+    def escaping(self):
+        u"""Escaped links:
+        - `Percent encoding: !"#%/()=?|+-_.!~*'()`
+        - `HTML entities: &<>`
+        - `Non-ASCII: \xe4\u2603`
+        """
=======================================
--- /src/robot/htmldata/libdoc/libdoc.html      Thu Feb 14 20:41:38 2013 UTC
+++ /src/robot/htmldata/libdoc/libdoc.html      Tue Apr 22 10:32:06 2014 UTC
@@ -89,7 +89,7 @@
     <h2 id="Shortcuts">Shortcuts</h2>
     <div class='shortcuts'>
         {{each keywords}}
- <a href="#${$value.name}" title="${$value.shortdoc}">${$value.name}</a> + <a href="#${encodeURIComponent($value.name)}" title="${$value.shortdoc}">${$value.name}</a>
             {{if $index < keywords.length-1}} &middot; {{/if}}
         {{/each}}
     </div>
=======================================
--- /src/robot/libdocpkg/htmlwriter.py  Thu Jan 23 14:00:53 2014 UTC
+++ /src/robot/libdocpkg/htmlwriter.py  Tue Apr 22 10:32:06 2014 UTC
@@ -13,6 +13,7 @@
 #  limitations under the License.

 import re
+import urllib

 from robot.errors import DataError
 from robot.htmldata import HtmlFileWriter, ModelWriter, JsonWriter, LIBDOC
@@ -82,20 +83,20 @@
robot_format=doc_format == 'ROBOT')

     def _get_targets(self, keywords, introduction, robot_format):
-        targets = NormalizedDict({
+        targets = {
             'introduction': 'Introduction',
             'library introduction': 'Introduction',
             'importing': 'Importing',
             'library importing': 'Importing',
             'shortcuts': 'Shortcuts',
             'keywords': 'Keywords'
-        })
+        }
         for kw in keywords:
             targets[kw.name] = kw.name
         if robot_format:
             for header in self._yield_header_targets(introduction):
                 targets[header] = header
-        return targets
+        return self._escape_and_encode_targets(targets)

     def _yield_header_targets(self, introduction):
         headers = HeaderFormatter()
@@ -104,6 +105,14 @@
             if match:
                 yield match.group(2)

+    def _escape_and_encode_targets(self, targets):
+ return NormalizedDict((html_escape(key), self._encode_uri_component(value))
+                              for key, value in targets.iteritems())
+
+    def _encode_uri_component(self, value):
+        # Emulates encodeURIComponent javascript function
+        return urllib.quote(value.encode('UTF-8'), safe="-_.!~*'()")
+
     def html(self, doc, intro=False):
         doc = self._doc_to_html(doc)
         if intro:

--

--- You received this message because you are subscribed to the Google Groups "robotframework-commit" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to robotframework-commit+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to