~launchpad-pqm/launchpad/devel

14291.1.1 by Jeroen Vermeulen
Some lint.
1
Displaying Paragraphs of Text with ZPT
2
======================================
2360 by Canonical.com Patch Queue Manager
[r=BjornT] implement MaloneSearchResults (currently exposed only on
3
2903.1.139 by Matthew Paul Thomas
Fixes most occurrences of wiki.launchpad.canonical.com in the Launchpad code.
4
To display paragraphs of text in HTML, use fmt:text-to-html. For details,
5
see <https://launchpad.canonical.com/DisplayingParagraphsOfText>.
2360 by Canonical.com Patch Queue Manager
[r=BjornT] implement MaloneSearchResults (currently exposed only on
6
5261.1.1 by Christian Robottom Reis
First cut of fix for bug #126371, Reference to FAQ should be automatically linked in comments. Do just that.
7
14291.1.1 by Jeroen Vermeulen
Some lint.
8
Basics
9
------
5261.1.1 by Christian Robottom Reis
First cut of fix for bug #126371, Reference to FAQ should be automatically linked in comments. Do just that.
10
13269.2.17 by Jonathan Lange
Get rid of the canonical.launchpad.ftests alias for test_tales.
11
    >>> from lp.testing import test_tales
2360 by Canonical.com Patch Queue Manager
[r=BjornT] implement MaloneSearchResults (currently exposed only on
12
13
    >>> text = ('This is a paragraph.\n'
14
    ...         '\n'
15
    ...         'This is another paragraph.')
16
    >>> test_tales('foo/fmt:text-to-html', foo=text)
17
    '<p>This is a paragraph.</p>\n<p>This is another paragraph.</p>'
18
19
    >>> text = ('This is a line.\n'
20
    ...         'This is another line.')
21
    >>> test_tales('foo/fmt:text-to-html', foo=text)
2425.1.22 by James Henstridge
simplify fmt:text_to_html code
22
    '<p>This is a line.<br />\nThis is another line.</p>'
2360 by Canonical.com Patch Queue Manager
[r=BjornT] implement MaloneSearchResults (currently exposed only on
23
24
    >>> text = (
25
    ...     'This is a paragraph that has been hard-wrapped by an e-mail'
26
    ...     ' application.\n'
3233.3.1 by Matthew Paul Thomas
fix test, then fix code
27
    ...     'We used to handle this specially, but we no longer do because it'
28
    ...     ' was disturbing\n'
29
    ...     'the display of backtraces. Expected results:\n'
30
    ...     '* joy\n'
31
    ...     '* elation'
2360 by Canonical.com Patch Queue Manager
[r=BjornT] implement MaloneSearchResults (currently exposed only on
32
    ...     )
33
    >>> print test_tales('foo/fmt:text-to-html', foo=text)
14291.1.1 by Jeroen Vermeulen
Some lint.
34
    <p>This is a paragraph that has been hard-wrapped by an e-mail
35
    application.<br />
36
    We used to handle this specially, but we no longer do because it was
37
    disturbing<br />
3233.3.1 by Matthew Paul Thomas
fix test, then fix code
38
    the display of backtraces. Expected results:<br />
39
    * joy<br />
40
    * elation</p>
2360 by Canonical.com Patch Queue Manager
[r=BjornT] implement MaloneSearchResults (currently exposed only on
41
42
    >>> text = (
3233.3.1 by Matthew Paul Thomas
fix test, then fix code
43
    ...     " 1. Here's an example\n"
44
    ...     " 2. where a list is followed by a paragraph.\n"
45
    ...     "   Leading spaces in a line or paragraph are presented, which "
46
    ...     "means converting them to &nbsp;. Trailing spaces are passed "
14291.1.1 by Jeroen Vermeulen
Some lint.
47
    ...     "through as-is, which means browsers will ignore them, but "
48
    ...     "that's fine, they're not important anyway.\n"
2360 by Canonical.com Patch Queue Manager
[r=BjornT] implement MaloneSearchResults (currently exposed only on
49
    ...     )
50
    >>> print test_tales('foo/fmt:text-to-html', foo=text)
3233.3.1 by Matthew Paul Thomas
fix test, then fix code
51
    <p>&nbsp;1. Here's an example<br />
2425.1.22 by James Henstridge
simplify fmt:text_to_html code
52
    &nbsp;2. where a list is followed by a paragraph.<br />
3233.3.1 by Matthew Paul Thomas
fix test, then fix code
53
    &nbsp;&nbsp;&nbsp;Leading spaces in a line or paragraph are presented, which means converting them to &amp;nbsp;. Trailing spaces are passed through as-is, which means browsers will ignore them, but that's fine, they're not important anyway.</p>
2360 by Canonical.com Patch Queue Manager
[r=BjornT] implement MaloneSearchResults (currently exposed only on
54
55
    >>> text = (
56
    ...     'This is a little paragraph all by itself. How cute!'
57
    ...     )
58
    >>> test_tales('foo/fmt:text-to-html', foo=text)
59
    '<p>This is a little paragraph all by itself. How cute!</p>'
60
61
    >>> text = (
62
    ...     'Here are two paragraphs with lots of whitespace between them.\n'
63
    ...     '\n'
64
    ...     '\n'
65
    ...     '\n'
66
    ...     '\n'
67
    ...     'But they\'re still just two paragraphs.')
68
    >>> print test_tales('foo/fmt:text-to-html', foo=text)
69
    <p>Here are two paragraphs with lots of whitespace between them.</p>
70
    <p>But they're still just two paragraphs.</p>
71
2425.1.23 by James Henstridge
add an example with a code sample
72
If a line begins with whitespace, it will not be merged with the
3233.3.1 by Matthew Paul Thomas
fix test, then fix code
73
previous line.  This aids in the display of code samples:
2425.1.23 by James Henstridge
add an example with a code sample
74
75
    >>> text = (
3233.3.1 by Matthew Paul Thomas
fix test, then fix code
76
    ...     'This is a code sample written in Python.\n'
2425.1.23 by James Henstridge
add an example with a code sample
77
    ...     '    def messageCount(self):\n'
78
    ...     '        """See IRosettaStats."""\n'
79
    ...     '        return self.potemplate.messageCount()\n'
80
    ...     '\n'
81
    ...     '    def currentCount(self, language=None):\n'
82
    ...     '        """See IRosettaStats."""\n'
83
    ...     '        return self.currentCount\n')
84
    >>> print test_tales('foo/fmt:text-to-html', foo=text)
3233.3.1 by Matthew Paul Thomas
fix test, then fix code
85
    <p>This is a code sample written in Python.<br />
2425.1.23 by James Henstridge
add an example with a code sample
86
    &nbsp;&nbsp;&nbsp;&nbsp;def messageCount(self):<br />
87
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"""See IRosettaStats."""<br />
3691.199.3 by James Henstridge
add <wbr>'s to displaying-paragraphs-of-text.txt
88
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return self.potemplate<wbr></wbr>.messageCount(<wbr></wbr>)</p>
2425.1.23 by James Henstridge
add an example with a code sample
89
    <p>&nbsp;&nbsp;&nbsp;&nbsp;def currentCount(self, language=None):<br />
90
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"""See IRosettaStats."""<br />
91
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return self.currentCount</p>
92
5261.1.1 by Christian Robottom Reis
First cut of fix for bug #126371, Reference to FAQ should be automatically linked in comments. Do just that.
93
Testing a bunch of URL links.
94
95
    >>> text = (
96
    ...     'https://launchpad.net/ is the new Launchpad site\n'
97
    ...     'http://example.com/something?foo=bar&hum=baz\n'
98
    ...     'You can check the PPC md5sums at '
99
    ...     'ftp://ftp.ubuntu.com/ubuntu/dists/breezy/main/installer-powerpc'
100
    ...     '/current/images/MD5SUMS\n'
101
    ...     'irc://irc.freenode.net/#launchpad\n'
102
    ...     '\n'
103
    ...     'I have a Jabber account (jabber:foo@jabber.example.com)\n'
104
    ...     'Foo Bar <mailto:foo.bar@example.net>')
105
    >>> print test_tales('foo/fmt:text-to-html', foo=text)
106
    <p><a rel="nofollow" href="https://launchpad.net/">https:/<wbr></wbr>/launchpad.<wbr></wbr>net/</a> is the new Launchpad site<br />
107
    <a rel="nofollow" href="http://example.com/something?foo=bar&amp;hum=baz">http://<wbr></wbr>example.<wbr></wbr>com/something?<wbr></wbr>foo=bar&amp;<wbr></wbr>hum=baz</a><br />
108
    You can check the PPC md5sums at <a rel="nofollow" href="ftp://ftp.ubuntu.com/ubuntu/dists/breezy/main/installer-powerpc/current/images/MD5SUMS">ftp://ftp.<wbr></wbr>ubuntu.<wbr></wbr>com/ubuntu/<wbr></wbr>dists/breezy/<wbr></wbr>main/installer-<wbr></wbr>powerpc/<wbr></wbr>current/<wbr></wbr>images/<wbr></wbr>MD5SUMS</a><br />
109
    <a rel="nofollow" href="irc://irc.freenode.net/#launchpad">irc://irc.<wbr></wbr>freenode.<wbr></wbr>net/#launchpad</a></p>
110
    <p>I have a Jabber account (<a rel="nofollow" href="jabber:foo@jabber.example.com">jabber:<wbr></wbr>foo@jabber.<wbr></wbr>example.<wbr></wbr>com</a>)<br />
111
    Foo Bar &lt;<a rel="nofollow" href="mailto:foo.bar@example.net">mailto:<wbr></wbr>foo.bar@<wbr></wbr>example.<wbr></wbr>net</a>&gt;</p>
112
113
14291.1.1 by Jeroen Vermeulen
Some lint.
114
URL linkification
115
-----------------
5261.1.1 by Christian Robottom Reis
First cut of fix for bug #126371, Reference to FAQ should be automatically linked in comments. Do just that.
116
2360 by Canonical.com Patch Queue Manager
[r=BjornT] implement MaloneSearchResults (currently exposed only on
117
fmt:text-to-html knows how to linkify URLs:
118
119
    >>> text = (
120
    ...     'http://localhost:8086/bar/baz/foo.html\n'
1716.2.25 by Christian Reis
Fix and test for bug 5423: URL auto-linkification doesn't recognize SFTP URLs
121
    ...     'ftp://localhost:8086/bar/baz/foo.bar.html\n'
122
    ...     'sftp://localhost:8086/bar/baz/foo.bar.html.\n'
2466 by Canonical.com Patch Queue Manager
[trivial] Tests and a fix for URLs trailed with semi-colons; a bit trickier than one might expect.
123
    ...     'http://localhost:8086/bar/baz/foo.bar.html;\n'
1716.2.25 by Christian Reis
Fix and test for bug 5423: URL auto-linkification doesn't recognize SFTP URLs
124
    ...     'news://localhost:8086/bar/baz/foo.bar.html:\n'
2360 by Canonical.com Patch Queue Manager
[r=BjornT] implement MaloneSearchResults (currently exposed only on
125
    ...     'http://localhost:8086/bar/baz/foo.bar.html?\n'
126
    ...     'http://localhost:8086/bar/baz/foo.bar.html,\n'
127
    ...     '<http://localhost:8086/bar/baz/foo.bar.html>\n'
128
    ...     '<http://localhost:8086/bar/baz/foo.bar.html>,\n'
129
    ...     '<http://localhost:8086/bar/baz/foo.bar.html>.\n'
2466 by Canonical.com Patch Queue Manager
[trivial] Tests and a fix for URLs trailed with semi-colons; a bit trickier than one might expect.
130
    ...     '<http://localhost:8086/bar/baz/foo.bar.html>;\n'
1716.1.168 by Christian Reis
One more linkify fix: allow trailing colons
131
    ...     '<http://localhost:8086/bar/baz/foo.bar.html>:\n'
2360 by Canonical.com Patch Queue Manager
[r=BjornT] implement MaloneSearchResults (currently exposed only on
132
    ...     '<http://localhost:8086/bar/baz/foo.bar.html>?\n'
133
    ...     '(http://localhost:8086/bar/baz/foo.bar.html)\n'
134
    ...     '(http://localhost:8086/bar/baz/foo.bar.html),\n'
135
    ...     '(http://localhost:8086/bar/baz/foo.bar.html).\n'
2466 by Canonical.com Patch Queue Manager
[trivial] Tests and a fix for URLs trailed with semi-colons; a bit trickier than one might expect.
136
    ...     '(http://localhost:8086/bar/baz/foo.bar.html);\n'
1716.1.168 by Christian Reis
One more linkify fix: allow trailing colons
137
    ...     '(http://localhost:8086/bar/baz/foo.bar.html):\n'
2360 by Canonical.com Patch Queue Manager
[r=BjornT] implement MaloneSearchResults (currently exposed only on
138
    ...     'http://localhost/bar/baz/foo.bar.html?a=b&b=a\n'
139
    ...     'http://localhost/bar/baz/foo.bar.html?a=b&b=a.\n'
2466 by Canonical.com Patch Queue Manager
[trivial] Tests and a fix for URLs trailed with semi-colons; a bit trickier than one might expect.
140
    ...     'http://localhost/bar/baz/foo.bar.html?a=b&b=a,\n'
1716.1.168 by Christian Reis
One more linkify fix: allow trailing colons
141
    ...     'http://localhost/bar/baz/foo.bar.html?a=b&b=a;\n'
3504.1.50 by kiko
Fix for Bug #41410:
142
    ...     'http://localhost/bar/baz/foo.bar.html?a=b&b=a:\n'
14291.1.1 by Jeroen Vermeulen
Some lint.
143
    ...     'http://localhost/bar/baz/foo.bar.html?'
144
    ...         'a=b&b=a:b;c@d_e%f~g#h,j!k-l+m$n*o\'p\n'
3485.3.13 by James Henstridge
adjust URL matching rules to follow RFC 3986 more closely, hopefully fixing bug 40255
145
    ...     'http://www.searchtools.com/test/urls/(parens).html\n'
146
    ...     'http://www.searchtools.com/test/urls/-dash.html\n'
147
    ...     'http://www.searchtools.com/test/urls/_underscore.html\n'
148
    ...     'http://www.searchtools.com/test/urls/period.x.html\n'
149
    ...     'http://www.searchtools.com/test/urls/!exclamation.html\n'
150
    ...     'http://www.searchtools.com/test/urls/~tilde.html\n'
151
    ...     'http://www.searchtools.com/test/urls/*asterisk.html\n'
152
    ...     'irc://irc.freenode.net/launchpad\n'
153
    ...     'irc://irc.freenode.net/%23launchpad,isserver\n'
154
    ...     'mailto:noreply@launchpad.net\n'
155
    ...     'jabber:noreply@launchpad.net\n'
3691.228.1 by James Henstridge
unescape the URL before stripping off trailer characters
156
    ...     'http://localhost/foo?xxx&\n'
4200.3.2 by Gavin Panella
Match URLs in bug comments consistently with earlier changes
157
    ...     'http://localhost?testing=[square-brackets-in-query]\n'
3504.1.50 by kiko
Fix for Bug #41410:
158
    ... )
159
2360 by Canonical.com Patch Queue Manager
[r=BjornT] implement MaloneSearchResults (currently exposed only on
160
    >>> print test_tales('foo/fmt:text-to-html', foo=text)
3691.199.3 by James Henstridge
add <wbr>'s to displaying-paragraphs-of-text.txt
161
    <p><a rel="nofollow" href="http://localhost:8086/bar/baz/foo.html">http://<wbr></wbr>localhost:<wbr></wbr>8086/bar/<wbr></wbr>baz/foo.<wbr></wbr>html</a><br />
162
    <a rel="nofollow" href="ftp://localhost:8086/bar/baz/foo.bar.html">ftp://localhost<wbr></wbr>:8086/bar/<wbr></wbr>baz/foo.<wbr></wbr>bar.html</a><br />
163
    <a rel="nofollow" href="sftp://localhost:8086/bar/baz/foo.bar.html">sftp://<wbr></wbr>localhost:<wbr></wbr>8086/bar/<wbr></wbr>baz/foo.<wbr></wbr>bar.html</a>.<br />
164
    <a rel="nofollow" href="http://localhost:8086/bar/baz/foo.bar.html">http://<wbr></wbr>localhost:<wbr></wbr>8086/bar/<wbr></wbr>baz/foo.<wbr></wbr>bar.html</a>;<br />
165
    <a rel="nofollow" href="news://localhost:8086/bar/baz/foo.bar.html">news://<wbr></wbr>localhost:<wbr></wbr>8086/bar/<wbr></wbr>baz/foo.<wbr></wbr>bar.html</a>:<br />
166
    <a rel="nofollow" href="http://localhost:8086/bar/baz/foo.bar.html">http://<wbr></wbr>localhost:<wbr></wbr>8086/bar/<wbr></wbr>baz/foo.<wbr></wbr>bar.html</a>?<br />
167
    <a rel="nofollow" href="http://localhost:8086/bar/baz/foo.bar.html">http://<wbr></wbr>localhost:<wbr></wbr>8086/bar/<wbr></wbr>baz/foo.<wbr></wbr>bar.html</a>,<br />
168
    &lt;<a rel="nofollow" href="http://localhost:8086/bar/baz/foo.bar.html">http://<wbr></wbr>localhost:<wbr></wbr>8086/bar/<wbr></wbr>baz/foo.<wbr></wbr>bar.html</a>&gt;<br />
169
    &lt;<a rel="nofollow" href="http://localhost:8086/bar/baz/foo.bar.html">http://<wbr></wbr>localhost:<wbr></wbr>8086/bar/<wbr></wbr>baz/foo.<wbr></wbr>bar.html</a>&gt;,<br />
170
    &lt;<a rel="nofollow" href="http://localhost:8086/bar/baz/foo.bar.html">http://<wbr></wbr>localhost:<wbr></wbr>8086/bar/<wbr></wbr>baz/foo.<wbr></wbr>bar.html</a>&gt;.<br />
171
    &lt;<a rel="nofollow" href="http://localhost:8086/bar/baz/foo.bar.html">http://<wbr></wbr>localhost:<wbr></wbr>8086/bar/<wbr></wbr>baz/foo.<wbr></wbr>bar.html</a>&gt;;<br />
172
    &lt;<a rel="nofollow" href="http://localhost:8086/bar/baz/foo.bar.html">http://<wbr></wbr>localhost:<wbr></wbr>8086/bar/<wbr></wbr>baz/foo.<wbr></wbr>bar.html</a>&gt;:<br />
173
    &lt;<a rel="nofollow" href="http://localhost:8086/bar/baz/foo.bar.html">http://<wbr></wbr>localhost:<wbr></wbr>8086/bar/<wbr></wbr>baz/foo.<wbr></wbr>bar.html</a>&gt;?<br />
174
    (<a rel="nofollow" href="http://localhost:8086/bar/baz/foo.bar.html">http://<wbr></wbr>localhost:<wbr></wbr>8086/bar/<wbr></wbr>baz/foo.<wbr></wbr>bar.html</a>)<br />
175
    (<a rel="nofollow" href="http://localhost:8086/bar/baz/foo.bar.html">http://<wbr></wbr>localhost:<wbr></wbr>8086/bar/<wbr></wbr>baz/foo.<wbr></wbr>bar.html</a>),<br />
176
    (<a rel="nofollow" href="http://localhost:8086/bar/baz/foo.bar.html">http://<wbr></wbr>localhost:<wbr></wbr>8086/bar/<wbr></wbr>baz/foo.<wbr></wbr>bar.html</a>).<br />
177
    (<a rel="nofollow" href="http://localhost:8086/bar/baz/foo.bar.html">http://<wbr></wbr>localhost:<wbr></wbr>8086/bar/<wbr></wbr>baz/foo.<wbr></wbr>bar.html</a>);<br />
178
    (<a rel="nofollow" href="http://localhost:8086/bar/baz/foo.bar.html">http://<wbr></wbr>localhost:<wbr></wbr>8086/bar/<wbr></wbr>baz/foo.<wbr></wbr>bar.html</a>):<br />
179
    <a rel="nofollow" href="http://localhost/bar/baz/foo.bar.html?a=b&amp;b=a">http://<wbr></wbr>localhost/<wbr></wbr>bar/baz/<wbr></wbr>foo.bar.<wbr></wbr>html?a=<wbr></wbr>b&amp;b=a</a><br />
180
    <a rel="nofollow" href="http://localhost/bar/baz/foo.bar.html?a=b&amp;b=a">http://<wbr></wbr>localhost/<wbr></wbr>bar/baz/<wbr></wbr>foo.bar.<wbr></wbr>html?a=<wbr></wbr>b&amp;b=a</a>.<br />
181
    <a rel="nofollow" href="http://localhost/bar/baz/foo.bar.html?a=b&amp;b=a">http://<wbr></wbr>localhost/<wbr></wbr>bar/baz/<wbr></wbr>foo.bar.<wbr></wbr>html?a=<wbr></wbr>b&amp;b=a</a>,<br />
182
    <a rel="nofollow" href="http://localhost/bar/baz/foo.bar.html?a=b&amp;b=a">http://<wbr></wbr>localhost/<wbr></wbr>bar/baz/<wbr></wbr>foo.bar.<wbr></wbr>html?a=<wbr></wbr>b&amp;b=a</a>;<br />
183
    <a rel="nofollow" href="http://localhost/bar/baz/foo.bar.html?a=b&amp;b=a">http://<wbr></wbr>localhost/<wbr></wbr>bar/baz/<wbr></wbr>foo.bar.<wbr></wbr>html?a=<wbr></wbr>b&amp;b=a</a>:<br />
184
    <a rel="nofollow" href="http://localhost/bar/baz/foo.bar.html?a=b&amp;b=a:b;c@d_e%f~g#h,j!k-l+m$n*o'p">http://<wbr></wbr>localhost/<wbr></wbr>bar/baz/<wbr></wbr>foo.bar.<wbr></wbr>html?a=<wbr></wbr>b&amp;b=a:b;<wbr></wbr>c@d_e%f~<wbr></wbr>g#h,j!k-<wbr></wbr>l+m$n*o'<wbr></wbr>p</a><br />
185
    <a rel="nofollow" href="http://www.searchtools.com/test/urls/(parens).html">http://<wbr></wbr>www.searchtools<wbr></wbr>.com/test/<wbr></wbr>urls/(parens)<wbr></wbr>.html</a><br />
186
    <a rel="nofollow" href="http://www.searchtools.com/test/urls/-dash.html">http://<wbr></wbr>www.searchtools<wbr></wbr>.com/test/<wbr></wbr>urls/-dash.<wbr></wbr>html</a><br />
187
    <a rel="nofollow" href="http://www.searchtools.com/test/urls/_underscore.html">http://<wbr></wbr>www.searchtools<wbr></wbr>.com/test/<wbr></wbr>urls/_underscor<wbr></wbr>e.html</a><br />
188
    <a rel="nofollow" href="http://www.searchtools.com/test/urls/period.x.html">http://<wbr></wbr>www.searchtools<wbr></wbr>.com/test/<wbr></wbr>urls/period.<wbr></wbr>x.html</a><br />
189
    <a rel="nofollow" href="http://www.searchtools.com/test/urls/!exclamation.html">http://<wbr></wbr>www.searchtools<wbr></wbr>.com/test/<wbr></wbr>urls/!exclamati<wbr></wbr>on.html</a><br />
190
    <a rel="nofollow" href="http://www.searchtools.com/test/urls/~tilde.html">http://<wbr></wbr>www.searchtools<wbr></wbr>.com/test/<wbr></wbr>urls/~tilde.<wbr></wbr>html</a><br />
191
    <a rel="nofollow" href="http://www.searchtools.com/test/urls/*asterisk.html">http://<wbr></wbr>www.searchtools<wbr></wbr>.com/test/<wbr></wbr>urls/*asterisk.<wbr></wbr>html</a><br />
192
    <a rel="nofollow" href="irc://irc.freenode.net/launchpad">irc://irc.<wbr></wbr>freenode.<wbr></wbr>net/launchpad</a><br />
193
    <a rel="nofollow" href="irc://irc.freenode.net/%23launchpad,isserver">irc://irc.<wbr></wbr>freenode.<wbr></wbr>net/%23launchpa<wbr></wbr>d,isserver</a><br />
194
    <a rel="nofollow" href="mailto:noreply@launchpad.net">mailto:<wbr></wbr>noreply@<wbr></wbr>launchpad.<wbr></wbr>net</a><br />
3691.228.1 by James Henstridge
unescape the URL before stripping off trailer characters
195
    <a rel="nofollow" href="jabber:noreply@launchpad.net">jabber:<wbr></wbr>noreply@<wbr></wbr>launchpad.<wbr></wbr>net</a><br />
4200.3.2 by Gavin Panella
Match URLs in bug comments consistently with earlier changes
196
    <a rel="nofollow" href="http://localhost/foo?xxx&amp;">http://<wbr></wbr>localhost/<wbr></wbr>foo?xxx&amp;</a><br />
197
    <a rel="nofollow" href="http://localhost?testing=[square-brackets-in-query]">http://<wbr></wbr>localhost?<wbr></wbr>testing=<wbr></wbr>[square-<wbr></wbr>brackets-<wbr></wbr>in-query]</a></p>
3485.3.13 by James Henstridge
adjust URL matching rules to follow RFC 3986 more closely, hopefully fixing bug 40255
198
199
200
The fmt:text-to-html formatter leaves a number of non-URIs unlinked:
201
202
    >>> text = (
203
    ...     'nothttp://launchpad.net/\n'
204
    ...     'http::No-cache=True\n')
205
    >>> print test_tales('foo/fmt:text-to-html', foo=text)
3691.199.3 by James Henstridge
add <wbr>'s to displaying-paragraphs-of-text.txt
206
    <p>nothttp:<wbr></wbr>//launchpad.<wbr></wbr>net/<br />
3485.3.13 by James Henstridge
adjust URL matching rules to follow RFC 3986 more closely, hopefully fixing bug 40255
207
    http::No-cache=True</p>
208
2360 by Canonical.com Patch Queue Manager
[r=BjornT] implement MaloneSearchResults (currently exposed only on
209
14291.1.1 by Jeroen Vermeulen
Some lint.
210
Bug references
211
--------------
5261.1.1 by Christian Robottom Reis
First cut of fix for bug #126371, Reference to FAQ should be automatically linked in comments. Do just that.
212
2360 by Canonical.com Patch Queue Manager
[r=BjornT] implement MaloneSearchResults (currently exposed only on
213
fmt:text-to-html is also smart enough to convert bug references into
214
links:
215
216
    >>> text = (
217
    ...     'bug 123\n'
218
    ...     'bug    123\n'
219
    ...     'bug #123\n'
220
    ...     'bug number 123\n'
221
    ...     'bug number. 123\n'
222
    ...     'bug num 123\n'
223
    ...     'bug num. 123\n'
224
    ...     'bug no 123\n'
3691.62.3 by kiko
Linkify the text 'bug report X', since it occurs in some locations.
225
    ...     'bug report 123\n'
2360 by Canonical.com Patch Queue Manager
[r=BjornT] implement MaloneSearchResults (currently exposed only on
226
    ...     'bug no. 123\n'
3485.3.7 by James Henstridge
Linkify bug references containing a new line (fixes bug #53977)
227
    ...     'bug#123\n'
8071.2.1 by Gavin Panella
Make bug=123, bug-123, faq=123, and faq-123 work with the linkifier.
228
    ...     'bug-123\n'
229
    ...     'bug-report-123\n'
230
    ...     'bug=123\n'
3485.3.7 by James Henstridge
Linkify bug references containing a new line (fixes bug #53977)
231
    ...     'bug\n'
3485.3.12 by James Henstridge
fix for bug 28620 (don't linkify words ending in 'bug'), and some cleanups to displaying-paragraphs-of-text.txt
232
    ...     '#123\n'
233
    ...     'debug #52\n')
2360 by Canonical.com Patch Queue Manager
[r=BjornT] implement MaloneSearchResults (currently exposed only on
234
    >>> print test_tales('foo/fmt:text-to-html', foo=text)
13570.1.13 by Nigel Babu
merged devel. fixed breakage
235
    <p><a href="/bugs/123" class="bug-link">bug 123</a><br />
236
    <a href="/bugs/123" class="bug-link">bug    123</a><br />
237
    <a href="/bugs/123" class="bug-link">bug #123</a><br />
238
    <a href="/bugs/123" class="bug-link">bug number 123</a><br />
12095.1.7 by j.c.sackett
Fixed a test.
239
    bug number. 123<br />
13570.1.13 by Nigel Babu
merged devel. fixed breakage
240
    <a href="/bugs/123" class="bug-link">bug num 123</a><br />
241
    <a href="/bugs/123" class="bug-link">bug num. 123</a><br />
242
    <a href="/bugs/123" class="bug-link">bug no 123</a><br />
243
    <a href="/bugs/123" class="bug-link">bug report 123</a><br />
244
    <a href="/bugs/123" class="bug-link">bug no. 123</a><br />
12095.1.7 by j.c.sackett
Fixed a test.
245
    bug#123<br />
13570.1.13 by Nigel Babu
merged devel. fixed breakage
246
    <a href="/bugs/123" class="bug-link">bug-123</a><br />
247
    <a href="/bugs/123" class="bug-link">bug-report-123</a><br />
248
    <a href="/bugs/123" class="bug-link">bug=123</a><br />
249
    <a href="/bugs/123" class="bug-link">bug<br /> #123</a><br />
3485.3.12 by James Henstridge
fix for bug 28620 (don't linkify words ending in 'bug'), and some cleanups to displaying-paragraphs-of-text.txt
250
    debug #52</p>
2360 by Canonical.com Patch Queue Manager
[r=BjornT] implement MaloneSearchResults (currently exposed only on
251
252
    >>> text = (
253
    ...     'bug 123\n'
254
    ...     'bug 123\n')
255
    >>> print test_tales('foo/fmt:text-to-html', foo=text)
13570.1.13 by Nigel Babu
merged devel. fixed breakage
256
    <p><a href="/bugs/123" class="bug-link">bug 123</a><br />
257
    <a href="/bugs/123" class="bug-link">bug 123</a></p>
2360 by Canonical.com Patch Queue Manager
[r=BjornT] implement MaloneSearchResults (currently exposed only on
258
259
    >>> text = (
260
    ...     'bug 1234\n'
261
    ...     'bug 123\n')
262
    >>> print test_tales('foo/fmt:text-to-html', foo=text)
13570.1.13 by Nigel Babu
merged devel. fixed breakage
263
    <p><a href="/bugs/1234" class="bug-link">bug 1234</a><br />
264
    <a href="/bugs/123" class="bug-link">bug 123</a></p>
2360 by Canonical.com Patch Queue Manager
[r=BjornT] implement MaloneSearchResults (currently exposed only on
265
266
    >>> text = 'bug 0123\n'
267
    >>> print test_tales('foo/fmt:text-to-html', foo=text)
13570.1.13 by Nigel Babu
merged devel. fixed breakage
268
    <p><a href="/bugs/123" class="bug-link">bug 0123</a></p>
2360 by Canonical.com Patch Queue Manager
[r=BjornT] implement MaloneSearchResults (currently exposed only on
269
9024.5.2 by James Westby, Jonathan Lange
Comments & docstrings.
270
271
We linkify bugs that are in the Ubuntu convention for referring to bugs in
272
Debian changelogs.
273
9024.5.1 by James Westby
Also link "LP: #12345" bug numbers as used in Ubuntu changelogs.
274
    >>> text = 'LP: #123.\n'
275
    >>> print test_tales('foo/fmt:text-to-html', foo=text)
13570.1.13 by Nigel Babu
merged devel. fixed breakage
276
    <p>LP: <a href="/bugs/123" class="bug-link">#123</a>.</p>
9024.5.1 by James Westby
Also link "LP: #12345" bug numbers as used in Ubuntu changelogs.
277
9024.5.3 by Jonathan Lange
Lower case tests.
278
Works with multiple bugs:
279
9024.5.1 by James Westby
Also link "LP: #12345" bug numbers as used in Ubuntu changelogs.
280
    >>> text = 'LP: #123, #2.\n'
281
    >>> print test_tales('foo/fmt:text-to-html', foo=text)
13570.1.13 by Nigel Babu
merged devel. fixed breakage
282
    <p>LP: <a href="/bugs/123" class="bug-link">#123</a>, <a href="/bugs/2" class="bug-link">#2</a>.</p>
9024.5.1 by James Westby
Also link "LP: #12345" bug numbers as used in Ubuntu changelogs.
283
9024.5.3 by Jonathan Lange
Lower case tests.
284
And with lower case 'lp' too:
285
286
    >>> text = 'lp: #123, #2.\n'
287
    >>> print test_tales('foo/fmt:text-to-html', foo=text)
13570.1.13 by Nigel Babu
merged devel. fixed breakage
288
    <p>lp: <a href="/bugs/123" class="bug-link">#123</a>, <a href="/bugs/2" class="bug-link">#2</a>.</p>
9024.5.3 by Jonathan Lange
Lower case tests.
289
290
Even line breaks cannot stop the power of bug linking:
291
9024.5.1 by James Westby
Also link "LP: #12345" bug numbers as used in Ubuntu changelogs.
292
    >>> text = 'LP:  #123,\n#2.\n'
293
    >>> print test_tales('foo/fmt:text-to-html', foo=text)
13570.1.13 by Nigel Babu
merged devel. fixed breakage
294
    <p>LP:  <a href="/bugs/123" class="bug-link">#123</a>,<br />
295
    <a href="/bugs/2" class="bug-link">#2</a>.</p>
9024.5.1 by James Westby
Also link "LP: #12345" bug numbers as used in Ubuntu changelogs.
296
2360 by Canonical.com Patch Queue Manager
[r=BjornT] implement MaloneSearchResults (currently exposed only on
297
To check a private bug, we need to log in and set a bug to be private.
298
299
    >>> from zope.component import getUtility
11692.6.2 by Curtis Hovey
Use deglober to fixing simple glob imports in doctests.
300
    >>> from lp.bugs.interfaces.bug import IBugSet
2360 by Canonical.com Patch Queue Manager
[r=BjornT] implement MaloneSearchResults (currently exposed only on
301
    >>> bugset = getUtility(IBugSet)
302
    >>> firefox_crashes = bugset.get(6)
4813.12.17 by Gavin Panella
Revert an experimental test change that shouldn't have been committed.
303
    >>> login("test@canonical.com")
4813.12.18 by Gavin Panella
Resolve two more test failures relating to new subscription handling in setPrivate.
304
    >>> current_user = getUtility(ILaunchBag).user
305
    >>> firefox_crashes.setPrivate(True, current_user)
4813.12.15 by Gavin Panella
Change assignments to bug.private to use bug.setPrivate(), pt. 1.
306
    True
2360 by Canonical.com Patch Queue Manager
[r=BjornT] implement MaloneSearchResults (currently exposed only on
307
4813.12.18 by Gavin Panella
Resolve two more test failures relating to new subscription handling in setPrivate.
308
Bug.setPrivate adds all indirect subscribers to the bug as direct
309
subscribers, but we want to see what the bug looks like if we're not a
310
subscriber.
311
7968.1.3 by Bjorn Tillenius
Make sure the extra argument is passed to unsubscribed().
312
    >>> firefox_crashes.unsubscribe(current_user, current_user)
4813.12.18 by Gavin Panella
Resolve two more test failures relating to new subscription handling in setPrivate.
313
10861.1.5 by Tim Penhey
Remove the titles from the doctests.
314
A private bug is still linked as no check is made on the actual bug.
2360 by Canonical.com Patch Queue Manager
[r=BjornT] implement MaloneSearchResults (currently exposed only on
315
316
    >>> text = 'bug 6\n'
317
    >>> print test_tales('foo/fmt:text-to-html', foo=text)
13570.1.13 by Nigel Babu
merged devel. fixed breakage
318
    <p><a href="/bugs/6" class="bug-link">bug 6</a></p>
2360 by Canonical.com Patch Queue Manager
[r=BjornT] implement MaloneSearchResults (currently exposed only on
319
5261.1.1 by Christian Robottom Reis
First cut of fix for bug #126371, Reference to FAQ should be automatically linked in comments. Do just that.
320
14291.1.1 by Jeroen Vermeulen
Some lint.
321
FAQ references
322
--------------
5261.1.1 by Christian Robottom Reis
First cut of fix for bug #126371, Reference to FAQ should be automatically linked in comments. Do just that.
323
324
FAQ references are global, and also linkified:
325
326
    >>> text = (
327
    ...     'faq 1\n'
328
    ...     'faq #2\n'
8071.2.1 by Gavin Panella
Make bug=123, bug-123, faq=123, and faq-123 work with the linkifier.
329
    ...     'faq-2\n'
330
    ...     'faq=2\n'
5261.1.1 by Christian Robottom Reis
First cut of fix for bug #126371, Reference to FAQ should be automatically linked in comments. Do just that.
331
    ...     'faq item 1\n'
332
    ...     'faq  number  2\n'
333
    ...     )
334
    >>> print test_tales('foo/fmt:text-to-html', foo=text)
5261.1.2 by Christian Robottom Reis
Drop the nofollow rel, which isn't relevant for OOPS and FAQs.
335
    <p><a href="http://answers.launchpad.dev/ubuntu/+faq/1">faq 1</a><br />
5261.1.3 by Christian Robottom Reis
unindent.
336
    <a href="http://answers.launchpad.dev/ubuntu/+faq/2">faq #2</a><br />
8071.2.1 by Gavin Panella
Make bug=123, bug-123, faq=123, and faq-123 work with the linkifier.
337
    <a href="http://answers.launchpad.dev/ubuntu/+faq/2">faq-2</a><br />
338
    <a href="http://answers.launchpad.dev/ubuntu/+faq/2">faq=2</a><br />
5261.1.3 by Christian Robottom Reis
unindent.
339
    <a href="http://answers.launchpad.dev/ubuntu/+faq/1">faq item 1</a><br />
14291.1.1 by Jeroen Vermeulen
Some lint.
340
    <a href="http://answers.launchpad.dev/ubuntu/+faq/2">faq number 2</a></p>
5261.1.1 by Christian Robottom Reis
First cut of fix for bug #126371, Reference to FAQ should be automatically linked in comments. Do just that.
341
342
Except, that is, when the FAQ doesn't exist:
343
344
    >>> text = (
345
    ...     'faq 999\n'
346
    ...     )
347
    >>> print test_tales('foo/fmt:text-to-html', foo=text)
348
    <p>faq 999</p>
349
350
14291.1.1 by Jeroen Vermeulen
Some lint.
351
Branch references
352
-----------------
8030.1.1 by Jonathan Lange
Highlight lp URLs in branches.
353
354
Branch references are linkified:
355
356
    >>> text = (
357
    ...     'lp:~foo/bar/baz\n'
8071.2.1 by Gavin Panella
Make bug=123, bug-123, faq=123, and faq-123 work with the linkifier.
358
    ...     'lp:~foo/bar/bug-123\n'
8030.1.1 by Jonathan Lange
Highlight lp URLs in branches.
359
    ...     'lp:~foo/+junk/baz\n'
360
    ...     'lp:~foo/ubuntu/jaunty/evolution/baz\n'
361
    ...     'lp:foo/bar\n'
362
    ...     'lp:foo\n'
8080.1.2 by Jonathan Lange
Don't include punctuation in lp URLs.
363
    ...     'lp:foo,\n'
364
    ...     'lp:foo/bar.\n'
8030.1.3 by Jonathan Lange
Support slashier URLs.
365
    ...     'lp:foo/bar/baz\n'
366
    ...     'lp:///foo\n'
367
    ...     'lp:/foo\n')
8030.1.1 by Jonathan Lange
Highlight lp URLs in branches.
368
    >>> print test_tales('foo/fmt:text-to-html', foo=text)
11644.2.17 by Ian Booth
Fix doc test
369
    <p><a href="/+branch/~foo/bar/baz" class="...">lp:~foo/bar/baz</a><br />
370
    <a href="/+branch/~foo/bar/bug-123" class="...">lp:~foo/bar/bug-123</a><br />
371
    <a href="/+branch/~foo/+junk/baz" class="...">lp:~foo/+junk/baz</a><br />
372
    <a href="/+branch/~foo/ubuntu/jaunty/evolution/baz" class="...">lp:~foo/ubuntu/jaunty/evolution/baz</a><br />
373
    <a href="/+branch/foo/bar" class="...">lp:foo/bar</a><br />
374
    <a href="/+branch/foo" class="...">lp:foo</a><br />
375
    <a href="/+branch/foo" class="...">lp:foo</a>,<br />
376
    <a href="/+branch/foo/bar" class="...">lp:foo/bar</a>.<br />
377
    <a href="/+branch/foo/bar/baz" class="...">lp:foo/bar/baz</a><br />
378
    <a href="/+branch/foo" class="...">lp:///foo</a><br />
379
    <a href="/+branch/foo" class="...">lp:/foo</a></p>
8030.1.1 by Jonathan Lange
Highlight lp URLs in branches.
380
8377.1.1 by Jonathan Lange
Address the actual bug, extracting out the code that generates a bug
381
Text that looks like a branch reference, but is followed only by digits is
382
treated as a link to a bug.
383
384
    >>> text = 'lp:1234'
385
    >>> print test_tales('foo/fmt:text-to-html', foo=text)
13570.1.13 by Nigel Babu
merged devel. fixed breakage
386
    <p><a href="/bugs/1234" class="bug-link">lp:1234</a></p>
8377.1.1 by Jonathan Lange
Address the actual bug, extracting out the code that generates a bug
387
8377.1.4 by Jonathan Lange
Handle trailing punctuation on lp:1234 bug links.
388
We are even smart enough to notice the trailing punctuation gunk and separate
389
that from the link.
390
391
    >>> text = 'lp:1234,'
392
    >>> print test_tales('foo/fmt:text-to-html', foo=text)
13570.1.13 by Nigel Babu
merged devel. fixed breakage
393
    <p><a href="/bugs/1234" class="bug-link">lp:1234</a>,</p>
8377.1.4 by Jonathan Lange
Handle trailing punctuation on lp:1234 bug links.
394
8030.1.1 by Jonathan Lange
Highlight lp URLs in branches.
395
14291.1.1 by Jeroen Vermeulen
Some lint.
396
OOPS references
397
---------------
5261.1.1 by Christian Robottom Reis
First cut of fix for bug #126371, Reference to FAQ should be automatically linked in comments. Do just that.
398
3095.2.1 by Dafydd Harries
turn OOPSes into links for developers
399
fmt:text-to-html is also smart enough to convert OOPS references into
400
links. However, it only does this if the logged in person is a member of the
401
Launchpad Developers team.
402
3485.3.12 by James Henstridge
fix for bug 28620 (don't linkify words ending in 'bug'), and some cleanups to displaying-paragraphs-of-text.txt
403
XXX 2006-08-23 jamesh
404
We explicitly cal set_developer_in_launchbag_before_traversal() here.
405
If this event handler is not called, then the "developer" attribute in
406
the launchbag is not updated.  Normally it would be called during the
407
request before traversal, but we aren't doing publication traversal in
408
this test.
409
  https://launchpad.net/bugs/30746
410
3095.2.3 by Dafydd Harries
add comment about test ugliness
411
3095.2.1 by Dafydd Harries
turn OOPSes into links for developers
412
When not logged in as a privileged user, no link:
413
14600.2.2 by Curtis Hovey
Moved webapp to lp.services.
414
    >>> from lp.services.webapp.launchbag import (
3485.3.12 by James Henstridge
fix for bug 28620 (don't linkify words ending in 'bug'), and some cleanups to displaying-paragraphs-of-text.txt
415
    ...     set_developer_in_launchbag_before_traversal)
416
    >>> login('test@canonical.com')
417
    >>> set_developer_in_launchbag_before_traversal(None)
418
    >>> getUtility(ILaunchBag).developer
419
    False
420
14235.1.2 by Robert Collins
Take two: restore the false-positive check and instead nuke support for OOPS 12ad13 being linked.
421
    >>> text = 'OOPS-38C23'
3485.3.12 by James Henstridge
fix for bug 28620 (don't linkify words ending in 'bug'), and some cleanups to displaying-paragraphs-of-text.txt
422
    >>> print test_tales('foo/fmt:text-to-html', foo=text)
14235.1.2 by Robert Collins
Take two: restore the false-positive check and instead nuke support for OOPS 12ad13 being linked.
423
    <p>OOPS-38C23</p>
3485.3.12 by James Henstridge
fix for bug 28620 (don't linkify words ending in 'bug'), and some cleanups to displaying-paragraphs-of-text.txt
424
3095.2.1 by Dafydd Harries
turn OOPSes into links for developers
425
426
After login, a link:
427
3485.3.12 by James Henstridge
fix for bug 28620 (don't linkify words ending in 'bug'), and some cleanups to displaying-paragraphs-of-text.txt
428
    >>> login('foo.bar@canonical.com')
429
    >>> set_developer_in_launchbag_before_traversal(None)
430
    >>> getUtility(ILaunchBag).developer
431
    True
432
433
    >>> print test_tales('foo/fmt:text-to-html', foo=text)
14235.1.2 by Robert Collins
Take two: restore the false-positive check and instead nuke support for OOPS 12ad13 being linked.
434
    <p><a href="https://lp-oops.canonical.com/oops.py/?oopsid=OOPS-38C23">OOPS-38C23</a></p>
3095.2.1 by Dafydd Harries
turn OOPSes into links for developers
435
436
OOPS references can take a number of forms:
437
438
    >>> text = 'OOPS-38C23'
439
    >>> print test_tales('foo/fmt:text-to-html', foo=text)
14235.1.1 by Robert Collins
Change the OOP urlification regex to be simpler and accept whatever single opaque string a system has generated.
440
    <p><a href="https://lp-oops.canonical.com/oops.py/?oopsid=OOPS-38C23">OOPS-38C23</a></p>
3095.2.1 by Dafydd Harries
turn OOPSes into links for developers
441
14235.1.1 by Robert Collins
Change the OOP urlification regex to be simpler and accept whatever single opaque string a system has generated.
442
    >>> text = 'OOPS-123abcdef'
443
    >>> print test_tales('foo/fmt:text-to-html', foo=text)
444
    <p><a href="https://lp-oops.canonical.com/oops.py/?oopsid=OOPS-123abcdef">OOPS-123abcdef</a></p>
445
446
    >>> text = 'OOPS-abcdef123'
447
    >>> print test_tales('foo/fmt:text-to-html', foo=text)
448
    <p><a href="https://lp-oops.canonical.com/oops.py/?oopsid=OOPS-abcdef123">OOPS-abcdef123</a></p>
3095.2.1 by Dafydd Harries
turn OOPSes into links for developers
449
7703.3.2 by Jonathan Lange
Fix broken tests.
450
If the configuration value doesn't end with a slash, we won't add one. This
451
lets us configure the URL to use query parameters.
3095.2.5 by Dafydd Harries
make oops links work if oops_root_url config value doesn't end with slash
452
14605.1.1 by Curtis Hovey
Moved canonical.config to lp.services.
453
    >>> from lp.services.config import config
7031.3.1 by Curtis Hovey
Fixed all unit tests and doctests that mutated the config.
454
    >>> oops_root_url = """
455
    ...     [launchpad]
456
    ...     oops_root_url: http://foo/bar
457
    ...     """
458
    >>> config.push('oops_root_url', oops_root_url)
14235.1.2 by Robert Collins
Take two: restore the false-positive check and instead nuke support for OOPS 12ad13 being linked.
459
    >>> text = 'OOPS-38C23'
3095.2.5 by Dafydd Harries
make oops links work if oops_root_url config value doesn't end with slash
460
    >>> print test_tales('foo/fmt:text-to-html', foo=text)
14235.1.2 by Robert Collins
Take two: restore the false-positive check and instead nuke support for OOPS 12ad13 being linked.
461
    <p><a href="http://foo/barOOPS-38C23">OOPS-38C23</a></p>
7031.3.1 by Curtis Hovey
Fixed all unit tests and doctests that mutated the config.
462
    >>> config_data = config.pop('oops_root_url')
3095.2.5 by Dafydd Harries
make oops links work if oops_root_url config value doesn't end with slash
463
14235.1.2 by Robert Collins
Take two: restore the false-positive check and instead nuke support for OOPS 12ad13 being linked.
464
Check against false positives:
465
466
    >>> text = 'OOPS code'
467
    >>> print test_tales('foo/fmt:text-to-html', foo=text)
468
    <p>OOPS code</p>
469
3095.2.5 by Dafydd Harries
make oops links work if oops_root_url config value doesn't end with slash
470
Reset login information.
471
3095.2.1 by Dafydd Harries
turn OOPSes into links for developers
472
    >>> login('test@canonical.com')
3485.3.12 by James Henstridge
fix for bug 28620 (don't linkify words ending in 'bug'), and some cleanups to displaying-paragraphs-of-text.txt
473
    >>> set_developer_in_launchbag_before_traversal(None)
474
    >>> getUtility(ILaunchBag).developer
475
    False
3095.2.1 by Dafydd Harries
turn OOPSes into links for developers
476
4353.2.1 by Curtis Hovey
Markup and logic in place. Must be assembled to work.
477
14291.1.1 by Jeroen Vermeulen
Some lint.
478
Regex helper functions
479
----------------------
2360 by Canonical.com Patch Queue Manager
[r=BjornT] implement MaloneSearchResults (currently exposed only on
480
481
The _substitute_matchgroup_for_spaces() static method is part of the
482
fmt:text-to-html code.  It is a helper for writing regular expressions where
483
we want to replace a variable number of spaces with the same number of
484
&nbsp; entities.
485
10861.1.2 by Tim Penhey
Move the FormattersAPI class.
486
    >>> from lp.app.browser.stringformatter import FormattersAPI
2360 by Canonical.com Patch Queue Manager
[r=BjornT] implement MaloneSearchResults (currently exposed only on
487
    >>> import re
488
    >>> matchobj = re.match('foo(.*)bar', 'fooX Ybar')
489
    >>> matchobj.groups()
490
    ('X Y',)
491
    >>> FormattersAPI._substitute_matchgroup_for_spaces(matchobj)
492
    '&nbsp;&nbsp;&nbsp;'
493
14291.1.1 by Jeroen Vermeulen
Some lint.
494
The _linkify_substitution() static method is used for converting bug
495
references or URLs into links.  It uses the named matchgroups 'bug' and
496
'bugnum' when it is dealing with bugs, and 'url' when it is dealing with URLs.
2360 by Canonical.com Patch Queue Manager
[r=BjornT] implement MaloneSearchResults (currently exposed only on
497
498
First, let's try a match of nothing it understands.  This is a bug, so we get
499
an AssertionError.
500
8030.1.2 by Jonathan Lange
Make the tests pass
501
    >>> matchobj = re.match(
502
    ...     ('(?P<bug>xxx)?(?P<faq>www)?(?P<url>yyy)?(?P<oops>zzz)?'
9024.5.1 by James Westby
Also link "LP: #12345" bug numbers as used in Ubuntu changelogs.
503
    ...      '(?P<lpbranchurl>www)?(?P<clbug>vvv)?'),
8030.1.2 by Jonathan Lange
Make the tests pass
504
    ...     'fish')
2360 by Canonical.com Patch Queue Manager
[r=BjornT] implement MaloneSearchResults (currently exposed only on
505
    >>> sorted(matchobj.groupdict().items())
8030.1.2 by Jonathan Lange
Make the tests pass
506
    [('bug', None),
9024.5.1 by James Westby
Also link "LP: #12345" bug numbers as used in Ubuntu changelogs.
507
     ('clbug', None),
8030.1.2 by Jonathan Lange
Make the tests pass
508
     ('faq', None),
509
      ('lpbranchurl', None),
510
      ('oops', None),
511
      ('url', None)]
2360 by Canonical.com Patch Queue Manager
[r=BjornT] implement MaloneSearchResults (currently exposed only on
512
    >>> FormattersAPI._linkify_substitution(matchobj)
513
    Traceback (most recent call last):
514
    ...
515
    AssertionError: Unknown pattern matched.
516
517
When we have a URL, the URL is made into a link.  A quote is added to the
518
url to demonstrate quoting in the HTML attribute.
519
520
    >>> matchobj = re.match('(?P<bug>xxx)?(?P<url>y"y)?', 'y"y')
521
    >>> sorted(matchobj.groupdict().items())
522
    [('bug', None), ('url', 'y"y')]
523
    >>> FormattersAPI._linkify_substitution(matchobj)
524
    '<a rel="nofollow" href="y&quot;y">y"y</a>'
525
526
When we have a bug reference, the 'bug' group is used as the text of the link,
527
and the 'bugnum' is used to look up the bug.
528
529
    >>> matchobj = re.match(
530
    ...     '(?P<bug>xxxx)?(?P<bugnum>2)?(?P<url>yyy)?', 'xxxx2')
531
    >>> sorted(matchobj.groupdict().items())
532
    [('bug', 'xxxx'), ('bugnum', '2'), ('url', None)]
533
    >>> FormattersAPI._linkify_substitution(matchobj)
13570.1.13 by Nigel Babu
merged devel. fixed breakage
534
    '<a href="/bugs/2" class="bug-link">xxxx</a>'
2360 by Canonical.com Patch Queue Manager
[r=BjornT] implement MaloneSearchResults (currently exposed only on
535
536
When the bugnum doesn't match any bug, we still get a link, but get a message
537
in the link's title.
538
539
    >>> matchobj = re.match(
540
    ...     '(?P<bug>xxxx)?(?P<bugnum>2000)?(?P<url>yyy)?', 'xxxx2000')
541
    >>> sorted(matchobj.groupdict().items())
542
    [('bug', 'xxxx'), ('bugnum', '2000'), ('url', None)]
543
    >>> FormattersAPI._linkify_substitution(matchobj)
13570.1.15 by Nigel Babu
Fix a broken doctest too
544
    '<a href="/bugs/2000" class="bug-link">xxxx</a>'