##// END OF EJS Templates
Better handle html-only emails (#16962)....
Jean-Philippe Lang -
r13931:3ae42cb32617
parent child
Show More
@@ -0,0 +1,54
1 # Redmine - project management software
2 # Copyright (C) 2006-2015 Jean-Philippe Lang
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
18 require 'loofah/helpers'
19
20 module Redmine
21 module WikiFormatting
22 class HtmlParser
23
24 class_attribute :tags
25 self.tags = {
26 'br' => {:post => "\n"}
27 }
28
29 def self.to_text(html)
30 html = html.gsub(/[\n\r]/, '').squeeze(' ')
31
32 doc = Loofah.document(html)
33 doc.scrub!(WikiTags.new(tags))
34 doc.scrub!(:newline_block_elements)
35
36 Loofah::Helpers.remove_extraneous_whitespace(doc.text).strip
37 end
38
39 class WikiTags < ::Loofah::Scrubber
40 def initialize(tags_to_text)
41 @direction = :bottom_up
42 @tags_to_text = tags_to_text || {}
43 end
44
45 def scrub(node)
46 formatting = @tags_to_text[node.name]
47 return CONTINUE unless formatting
48 node.add_next_sibling Nokogiri::XML::Text.new("#{formatting[:pre]}#{node.content}#{formatting[:post]}", node.document)
49 node.remove
50 end
51 end
52 end
53 end
54 end
@@ -0,0 +1,40
1 # Redmine - project management software
2 # Copyright (C) 2006-2015 Jean-Philippe Lang
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
18 module Redmine
19 module WikiFormatting
20 module Markdown
21 class HtmlParser < Redmine::WikiFormatting::HtmlParser
22
23 self.tags = {
24 'b' => {:pre => '**', :post => '**'},
25 'strong' => {:pre => '**', :post => '**'},
26 'i' => {:pre => '_', :post => '_'},
27 'em' => {:pre => '_', :post => '_'},
28 'strike' => {:pre => '~~', :post => '~~'},
29 'br' => {:post => "\n"},
30 'h1' => {:pre => "\n\n# ", :post => "\n\n"},
31 'h2' => {:pre => "\n\n## ", :post => "\n\n"},
32 'h3' => {:pre => "\n\n### ", :post => "\n\n"},
33 'h4' => {:pre => "\n\n#### ", :post => "\n\n"},
34 'h5' => {:pre => "\n\n##### ", :post => "\n\n"},
35 'h6' => {:pre => "\n\n###### ", :post => "\n\n"}
36 }
37 end
38 end
39 end
40 end
@@ -0,0 +1,41
1 # Redmine - project management software
2 # Copyright (C) 2006-2015 Jean-Philippe Lang
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
18 module Redmine
19 module WikiFormatting
20 module Textile
21 class HtmlParser < Redmine::WikiFormatting::HtmlParser
22
23 self.tags = {
24 'b' => {:pre => '*', :post => '*'},
25 'strong' => {:pre => '*', :post => '*'},
26 'i' => {:pre => '_', :post => '_'},
27 'em' => {:pre => '_', :post => '_'},
28 'u' => {:pre => '+', :post => '+'},
29 'strike' => {:pre => '-', :post => '-'},
30 'br' => {:post => "\n"},
31 'h1' => {:pre => "\n\nh1. ", :post => "\n\n"},
32 'h2' => {:pre => "\n\nh2. ", :post => "\n\n"},
33 'h3' => {:pre => "\n\nh3. ", :post => "\n\n"},
34 'h4' => {:pre => "\n\nh4. ", :post => "\n\n"},
35 'h5' => {:pre => "\n\nh5. ", :post => "\n\n"},
36 'h6' => {:pre => "\n\nh6. ", :post => "\n\n"}
37 }
38 end
39 end
40 end
41 end
This diff has been collapsed as it changes many lines, (966 lines changed) Show them Hide them
@@ -0,0 +1,966
1 From: jsmith@somenet.foo
2 To: testuser@example.org
3 Subject: =?utf-8?Q?Test_email?=
4 Date: Mon, 11 May 2015 10:50:31 -0500
5 MIME-Version: 1.0
6 Content-Type: multipart/alternative;
7 boundary="Mark=_539924359269962179476"
8 X-Priority: 3
9
10 This is a multi-part message in MIME format.
11
12 --Mark=_539924359269962179476
13 Content-Type: text/plain;
14 charset="utf-8"
15 Content-Transfer-Encoding: quoted-printable
16
17 Simple, unadorned test email generated by Outlook 2010. It is in HTML f=
18 ormat, but no special formatting has been chosen. I=E2=80=99m going to =
19 save this as a draft and then manually drop it into the Inbox for scrap=
20 ing by Redmine 3.0.2.
21
22 --Mark=_539924359269962179476
23 Content-Type: text/html;
24 charset="utf-8"
25 Content-Transfer-Encoding: quoted-printable
26
27 <STYLE>
28 pre {
29 white-space: pre-wrap; /* css-3 */
30 white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */
31 white-space: -pre-wrap; /* Opera 4-6 */
32 white-space: -o-pre-wrap; /* Opera 7 */
33 word-wrap: break-word; /* Internet Explorer 5.5+ */
34 }
35 </STYLE>
36 <html xmlns:v=3D"urn:schemas-microsoft-com:vml" xmlns:o=3D"urn:schemas-=
37 microsoft-com:office:office" xmlns:w=3D"urn:schemas-microsoft-com:offic=
38 e:word" xmlns:m=3D"http://schemas.microsoft.com/office/2004/12/omml" xm=
39 lns=3D"http://www.w3.org/TR/REC-html40"><head><meta name=3DProgId conte=
40 nt=3DWord.Document><meta name=3DGenerator content=3D"Microsoft Word 15"=
41 ><meta name=3DOriginator content=3D"Microsoft Word 15"><link rel=3DFile=
42 -List href=3D"cid:filelist.xml@01D08BD8.4D051580"><!--[if gte mso 9]><x=
43 ml>
44 <o:OfficeDocumentSettings>
45 <o:AllowPNG/>
46 </o:OfficeDocumentSettings>
47 </xml><![endif]--><link rel=3DthemeData href=3D"~~themedata~~"><link re=
48 l=3DcolorSchemeMapping href=3D"~~colorschememapping~~"><!--[if gte mso =
49 9]><xml>
50 <w:WordDocument>
51 <w:Zoom>120</w:Zoom>
52 <w:SpellingState>Clean</w:SpellingState>
53 <w:TrackMoves/>
54 <w:TrackFormatting/>
55 <w:EnvelopeVis/>
56 <w:PunctuationKerning/>
57 <w:ValidateAgainstSchemas/>
58 <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
59 <w:IgnoreMixedContent>false</w:IgnoreMixedContent>
60 <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
61 <w:DoNotPromoteQF/>
62 <w:LidThemeOther>EN-US</w:LidThemeOther>
63 <w:LidThemeAsian>X-NONE</w:LidThemeAsian>
64 <w:LidThemeComplexScript>X-NONE</w:LidThemeComplexScript>
65 <w:Compatibility>
66 <w:DoNotExpandShiftReturn/>
67 <w:BreakWrappedTables/>
68 <w:SnapToGridInCell/>
69 <w:WrapTextWithPunct/>
70 <w:UseAsianBreakRules/>
71 <w:DontGrowAutofit/>
72 <w:SplitPgBreakAndParaMark/>
73 <w:EnableOpenTypeKerning/>
74 <w:DontFlipMirrorIndents/>
75 <w:OverrideTableStyleHps/>
76 </w:Compatibility>
77 <w:BrowserLevel>MicrosoftInternetExplorer4</w:BrowserLevel>
78 <m:mathPr>
79 <m:mathFont m:val=3D"Cambria Math"/>
80 <m:brkBin m:val=3D"before"/>
81 <m:brkBinSub m:val=3D"&#45;-"/>
82 <m:smallFrac m:val=3D"off"/>
83 <m:dispDef/>
84 <m:lMargin m:val=3D"0"/>
85 <m:rMargin m:val=3D"0"/>
86 <m:defJc m:val=3D"centerGroup"/>
87 <m:wrapIndent m:val=3D"1440"/>
88 <m:intLim m:val=3D"subSup"/>
89 <m:naryLim m:val=3D"undOvr"/>
90 </m:mathPr></w:WordDocument>
91 </xml><![endif]--><!--[if gte mso 9]><xml>
92 <w:LatentStyles DefLockedState=3D"false" DefUnhideWhenUsed=3D"false" De=
93 fSemiHidden=3D"false" DefQFormat=3D"false" DefPriority=3D"99" LatentSty=
94 leCount=3D"371">
95 <w:LsdException Locked=3D"false" Priority=3D"0" QFormat=3D"true" Name=3D=
96 "Normal"/>
97 <w:LsdException Locked=3D"false" Priority=3D"9" QFormat=3D"true" Name=3D=
98 "heading 1"/>
99 <w:LsdException Locked=3D"false" Priority=3D"9" SemiHidden=3D"true" Unh=
100 ideWhenUsed=3D"true" QFormat=3D"true" Name=3D"heading 2"/>
101 <w:LsdException Locked=3D"false" Priority=3D"9" SemiHidden=3D"true" Unh=
102 ideWhenUsed=3D"true" QFormat=3D"true" Name=3D"heading 3"/>
103 <w:LsdException Locked=3D"false" Priority=3D"9" SemiHidden=3D"true" Unh=
104 ideWhenUsed=3D"true" QFormat=3D"true" Name=3D"heading 4"/>
105 <w:LsdException Locked=3D"false" Priority=3D"9" SemiHidden=3D"true" Unh=
106 ideWhenUsed=3D"true" QFormat=3D"true" Name=3D"heading 5"/>
107 <w:LsdException Locked=3D"false" Priority=3D"9" SemiHidden=3D"true" Unh=
108 ideWhenUsed=3D"true" QFormat=3D"true" Name=3D"heading 6"/>
109 <w:LsdException Locked=3D"false" Priority=3D"9" SemiHidden=3D"true" Unh=
110 ideWhenUsed=3D"true" QFormat=3D"true" Name=3D"heading 7"/>
111 <w:LsdException Locked=3D"false" Priority=3D"9" SemiHidden=3D"true" Unh=
112 ideWhenUsed=3D"true" QFormat=3D"true" Name=3D"heading 8"/>
113 <w:LsdException Locked=3D"false" Priority=3D"9" SemiHidden=3D"true" Unh=
114 ideWhenUsed=3D"true" QFormat=3D"true" Name=3D"heading 9"/>
115 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
116 true" Name=3D"index 1"/>
117 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
118 true" Name=3D"index 2"/>
119 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
120 true" Name=3D"index 3"/>
121 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
122 true" Name=3D"index 4"/>
123 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
124 true" Name=3D"index 5"/>
125 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
126 true" Name=3D"index 6"/>
127 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
128 true" Name=3D"index 7"/>
129 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
130 true" Name=3D"index 8"/>
131 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
132 true" Name=3D"index 9"/>
133 <w:LsdException Locked=3D"false" Priority=3D"39" SemiHidden=3D"true" Un=
134 hideWhenUsed=3D"true" Name=3D"toc 1"/>
135 <w:LsdException Locked=3D"false" Priority=3D"39" SemiHidden=3D"true" Un=
136 hideWhenUsed=3D"true" Name=3D"toc 2"/>
137 <w:LsdException Locked=3D"false" Priority=3D"39" SemiHidden=3D"true" Un=
138 hideWhenUsed=3D"true" Name=3D"toc 3"/>
139 <w:LsdException Locked=3D"false" Priority=3D"39" SemiHidden=3D"true" Un=
140 hideWhenUsed=3D"true" Name=3D"toc 4"/>
141 <w:LsdException Locked=3D"false" Priority=3D"39" SemiHidden=3D"true" Un=
142 hideWhenUsed=3D"true" Name=3D"toc 5"/>
143 <w:LsdException Locked=3D"false" Priority=3D"39" SemiHidden=3D"true" Un=
144 hideWhenUsed=3D"true" Name=3D"toc 6"/>
145 <w:LsdException Locked=3D"false" Priority=3D"39" SemiHidden=3D"true" Un=
146 hideWhenUsed=3D"true" Name=3D"toc 7"/>
147 <w:LsdException Locked=3D"false" Priority=3D"39" SemiHidden=3D"true" Un=
148 hideWhenUsed=3D"true" Name=3D"toc 8"/>
149 <w:LsdException Locked=3D"false" Priority=3D"39" SemiHidden=3D"true" Un=
150 hideWhenUsed=3D"true" Name=3D"toc 9"/>
151 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
152 true" Name=3D"Normal Indent"/>
153 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
154 true" Name=3D"footnote text"/>
155 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
156 true" Name=3D"annotation text"/>
157 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
158 true" Name=3D"header"/>
159 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
160 true" Name=3D"footer"/>
161 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
162 true" Name=3D"index heading"/>
163 <w:LsdException Locked=3D"false" Priority=3D"35" SemiHidden=3D"true" Un=
164 hideWhenUsed=3D"true" QFormat=3D"true" Name=3D"caption"/>
165 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
166 true" Name=3D"table of figures"/>
167 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
168 true" Name=3D"envelope address"/>
169 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
170 true" Name=3D"envelope return"/>
171 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
172 true" Name=3D"footnote reference"/>
173 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
174 true" Name=3D"annotation reference"/>
175 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
176 true" Name=3D"line number"/>
177 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
178 true" Name=3D"page number"/>
179 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
180 true" Name=3D"endnote reference"/>
181 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
182 true" Name=3D"endnote text"/>
183 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
184 true" Name=3D"table of authorities"/>
185 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
186 true" Name=3D"macro"/>
187 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
188 true" Name=3D"toa heading"/>
189 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
190 true" Name=3D"List"/>
191 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
192 true" Name=3D"List Bullet"/>
193 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
194 true" Name=3D"List Number"/>
195 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
196 true" Name=3D"List 2"/>
197 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
198 true" Name=3D"List 3"/>
199 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
200 true" Name=3D"List 4"/>
201 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
202 true" Name=3D"List 5"/>
203 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
204 true" Name=3D"List Bullet 2"/>
205 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
206 true" Name=3D"List Bullet 3"/>
207 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
208 true" Name=3D"List Bullet 4"/>
209 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
210 true" Name=3D"List Bullet 5"/>
211 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
212 true" Name=3D"List Number 2"/>
213 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
214 true" Name=3D"List Number 3"/>
215 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
216 true" Name=3D"List Number 4"/>
217 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
218 true" Name=3D"List Number 5"/>
219 <w:LsdException Locked=3D"false" Priority=3D"10" QFormat=3D"true" Name=3D=
220 "Title"/>
221 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
222 true" Name=3D"Closing"/>
223 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
224 true" Name=3D"Signature"/>
225 <w:LsdException Locked=3D"false" Priority=3D"1" SemiHidden=3D"true" Unh=
226 ideWhenUsed=3D"true" Name=3D"Default Paragraph Font"/>
227 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
228 true" Name=3D"Body Text"/>
229 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
230 true" Name=3D"Body Text Indent"/>
231 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
232 true" Name=3D"List Continue"/>
233 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
234 true" Name=3D"List Continue 2"/>
235 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
236 true" Name=3D"List Continue 3"/>
237 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
238 true" Name=3D"List Continue 4"/>
239 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
240 true" Name=3D"List Continue 5"/>
241 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
242 true" Name=3D"Message Header"/>
243 <w:LsdException Locked=3D"false" Priority=3D"11" QFormat=3D"true" Name=3D=
244 "Subtitle"/>
245 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
246 true" Name=3D"Salutation"/>
247 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
248 true" Name=3D"Date"/>
249 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
250 true" Name=3D"Body Text First Indent"/>
251 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
252 true" Name=3D"Body Text First Indent 2"/>
253 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
254 true" Name=3D"Note Heading"/>
255 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
256 true" Name=3D"Body Text 2"/>
257 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
258 true" Name=3D"Body Text 3"/>
259 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
260 true" Name=3D"Body Text Indent 2"/>
261 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
262 true" Name=3D"Body Text Indent 3"/>
263 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
264 true" Name=3D"Block Text"/>
265 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
266 true" Name=3D"Hyperlink"/>
267 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
268 true" Name=3D"FollowedHyperlink"/>
269 <w:LsdException Locked=3D"false" Priority=3D"22" QFormat=3D"true" Name=3D=
270 "Strong"/>
271 <w:LsdException Locked=3D"false" Priority=3D"20" QFormat=3D"true" Name=3D=
272 "Emphasis"/>
273 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
274 true" Name=3D"Document Map"/>
275 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
276 true" Name=3D"Plain Text"/>
277 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
278 true" Name=3D"E-mail Signature"/>
279 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
280 true" Name=3D"HTML Top of Form"/>
281 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
282 true" Name=3D"HTML Bottom of Form"/>
283 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
284 true" Name=3D"Normal (Web)"/>
285 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
286 true" Name=3D"HTML Acronym"/>
287 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
288 true" Name=3D"HTML Address"/>
289 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
290 true" Name=3D"HTML Cite"/>
291 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
292 true" Name=3D"HTML Code"/>
293 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
294 true" Name=3D"HTML Definition"/>
295 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
296 true" Name=3D"HTML Keyboard"/>
297 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
298 true" Name=3D"HTML Preformatted"/>
299 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
300 true" Name=3D"HTML Sample"/>
301 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
302 true" Name=3D"HTML Typewriter"/>
303 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
304 true" Name=3D"HTML Variable"/>
305 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
306 true" Name=3D"Normal Table"/>
307 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
308 true" Name=3D"annotation subject"/>
309 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
310 true" Name=3D"No List"/>
311 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
312 true" Name=3D"Outline List 1"/>
313 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
314 true" Name=3D"Outline List 2"/>
315 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
316 true" Name=3D"Outline List 3"/>
317 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
318 true" Name=3D"Table Simple 1"/>
319 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
320 true" Name=3D"Table Simple 2"/>
321 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
322 true" Name=3D"Table Simple 3"/>
323 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
324 true" Name=3D"Table Classic 1"/>
325 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
326 true" Name=3D"Table Classic 2"/>
327 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
328 true" Name=3D"Table Classic 3"/>
329 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
330 true" Name=3D"Table Classic 4"/>
331 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
332 true" Name=3D"Table Colorful 1"/>
333 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
334 true" Name=3D"Table Colorful 2"/>
335 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
336 true" Name=3D"Table Colorful 3"/>
337 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
338 true" Name=3D"Table Columns 1"/>
339 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
340 true" Name=3D"Table Columns 2"/>
341 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
342 true" Name=3D"Table Columns 3"/>
343 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
344 true" Name=3D"Table Columns 4"/>
345 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
346 true" Name=3D"Table Columns 5"/>
347 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
348 true" Name=3D"Table Grid 1"/>
349 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
350 true" Name=3D"Table Grid 2"/>
351 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
352 true" Name=3D"Table Grid 3"/>
353 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
354 true" Name=3D"Table Grid 4"/>
355 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
356 true" Name=3D"Table Grid 5"/>
357 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
358 true" Name=3D"Table Grid 6"/>
359 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
360 true" Name=3D"Table Grid 7"/>
361 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
362 true" Name=3D"Table Grid 8"/>
363 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
364 true" Name=3D"Table List 1"/>
365 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
366 true" Name=3D"Table List 2"/>
367 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
368 true" Name=3D"Table List 3"/>
369 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
370 true" Name=3D"Table List 4"/>
371 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
372 true" Name=3D"Table List 5"/>
373 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
374 true" Name=3D"Table List 6"/>
375 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
376 true" Name=3D"Table List 7"/>
377 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
378 true" Name=3D"Table List 8"/>
379 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
380 true" Name=3D"Table 3D effects 1"/>
381 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
382 true" Name=3D"Table 3D effects 2"/>
383 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
384 true" Name=3D"Table 3D effects 3"/>
385 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
386 true" Name=3D"Table Contemporary"/>
387 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
388 true" Name=3D"Table Elegant"/>
389 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
390 true" Name=3D"Table Professional"/>
391 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
392 true" Name=3D"Table Subtle 1"/>
393 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
394 true" Name=3D"Table Subtle 2"/>
395 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
396 true" Name=3D"Table Web 1"/>
397 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
398 true" Name=3D"Table Web 2"/>
399 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
400 true" Name=3D"Table Web 3"/>
401 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
402 true" Name=3D"Balloon Text"/>
403 <w:LsdException Locked=3D"false" Priority=3D"59" Name=3D"Table Grid"/>
404 <w:LsdException Locked=3D"false" SemiHidden=3D"true" UnhideWhenUsed=3D"=
405 true" Name=3D"Table Theme"/>
406 <w:LsdException Locked=3D"false" SemiHidden=3D"true" Name=3D"Placeholde=
407 r Text"/>
408 <w:LsdException Locked=3D"false" Priority=3D"1" QFormat=3D"true" Name=3D=
409 "No Spacing"/>
410 <w:LsdException Locked=3D"false" Priority=3D"60" Name=3D"Light Shading"=
411 />
412 <w:LsdException Locked=3D"false" Priority=3D"61" Name=3D"Light List"/>
413 <w:LsdException Locked=3D"false" Priority=3D"62" Name=3D"Light Grid"/>
414 <w:LsdException Locked=3D"false" Priority=3D"63" Name=3D"Medium Shading=
415 1"/>
416 <w:LsdException Locked=3D"false" Priority=3D"64" Name=3D"Medium Shading=
417 2"/>
418 <w:LsdException Locked=3D"false" Priority=3D"65" Name=3D"Medium List 1"=
419 />
420 <w:LsdException Locked=3D"false" Priority=3D"66" Name=3D"Medium List 2"=
421 />
422 <w:LsdException Locked=3D"false" Priority=3D"67" Name=3D"Medium Grid 1"=
423 />
424 <w:LsdException Locked=3D"false" Priority=3D"68" Name=3D"Medium Grid 2"=
425 />
426 <w:LsdException Locked=3D"false" Priority=3D"69" Name=3D"Medium Grid 3"=
427 />
428 <w:LsdException Locked=3D"false" Priority=3D"70" Name=3D"Dark List"/>
429 <w:LsdException Locked=3D"false" Priority=3D"71" Name=3D"Colorful Shadi=
430 ng"/>
431 <w:LsdException Locked=3D"false" Priority=3D"72" Name=3D"Colorful List"=
432 />
433 <w:LsdException Locked=3D"false" Priority=3D"73" Name=3D"Colorful Grid"=
434 />
435 <w:LsdException Locked=3D"false" Priority=3D"60" Name=3D"Light Shading =
436 Accent 1"/>
437 <w:LsdException Locked=3D"false" Priority=3D"61" Name=3D"Light List Acc=
438 ent 1"/>
439 <w:LsdException Locked=3D"false" Priority=3D"62" Name=3D"Light Grid Acc=
440 ent 1"/>
441 <w:LsdException Locked=3D"false" Priority=3D"63" Name=3D"Medium Shading=
442 1 Accent 1"/>
443 <w:LsdException Locked=3D"false" Priority=3D"64" Name=3D"Medium Shading=
444 2 Accent 1"/>
445 <w:LsdException Locked=3D"false" Priority=3D"65" Name=3D"Medium List 1 =
446 Accent 1"/>
447 <w:LsdException Locked=3D"false" SemiHidden=3D"true" Name=3D"Revision"/=
448 >
449 <w:LsdException Locked=3D"false" Priority=3D"34" QFormat=3D"true" Name=3D=
450 "List Paragraph"/>
451 <w:LsdException Locked=3D"false" Priority=3D"29" QFormat=3D"true" Name=3D=
452 "Quote"/>
453 <w:LsdException Locked=3D"false" Priority=3D"30" QFormat=3D"true" Name=3D=
454 "Intense Quote"/>
455 <w:LsdException Locked=3D"false" Priority=3D"66" Name=3D"Medium List 2 =
456 Accent 1"/>
457 <w:LsdException Locked=3D"false" Priority=3D"67" Name=3D"Medium Grid 1 =
458 Accent 1"/>
459 <w:LsdException Locked=3D"false" Priority=3D"68" Name=3D"Medium Grid 2 =
460 Accent 1"/>
461 <w:LsdException Locked=3D"false" Priority=3D"69" Name=3D"Medium Grid 3 =
462 Accent 1"/>
463 <w:LsdException Locked=3D"false" Priority=3D"70" Name=3D"Dark List Acce=
464 nt 1"/>
465 <w:LsdException Locked=3D"false" Priority=3D"71" Name=3D"Colorful Shadi=
466 ng Accent 1"/>
467 <w:LsdException Locked=3D"false" Priority=3D"72" Name=3D"Colorful List =
468 Accent 1"/>
469 <w:LsdException Locked=3D"false" Priority=3D"73" Name=3D"Colorful Grid =
470 Accent 1"/>
471 <w:LsdException Locked=3D"false" Priority=3D"60" Name=3D"Light Shading =
472 Accent 2"/>
473 <w:LsdException Locked=3D"false" Priority=3D"61" Name=3D"Light List Acc=
474 ent 2"/>
475 <w:LsdException Locked=3D"false" Priority=3D"62" Name=3D"Light Grid Acc=
476 ent 2"/>
477 <w:LsdException Locked=3D"false" Priority=3D"63" Name=3D"Medium Shading=
478 1 Accent 2"/>
479 <w:LsdException Locked=3D"false" Priority=3D"64" Name=3D"Medium Shading=
480 2 Accent 2"/>
481 <w:LsdException Locked=3D"false" Priority=3D"65" Name=3D"Medium List 1 =
482 Accent 2"/>
483 <w:LsdException Locked=3D"false" Priority=3D"66" Name=3D"Medium List 2 =
484 Accent 2"/>
485 <w:LsdException Locked=3D"false" Priority=3D"67" Name=3D"Medium Grid 1 =
486 Accent 2"/>
487 <w:LsdException Locked=3D"false" Priority=3D"68" Name=3D"Medium Grid 2 =
488 Accent 2"/>
489 <w:LsdException Locked=3D"false" Priority=3D"69" Name=3D"Medium Grid 3 =
490 Accent 2"/>
491 <w:LsdException Locked=3D"false" Priority=3D"70" Name=3D"Dark List Acce=
492 nt 2"/>
493 <w:LsdException Locked=3D"false" Priority=3D"71" Name=3D"Colorful Shadi=
494 ng Accent 2"/>
495 <w:LsdException Locked=3D"false" Priority=3D"72" Name=3D"Colorful List =
496 Accent 2"/>
497 <w:LsdException Locked=3D"false" Priority=3D"73" Name=3D"Colorful Grid =
498 Accent 2"/>
499 <w:LsdException Locked=3D"false" Priority=3D"60" Name=3D"Light Shading =
500 Accent 3"/>
501 <w:LsdException Locked=3D"false" Priority=3D"61" Name=3D"Light List Acc=
502 ent 3"/>
503 <w:LsdException Locked=3D"false" Priority=3D"62" Name=3D"Light Grid Acc=
504 ent 3"/>
505 <w:LsdException Locked=3D"false" Priority=3D"63" Name=3D"Medium Shading=
506 1 Accent 3"/>
507 <w:LsdException Locked=3D"false" Priority=3D"64" Name=3D"Medium Shading=
508 2 Accent 3"/>
509 <w:LsdException Locked=3D"false" Priority=3D"65" Name=3D"Medium List 1 =
510 Accent 3"/>
511 <w:LsdException Locked=3D"false" Priority=3D"66" Name=3D"Medium List 2 =
512 Accent 3"/>
513 <w:LsdException Locked=3D"false" Priority=3D"67" Name=3D"Medium Grid 1 =
514 Accent 3"/>
515 <w:LsdException Locked=3D"false" Priority=3D"68" Name=3D"Medium Grid 2 =
516 Accent 3"/>
517 <w:LsdException Locked=3D"false" Priority=3D"69" Name=3D"Medium Grid 3 =
518 Accent 3"/>
519 <w:LsdException Locked=3D"false" Priority=3D"70" Name=3D"Dark List Acce=
520 nt 3"/>
521 <w:LsdException Locked=3D"false" Priority=3D"71" Name=3D"Colorful Shadi=
522 ng Accent 3"/>
523 <w:LsdException Locked=3D"false" Priority=3D"72" Name=3D"Colorful List =
524 Accent 3"/>
525 <w:LsdException Locked=3D"false" Priority=3D"73" Name=3D"Colorful Grid =
526 Accent 3"/>
527 <w:LsdException Locked=3D"false" Priority=3D"60" Name=3D"Light Shading =
528 Accent 4"/>
529 <w:LsdException Locked=3D"false" Priority=3D"61" Name=3D"Light List Acc=
530 ent 4"/>
531 <w:LsdException Locked=3D"false" Priority=3D"62" Name=3D"Light Grid Acc=
532 ent 4"/>
533 <w:LsdException Locked=3D"false" Priority=3D"63" Name=3D"Medium Shading=
534 1 Accent 4"/>
535 <w:LsdException Locked=3D"false" Priority=3D"64" Name=3D"Medium Shading=
536 2 Accent 4"/>
537 <w:LsdException Locked=3D"false" Priority=3D"65" Name=3D"Medium List 1 =
538 Accent 4"/>
539 <w:LsdException Locked=3D"false" Priority=3D"66" Name=3D"Medium List 2 =
540 Accent 4"/>
541 <w:LsdException Locked=3D"false" Priority=3D"67" Name=3D"Medium Grid 1 =
542 Accent 4"/>
543 <w:LsdException Locked=3D"false" Priority=3D"68" Name=3D"Medium Grid 2 =
544 Accent 4"/>
545 <w:LsdException Locked=3D"false" Priority=3D"69" Name=3D"Medium Grid 3 =
546 Accent 4"/>
547 <w:LsdException Locked=3D"false" Priority=3D"70" Name=3D"Dark List Acce=
548 nt 4"/>
549 <w:LsdException Locked=3D"false" Priority=3D"71" Name=3D"Colorful Shadi=
550 ng Accent 4"/>
551 <w:LsdException Locked=3D"false" Priority=3D"72" Name=3D"Colorful List =
552 Accent 4"/>
553 <w:LsdException Locked=3D"false" Priority=3D"73" Name=3D"Colorful Grid =
554 Accent 4"/>
555 <w:LsdException Locked=3D"false" Priority=3D"60" Name=3D"Light Shading =
556 Accent 5"/>
557 <w:LsdException Locked=3D"false" Priority=3D"61" Name=3D"Light List Acc=
558 ent 5"/>
559 <w:LsdException Locked=3D"false" Priority=3D"62" Name=3D"Light Grid Acc=
560 ent 5"/>
561 <w:LsdException Locked=3D"false" Priority=3D"63" Name=3D"Medium Shading=
562 1 Accent 5"/>
563 <w:LsdException Locked=3D"false" Priority=3D"64" Name=3D"Medium Shading=
564 2 Accent 5"/>
565 <w:LsdException Locked=3D"false" Priority=3D"65" Name=3D"Medium List 1 =
566 Accent 5"/>
567 <w:LsdException Locked=3D"false" Priority=3D"66" Name=3D"Medium List 2 =
568 Accent 5"/>
569 <w:LsdException Locked=3D"false" Priority=3D"67" Name=3D"Medium Grid 1 =
570 Accent 5"/>
571 <w:LsdException Locked=3D"false" Priority=3D"68" Name=3D"Medium Grid 2 =
572 Accent 5"/>
573 <w:LsdException Locked=3D"false" Priority=3D"69" Name=3D"Medium Grid 3 =
574 Accent 5"/>
575 <w:LsdException Locked=3D"false" Priority=3D"70" Name=3D"Dark List Acce=
576 nt 5"/>
577 <w:LsdException Locked=3D"false" Priority=3D"71" Name=3D"Colorful Shadi=
578 ng Accent 5"/>
579 <w:LsdException Locked=3D"false" Priority=3D"72" Name=3D"Colorful List =
580 Accent 5"/>
581 <w:LsdException Locked=3D"false" Priority=3D"73" Name=3D"Colorful Grid =
582 Accent 5"/>
583 <w:LsdException Locked=3D"false" Priority=3D"60" Name=3D"Light Shading =
584 Accent 6"/>
585 <w:LsdException Locked=3D"false" Priority=3D"61" Name=3D"Light List Acc=
586 ent 6"/>
587 <w:LsdException Locked=3D"false" Priority=3D"62" Name=3D"Light Grid Acc=
588 ent 6"/>
589 <w:LsdException Locked=3D"false" Priority=3D"63" Name=3D"Medium Shading=
590 1 Accent 6"/>
591 <w:LsdException Locked=3D"false" Priority=3D"64" Name=3D"Medium Shading=
592 2 Accent 6"/>
593 <w:LsdException Locked=3D"false" Priority=3D"65" Name=3D"Medium List 1 =
594 Accent 6"/>
595 <w:LsdException Locked=3D"false" Priority=3D"66" Name=3D"Medium List 2 =
596 Accent 6"/>
597 <w:LsdException Locked=3D"false" Priority=3D"67" Name=3D"Medium Grid 1 =
598 Accent 6"/>
599 <w:LsdException Locked=3D"false" Priority=3D"68" Name=3D"Medium Grid 2 =
600 Accent 6"/>
601 <w:LsdException Locked=3D"false" Priority=3D"69" Name=3D"Medium Grid 3 =
602 Accent 6"/>
603 <w:LsdException Locked=3D"false" Priority=3D"70" Name=3D"Dark List Acce=
604 nt 6"/>
605 <w:LsdException Locked=3D"false" Priority=3D"71" Name=3D"Colorful Shadi=
606 ng Accent 6"/>
607 <w:LsdException Locked=3D"false" Priority=3D"72" Name=3D"Colorful List =
608 Accent 6"/>
609 <w:LsdException Locked=3D"false" Priority=3D"73" Name=3D"Colorful Grid =
610 Accent 6"/>
611 <w:LsdException Locked=3D"false" Priority=3D"19" QFormat=3D"true" Name=3D=
612 "Subtle Emphasis"/>
613 <w:LsdException Locked=3D"false" Priority=3D"21" QFormat=3D"true" Name=3D=
614 "Intense Emphasis"/>
615 <w:LsdException Locked=3D"false" Priority=3D"31" QFormat=3D"true" Name=3D=
616 "Subtle Reference"/>
617 <w:LsdException Locked=3D"false" Priority=3D"32" QFormat=3D"true" Name=3D=
618 "Intense Reference"/>
619 <w:LsdException Locked=3D"false" Priority=3D"33" QFormat=3D"true" Name=3D=
620 "Book Title"/>
621 <w:LsdException Locked=3D"false" Priority=3D"37" SemiHidden=3D"true" Un=
622 hideWhenUsed=3D"true" Name=3D"Bibliography"/>
623 <w:LsdException Locked=3D"false" Priority=3D"39" SemiHidden=3D"true" Un=
624 hideWhenUsed=3D"true" QFormat=3D"true" Name=3D"TOC Heading"/>
625 <w:LsdException Locked=3D"false" Priority=3D"41" Name=3D"Plain Table 1"=
626 />
627 <w:LsdException Locked=3D"false" Priority=3D"42" Name=3D"Plain Table 2"=
628 />
629 <w:LsdException Locked=3D"false" Priority=3D"43" Name=3D"Plain Table 3"=
630 />
631 <w:LsdException Locked=3D"false" Priority=3D"44" Name=3D"Plain Table 4"=
632 />
633 <w:LsdException Locked=3D"false" Priority=3D"45" Name=3D"Plain Table 5"=
634 />
635 <w:LsdException Locked=3D"false" Priority=3D"40" Name=3D"Grid Table Lig=
636 ht"/>
637 <w:LsdException Locked=3D"false" Priority=3D"46" Name=3D"Grid Table 1 L=
638 ight"/>
639 <w:LsdException Locked=3D"false" Priority=3D"47" Name=3D"Grid Table 2"/=
640 >
641 <w:LsdException Locked=3D"false" Priority=3D"48" Name=3D"Grid Table 3"/=
642 >
643 <w:LsdException Locked=3D"false" Priority=3D"49" Name=3D"Grid Table 4"/=
644 >
645 <w:LsdException Locked=3D"false" Priority=3D"50" Name=3D"Grid Table 5 D=
646 ark"/>
647 <w:LsdException Locked=3D"false" Priority=3D"51" Name=3D"Grid Table 6 C=
648 olorful"/>
649 <w:LsdException Locked=3D"false" Priority=3D"52" Name=3D"Grid Table 7 C=
650 olorful"/>
651 <w:LsdException Locked=3D"false" Priority=3D"46" Name=3D"Grid Table 1 L=
652 ight Accent 1"/>
653 <w:LsdException Locked=3D"false" Priority=3D"47" Name=3D"Grid Table 2 A=
654 ccent 1"/>
655 <w:LsdException Locked=3D"false" Priority=3D"48" Name=3D"Grid Table 3 A=
656 ccent 1"/>
657 <w:LsdException Locked=3D"false" Priority=3D"49" Name=3D"Grid Table 4 A=
658 ccent 1"/>
659 <w:LsdException Locked=3D"false" Priority=3D"50" Name=3D"Grid Table 5 D=
660 ark Accent 1"/>
661 <w:LsdException Locked=3D"false" Priority=3D"51" Name=3D"Grid Table 6 C=
662 olorful Accent 1"/>
663 <w:LsdException Locked=3D"false" Priority=3D"52" Name=3D"Grid Table 7 C=
664 olorful Accent 1"/>
665 <w:LsdException Locked=3D"false" Priority=3D"46" Name=3D"Grid Table 1 L=
666 ight Accent 2"/>
667 <w:LsdException Locked=3D"false" Priority=3D"47" Name=3D"Grid Table 2 A=
668 ccent 2"/>
669 <w:LsdException Locked=3D"false" Priority=3D"48" Name=3D"Grid Table 3 A=
670 ccent 2"/>
671 <w:LsdException Locked=3D"false" Priority=3D"49" Name=3D"Grid Table 4 A=
672 ccent 2"/>
673 <w:LsdException Locked=3D"false" Priority=3D"50" Name=3D"Grid Table 5 D=
674 ark Accent 2"/>
675 <w:LsdException Locked=3D"false" Priority=3D"51" Name=3D"Grid Table 6 C=
676 olorful Accent 2"/>
677 <w:LsdException Locked=3D"false" Priority=3D"52" Name=3D"Grid Table 7 C=
678 olorful Accent 2"/>
679 <w:LsdException Locked=3D"false" Priority=3D"46" Name=3D"Grid Table 1 L=
680 ight Accent 3"/>
681 <w:LsdException Locked=3D"false" Priority=3D"47" Name=3D"Grid Table 2 A=
682 ccent 3"/>
683 <w:LsdException Locked=3D"false" Priority=3D"48" Name=3D"Grid Table 3 A=
684 ccent 3"/>
685 <w:LsdException Locked=3D"false" Priority=3D"49" Name=3D"Grid Table 4 A=
686 ccent 3"/>
687 <w:LsdException Locked=3D"false" Priority=3D"50" Name=3D"Grid Table 5 D=
688 ark Accent 3"/>
689 <w:LsdException Locked=3D"false" Priority=3D"51" Name=3D"Grid Table 6 C=
690 olorful Accent 3"/>
691 <w:LsdException Locked=3D"false" Priority=3D"52" Name=3D"Grid Table 7 C=
692 olorful Accent 3"/>
693 <w:LsdException Locked=3D"false" Priority=3D"46" Name=3D"Grid Table 1 L=
694 ight Accent 4"/>
695 <w:LsdException Locked=3D"false" Priority=3D"47" Name=3D"Grid Table 2 A=
696 ccent 4"/>
697 <w:LsdException Locked=3D"false" Priority=3D"48" Name=3D"Grid Table 3 A=
698 ccent 4"/>
699 <w:LsdException Locked=3D"false" Priority=3D"49" Name=3D"Grid Table 4 A=
700 ccent 4"/>
701 <w:LsdException Locked=3D"false" Priority=3D"50" Name=3D"Grid Table 5 D=
702 ark Accent 4"/>
703 <w:LsdException Locked=3D"false" Priority=3D"51" Name=3D"Grid Table 6 C=
704 olorful Accent 4"/>
705 <w:LsdException Locked=3D"false" Priority=3D"52" Name=3D"Grid Table 7 C=
706 olorful Accent 4"/>
707 <w:LsdException Locked=3D"false" Priority=3D"46" Name=3D"Grid Table 1 L=
708 ight Accent 5"/>
709 <w:LsdException Locked=3D"false" Priority=3D"47" Name=3D"Grid Table 2 A=
710 ccent 5"/>
711 <w:LsdException Locked=3D"false" Priority=3D"48" Name=3D"Grid Table 3 A=
712 ccent 5"/>
713 <w:LsdException Locked=3D"false" Priority=3D"49" Name=3D"Grid Table 4 A=
714 ccent 5"/>
715 <w:LsdException Locked=3D"false" Priority=3D"50" Name=3D"Grid Table 5 D=
716 ark Accent 5"/>
717 <w:LsdException Locked=3D"false" Priority=3D"51" Name=3D"Grid Table 6 C=
718 olorful Accent 5"/>
719 <w:LsdException Locked=3D"false" Priority=3D"52" Name=3D"Grid Table 7 C=
720 olorful Accent 5"/>
721 <w:LsdException Locked=3D"false" Priority=3D"46" Name=3D"Grid Table 1 L=
722 ight Accent 6"/>
723 <w:LsdException Locked=3D"false" Priority=3D"47" Name=3D"Grid Table 2 A=
724 ccent 6"/>
725 <w:LsdException Locked=3D"false" Priority=3D"48" Name=3D"Grid Table 3 A=
726 ccent 6"/>
727 <w:LsdException Locked=3D"false" Priority=3D"49" Name=3D"Grid Table 4 A=
728 ccent 6"/>
729 <w:LsdException Locked=3D"false" Priority=3D"50" Name=3D"Grid Table 5 D=
730 ark Accent 6"/>
731 <w:LsdException Locked=3D"false" Priority=3D"51" Name=3D"Grid Table 6 C=
732 olorful Accent 6"/>
733 <w:LsdException Locked=3D"false" Priority=3D"52" Name=3D"Grid Table 7 C=
734 olorful Accent 6"/>
735 <w:LsdException Locked=3D"false" Priority=3D"46" Name=3D"List Table 1 L=
736 ight"/>
737 <w:LsdException Locked=3D"false" Priority=3D"47" Name=3D"List Table 2"/=
738 >
739 <w:LsdException Locked=3D"false" Priority=3D"48" Name=3D"List Table 3"/=
740 >
741 <w:LsdException Locked=3D"false" Priority=3D"49" Name=3D"List Table 4"/=
742 >
743 <w:LsdException Locked=3D"false" Priority=3D"50" Name=3D"List Table 5 D=
744 ark"/>
745 <w:LsdException Locked=3D"false" Priority=3D"51" Name=3D"List Table 6 C=
746 olorful"/>
747 <w:LsdException Locked=3D"false" Priority=3D"52" Name=3D"List Table 7 C=
748 olorful"/>
749 <w:LsdException Locked=3D"false" Priority=3D"46" Name=3D"List Table 1 L=
750 ight Accent 1"/>
751 <w:LsdException Locked=3D"false" Priority=3D"47" Name=3D"List Table 2 A=
752 ccent 1"/>
753 <w:LsdException Locked=3D"false" Priority=3D"48" Name=3D"List Table 3 A=
754 ccent 1"/>
755 <w:LsdException Locked=3D"false" Priority=3D"49" Name=3D"List Table 4 A=
756 ccent 1"/>
757 <w:LsdException Locked=3D"false" Priority=3D"50" Name=3D"List Table 5 D=
758 ark Accent 1"/>
759 <w:LsdException Locked=3D"false" Priority=3D"51" Name=3D"List Table 6 C=
760 olorful Accent 1"/>
761 <w:LsdException Locked=3D"false" Priority=3D"52" Name=3D"List Table 7 C=
762 olorful Accent 1"/>
763 <w:LsdException Locked=3D"false" Priority=3D"46" Name=3D"List Table 1 L=
764 ight Accent 2"/>
765 <w:LsdException Locked=3D"false" Priority=3D"47" Name=3D"List Table 2 A=
766 ccent 2"/>
767 <w:LsdException Locked=3D"false" Priority=3D"48" Name=3D"List Table 3 A=
768 ccent 2"/>
769 <w:LsdException Locked=3D"false" Priority=3D"49" Name=3D"List Table 4 A=
770 ccent 2"/>
771 <w:LsdException Locked=3D"false" Priority=3D"50" Name=3D"List Table 5 D=
772 ark Accent 2"/>
773 <w:LsdException Locked=3D"false" Priority=3D"51" Name=3D"List Table 6 C=
774 olorful Accent 2"/>
775 <w:LsdException Locked=3D"false" Priority=3D"52" Name=3D"List Table 7 C=
776 olorful Accent 2"/>
777 <w:LsdException Locked=3D"false" Priority=3D"46" Name=3D"List Table 1 L=
778 ight Accent 3"/>
779 <w:LsdException Locked=3D"false" Priority=3D"47" Name=3D"List Table 2 A=
780 ccent 3"/>
781 <w:LsdException Locked=3D"false" Priority=3D"48" Name=3D"List Table 3 A=
782 ccent 3"/>
783 <w:LsdException Locked=3D"false" Priority=3D"49" Name=3D"List Table 4 A=
784 ccent 3"/>
785 <w:LsdException Locked=3D"false" Priority=3D"50" Name=3D"List Table 5 D=
786 ark Accent 3"/>
787 <w:LsdException Locked=3D"false" Priority=3D"51" Name=3D"List Table 6 C=
788 olorful Accent 3"/>
789 <w:LsdException Locked=3D"false" Priority=3D"52" Name=3D"List Table 7 C=
790 olorful Accent 3"/>
791 <w:LsdException Locked=3D"false" Priority=3D"46" Name=3D"List Table 1 L=
792 ight Accent 4"/>
793 <w:LsdException Locked=3D"false" Priority=3D"47" Name=3D"List Table 2 A=
794 ccent 4"/>
795 <w:LsdException Locked=3D"false" Priority=3D"48" Name=3D"List Table 3 A=
796 ccent 4"/>
797 <w:LsdException Locked=3D"false" Priority=3D"49" Name=3D"List Table 4 A=
798 ccent 4"/>
799 <w:LsdException Locked=3D"false" Priority=3D"50" Name=3D"List Table 5 D=
800 ark Accent 4"/>
801 <w:LsdException Locked=3D"false" Priority=3D"51" Name=3D"List Table 6 C=
802 olorful Accent 4"/>
803 <w:LsdException Locked=3D"false" Priority=3D"52" Name=3D"List Table 7 C=
804 olorful Accent 4"/>
805 <w:LsdException Locked=3D"false" Priority=3D"46" Name=3D"List Table 1 L=
806 ight Accent 5"/>
807 <w:LsdException Locked=3D"false" Priority=3D"47" Name=3D"List Table 2 A=
808 ccent 5"/>
809 <w:LsdException Locked=3D"false" Priority=3D"48" Name=3D"List Table 3 A=
810 ccent 5"/>
811 <w:LsdException Locked=3D"false" Priority=3D"49" Name=3D"List Table 4 A=
812 ccent 5"/>
813 <w:LsdException Locked=3D"false" Priority=3D"50" Name=3D"List Table 5 D=
814 ark Accent 5"/>
815 <w:LsdException Locked=3D"false" Priority=3D"51" Name=3D"List Table 6 C=
816 olorful Accent 5"/>
817 <w:LsdException Locked=3D"false" Priority=3D"52" Name=3D"List Table 7 C=
818 olorful Accent 5"/>
819 <w:LsdException Locked=3D"false" Priority=3D"46" Name=3D"List Table 1 L=
820 ight Accent 6"/>
821 <w:LsdException Locked=3D"false" Priority=3D"47" Name=3D"List Table 2 A=
822 ccent 6"/>
823 <w:LsdException Locked=3D"false" Priority=3D"48" Name=3D"List Table 3 A=
824 ccent 6"/>
825 <w:LsdException Locked=3D"false" Priority=3D"49" Name=3D"List Table 4 A=
826 ccent 6"/>
827 <w:LsdException Locked=3D"false" Priority=3D"50" Name=3D"List Table 5 D=
828 ark Accent 6"/>
829 <w:LsdException Locked=3D"false" Priority=3D"51" Name=3D"List Table 6 C=
830 olorful Accent 6"/>
831 <w:LsdException Locked=3D"false" Priority=3D"52" Name=3D"List Table 7 C=
832 olorful Accent 6"/>
833 </w:LatentStyles>
834 </xml><![endif]--><style><!--
835 /* Font Definitions */
836 @font-face
837 {font-family:"Cambria Math";
838 panose-1:2 4 5 3 5 4 6 3 2 4;
839 mso-font-charset:0;
840 mso-generic-font-family:roman;
841 mso-font-pitch:variable;
842 mso-font-signature:-536870145 1107305727 0 0 415 0;}
843 @font-face
844 {font-family:Calibri;
845 panose-1:2 15 5 2 2 2 4 3 2 4;
846 mso-font-alt:"Times New Roman";
847 mso-font-charset:0;
848 mso-generic-font-family:swiss;
849 mso-font-pitch:variable;
850 mso-font-signature:-536870145 1073786111 1 0 415 0;}
851 /* Style Definitions */
852 p.MsoNormal, li.MsoNormal, div.MsoNormal
853 {mso-style-unhide:no;
854 mso-style-qformat:yes;
855 mso-style-parent:"";
856 margin:0in;
857 margin-bottom:.0001pt;
858 mso-pagination:widow-orphan;
859 font-size:11.0pt;
860 font-family:"Calibri",sans-serif;
861 mso-ascii-font-family:Calibri;
862 mso-ascii-theme-font:minor-latin;
863 mso-fareast-font-family:Calibri;
864 mso-fareast-theme-font:minor-latin;
865 mso-hansi-font-family:Calibri;
866 mso-hansi-theme-font:minor-latin;
867 mso-bidi-font-family:"Times New Roman";
868 mso-bidi-theme-font:minor-bidi;}
869 a:link, span.MsoHyperlink
870 {mso-style-noshow:yes;
871 mso-style-priority:99;
872 color:blue;
873 mso-themecolor:hyperlink;
874 text-decoration:underline;
875 text-underline:single;}
876 a:visited, span.MsoHyperlinkFollowed
877 {mso-style-noshow:yes;
878 mso-style-priority:99;
879 color:purple;
880 mso-themecolor:followedhyperlink;
881 text-decoration:underline;
882 text-underline:single;}
883 p.MsoPlainText, li.MsoPlainText, div.MsoPlainText
884 {mso-style-noshow:yes;
885 mso-style-priority:99;
886 mso-style-link:"Plain Text Char";
887 margin:0in;
888 margin-bottom:.0001pt;
889 mso-pagination:widow-orphan;
890 font-size:11.0pt;
891 mso-bidi-font-size:10.5pt;
892 font-family:"Calibri",sans-serif;
893 mso-fareast-font-family:Calibri;
894 mso-fareast-theme-font:minor-latin;
895 mso-bidi-font-family:"Times New Roman";
896 mso-bidi-theme-font:minor-bidi;}
897 span.PlainTextChar
898 {mso-style-name:"Plain Text Char";
899 mso-style-noshow:yes;
900 mso-style-priority:99;
901 mso-style-unhide:no;
902 mso-style-locked:yes;
903 mso-style-link:"Plain Text";
904 mso-bidi-font-size:10.5pt;
905 font-family:"Calibri",sans-serif;
906 mso-ascii-font-family:Calibri;
907 mso-hansi-font-family:Calibri;}
908 span.EmailStyle19
909 {mso-style-type:personal-compose;
910 mso-style-noshow:yes;
911 mso-style-unhide:no;}
912 .MsoChpDefault
913 {mso-style-type:export-only;
914 mso-default-props:yes;
915 font-size:10.0pt;
916 mso-ansi-font-size:10.0pt;
917 mso-bidi-font-size:10.0pt;
918 font-family:"Calibri",sans-serif;
919 mso-ascii-font-family:Calibri;
920 mso-ascii-theme-font:minor-latin;
921 mso-fareast-font-family:Calibri;
922 mso-fareast-theme-font:minor-latin;
923 mso-hansi-font-family:Calibri;
924 mso-hansi-theme-font:minor-latin;
925 mso-bidi-font-family:"Times New Roman";
926 mso-bidi-theme-font:minor-bidi;}
927 @page WordSection1
928 {size:8.5in 11.0in;
929 margin:1.0in 1.0in 1.0in 1.0in;
930 mso-header-margin:.5in;
931 mso-footer-margin:.5in;
932 mso-paper-source:0;}
933 div.WordSection1
934 {page:WordSection1;}
935 --></style><!--[if gte mso 10]><style>/* Style Definitions */
936 table.MsoNormalTable
937 {mso-style-name:"Table Normal";
938 mso-tstyle-rowband-size:0;
939 mso-tstyle-colband-size:0;
940 mso-style-noshow:yes;
941 mso-style-priority:99;
942 mso-style-parent:"";
943 mso-padding-alt:0in 5.4pt 0in 5.4pt;
944 mso-para-margin:0in;
945 mso-para-margin-bottom:.0001pt;
946 mso-pagination:widow-orphan;
947 font-size:10.0pt;
948 font-family:"Calibri",sans-serif;
949 mso-ascii-font-family:Calibri;
950 mso-ascii-theme-font:minor-latin;
951 mso-hansi-font-family:Calibri;
952 mso-hansi-theme-font:minor-latin;}
953 </style><![endif]--><!--[if gte mso 9]><xml>
954 <o:shapedefaults v:ext=3D"edit" spidmax=3D"1026" />
955 </xml><![endif]--><!--[if gte mso 9]><xml>
956 <o:shapelayout v:ext=3D"edit">
957 <o:idmap v:ext=3D"edit" data=3D"1" />
958 </o:shapelayout></xml><![endif]--></head><body lang=3DEN-US link=3Dblue=
959 vlink=3Dpurple style=3D'tab-interval:.5in'><div class=3DWordSection1><=
960 p class=3DMsoPlainText>Simple, unadorned test email generated by Outloo=
961 k 2010. It is in HTML format, but no special formatting has been chosen=
962 . I=E2=80=99m going to save this as a draft and then manually drop it i=
963 nto the Inbox for scraping by Redmine 3.0.2.<o:p></o:p></p></div></body=
964 ></html>
965
966 --Mark=_539924359269962179476--
@@ -0,0 +1,65
1 From: "John Smith" <jsmith@somenet.foo>
2 To: redmine <r@MYCOMPANYNAME.com>
3 Subject: Upgrade Redmine to 3.0.x
4 Thread-Topic: Upgrade Redmine to 3.0.x
5 Thread-Index: AQHQknBe94y5Or7Yl02JransMRF41p2Dv6Hu
6 Date: Tue, 19 May 2015 16:27:43 -0400
7 Message-ID: <A2D341A8808F024CAFA63F1287B9929CF1BC440F@EMBX01.exch.local>
8 Accept-Language: en-US
9 Content-Language: en-US
10 X-MS-Exchange-Organization-AuthAs: Internal
11 X-MS-Exchange-Organization-AuthMechanism: 04
12 X-MS-Exchange-Organization-AuthSource: EHUB01.exch.local
13 X-MS-Has-Attach:
14 X-MS-Exchange-Organization-SCL: -1
15 X-MS-TNEF-Correlator:
16 Content-Type: text/html; charset="iso-8859-1"
17 Content-Transfer-Encoding: quoted-printable
18 MIME-Version: 1.0
19
20 <html dir=3D"ltr">
21 <head>
22 <meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Diso-8859-=
23 1">
24 <style>=0A=
25 <!--=0A=
26 body=0A=
27 {font-family:Verdana,sans-serif;=0A=
28 font-size:0.8em;=0A=
29 color:#484848}=0A=
30 h1, h2, h3=0A=
31 {font-family:"Trebuchet MS",Verdana,sans-serif;=0A=
32 margin:0px}=0A=
33 h1=0A=
34 {font-size:1.2em}=0A=
35 h2, h3=0A=
36 {font-size:1.1em}=0A=
37 a, a:link, a:visited=0A=
38 {color:#2A5685}=0A=
39 a:hover, a:active=0A=
40 {color:#c61a1a}=0A=
41 fieldset.attachments=0A=
42 {border-width:1px 0 0 0}=0A=
43 hr=0A=
44 {width:100%;=0A=
45 height:1px;=0A=
46 background:#ccc;=0A=
47 border:0}=0A=
48 span.footer=0A=
49 {font-size:0.8em;=0A=
50 font-style:italic}=0A=
51 -->=0A=
52 </style><style id=3D"owaParaStyle" type=3D"text/css">P {margin-top:0;margin=
53 -bottom:0;}</style>
54 </head>
55 <body ocsi=3D"0" fpstyle=3D"1">
56 <div style=3D"direction: ltr;font-family: Tahoma;color: #000000;font-size: =
57 10pt;">A mess.<br>
58 <div><br>
59 <div style=3D"font-family:Tahoma; font-size:13px">--Geoff Maciolek<br>
60 MYCOMPANYNAME, LLC<br>
61 </div>
62 </div>
63 </div>
64 </body>
65 </html> No newline at end of file
@@ -0,0 +1,30
1 # Redmine - project management software
2 # Copyright (C) 2006-2015 Jean-Philippe Lang
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
18 require File.expand_path('../../../../../test_helper', __FILE__)
19
20 class Redmine::WikiFormatting::HtmlParserTest < ActiveSupport::TestCase
21
22 def setup
23 @parser = Redmine::WikiFormatting::HtmlParser
24 end
25
26 def test_convert_line_breaks
27 assert_equal "A html snippet with\na new line.",
28 @parser.to_text('<p>A html snippet with<br>a new line.</p>')
29 end
30 end
@@ -0,0 +1,30
1 # Redmine - project management software
2 # Copyright (C) 2006-2015 Jean-Philippe Lang
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
18 require File.expand_path('../../../../../test_helper', __FILE__)
19
20 class Redmine::WikiFormatting::MarkdownHtmlParserTest < ActiveSupport::TestCase
21
22 def setup
23 @parser = Redmine::WikiFormatting::Markdown::HtmlParser
24 end
25
26 def test_should_convert_tags
27 assert_equal 'A **simple** html snippet.',
28 @parser.to_text('<p>A <b>simple</b> html snippet.</p>')
29 end
30 end
@@ -0,0 +1,30
1 # Redmine - project management software
2 # Copyright (C) 2006-2015 Jean-Philippe Lang
3 #
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
18 require File.expand_path('../../../../../test_helper', __FILE__)
19
20 class Redmine::WikiFormatting::TextileHtmlParserTest < ActiveSupport::TestCase
21
22 def setup
23 @parser = Redmine::WikiFormatting::Textile::HtmlParser
24 end
25
26 def test_should_convert_tags
27 assert_equal 'A *simple* html snippet.',
28 @parser.to_text('<p>A <b>simple</b> html snippet.</p>')
29 end
30 end
@@ -13,6 +13,7 gem "mime-types"
13 13 gem "protected_attributes"
14 14 gem "actionpack-action_caching"
15 15 gem "actionpack-xml_parser"
16 gem "loofah", "~> 2.0"
16 17
17 18 # Windows does not include zoneinfo files, so bundle the tzinfo-data gem
18 19 gem 'tzinfo-data', platforms: [:mingw, :x64_mingw, :mswin, :jruby]
@@ -433,14 +433,11 class MailHandler < ActionMailer::Base
433 433 @plain_text_body = parts.map do |p|
434 434 body_charset = Mail::RubyVer.respond_to?(:pick_encoding) ?
435 435 Mail::RubyVer.pick_encoding(p.charset).to_s : p.charset
436 Redmine::CodesetUtil.to_utf8(p.body.decoded, body_charset)
437 end.join("\r\n")
438 436
439 # strip html tags and remove doctype directive
440 if parts.any? {|p| p.mime_type == 'text/html'}
441 @plain_text_body = strip_tags(@plain_text_body.strip)
442 @plain_text_body.sub! %r{^<!DOCTYPE .*$}, ''
443 end
437 body = Redmine::CodesetUtil.to_utf8(p.body.decoded, body_charset)
438 # convert html parts to text
439 p.mime_type == 'text/html' ? self.class.html_body_to_text(body) : body
440 end.join("\r\n")
444 441
445 442 @plain_text_body
446 443 end
@@ -454,6 +451,11 class MailHandler < ActionMailer::Base
454 451 subject.strip[0,255]
455 452 end
456 453
454 # Converts a HTML email body to text
455 def self.html_body_to_text(html)
456 Redmine::WikiFormatting.html_parser.to_text(html)
457 end
458
457 459 def self.assign_string_attribute_with_limit(object, attribute, value, limit=nil)
458 460 limit ||= object.class.columns_hash[attribute.to_s].limit || 255
459 461 value = value.to_s.slice(0, limit)
@@ -267,11 +267,8 Redmine::Search.map do |search|
267 267 end
268 268
269 269 Redmine::WikiFormatting.map do |format|
270 format.register :textile, Redmine::WikiFormatting::Textile::Formatter, Redmine::WikiFormatting::Textile::Helper
271 if Object.const_defined?(:Redcarpet)
272 format.register :markdown, Redmine::WikiFormatting::Markdown::Formatter, Redmine::WikiFormatting::Markdown::Helper,
273 :label => 'Markdown'
274 end
270 format.register :textile
271 format.register :markdown if Object.const_defined?(:Redcarpet)
275 272 end
276 273
277 274 ActionView::Template.register_template_handler :rsb, Redmine::Views::ApiTemplateHandler
@@ -28,12 +28,19 module Redmine
28 28 yield self
29 29 end
30 30
31 def register(name, formatter, helper, options={})
31 def register(name, *args)
32 options = args.last.is_a?(Hash) ? args.pop : {}
32 33 name = name.to_s
33 34 raise ArgumentError, "format name '#{name}' is already taken" if @@formatters[name]
35
36 formatter, helper, parser = args.any? ?
37 args :
38 %w(Formatter Helper HtmlParser).map {|m| "Redmine::WikiFormatting::#{name.classify}::#{m}".constantize}
39
34 40 @@formatters[name] = {
35 41 :formatter => formatter,
36 42 :helper => helper,
43 :html_parser => parser,
37 44 :label => options[:label] || name.humanize
38 45 }
39 46 end
@@ -42,6 +49,10 module Redmine
42 49 formatter_for(Setting.text_formatting)
43 50 end
44 51
52 def html_parser
53 html_parser_for(Setting.text_formatting)
54 end
55
45 56 def formatter_for(name)
46 57 entry = @@formatters[name.to_s]
47 58 (entry && entry[:formatter]) || Redmine::WikiFormatting::NullFormatter::Formatter
@@ -52,6 +63,11 module Redmine
52 63 (entry && entry[:helper]) || Redmine::WikiFormatting::NullFormatter::Helper
53 64 end
54 65
66 def html_parser_for(name)
67 entry = @@formatters[name.to_s]
68 (entry && entry[:html_parser]) || Redmine::WikiFormatting::HtmlParser
69 end
70
55 71 def format_names
56 72 @@formatters.keys.map
57 73 end
@@ -15,8 +15,9 Content-Transfer-Encoding: 7bit
15 15 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
16 16 <html>
17 17 <head>
18 <style>p {font-size:12.0pt;}</style>
18 19 </head>
19 20 <body bgcolor="#ffffff" text="#000000">
20 This is a <b>html-only</b> email.<br>
21 This is a <b>html-only</b> email.<br><h1>With a title</h1><p>and a paragraph.</p>
21 22 </body>
22 23 </html>
@@ -797,13 +797,33 class MailHandlerTest < ActiveSupport::TestCase
797 797 assert_equal Message.find(1), m.parent
798 798 end
799 799
800 def test_should_strip_tags_of_html_only_emails
801 issue = submit_email('ticket_html_only.eml', :issue => {:project => 'ecookbook'})
800 def test_should_convert_tags_of_html_only_emails
801 with_settings :text_formatting => 'textile' do
802 issue = submit_email('ticket_html_only.eml', :issue => {:project => 'ecookbook'})
803 assert issue.is_a?(Issue)
804 assert !issue.new_record?
805 issue.reload
806 assert_equal 'HTML email', issue.subject
807 assert_equal "This is a *html-only* email.\r\n\r\nh1. With a title\r\n\r\nand a paragraph.", issue.description
808 end
809 end
810
811 def test_should_handle_outlook_web_access_2010_html_only
812 issue = submit_email('outlook_web_access_2010_html_only.eml', :issue => {:project => 'ecookbook'})
813 assert issue.is_a?(Issue)
814 issue.reload
815 assert_equal 'Upgrade Redmine to 3.0.x', issue.subject
816 assert_equal "A mess.\r\n\r\n--Geoff Maciolek\r\nMYCOMPANYNAME, LLC", issue.description
817 end
818
819 def test_should_handle_outlook_2010_html_only
820 issue = submit_email('outlook_2010_html_only.eml', :issue => {:project => 'ecookbook'})
802 821 assert issue.is_a?(Issue)
803 assert !issue.new_record?
804 822 issue.reload
805 assert_equal 'HTML email', issue.subject
806 assert_equal 'This is a html-only email.', issue.description
823 assert_equal 'Test email', issue.subject
824 assert_equal "Simple, unadorned test email generated by Outlook 2010. It is in HTML format, but" +
825 " no special formatting has been chosen. I’m going to save this as a draft and then manually" +
826 " drop it into the Inbox for scraping by Redmine 3.0.2.", issue.description
807 827 end
808 828
809 829 test "truncate emails with no setting should add the entire email into the issue" do
General Comments 0
You need to be logged in to leave comments. Login now