src/eric7/QScintilla/MarkupProviders/HtmlProvider.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9482
a2bc06a54d9d
equal deleted inserted replaced
9220:e9e7eca7efee 9221:bf71ee032bb4
15 15
16 class HtmlProvider(MarkupBase): 16 class HtmlProvider(MarkupBase):
17 """ 17 """
18 Class implementing the HTML markup provider. 18 Class implementing the HTML markup provider.
19 """ 19 """
20
20 def __init__(self): 21 def __init__(self):
21 """ 22 """
22 Constructor 23 Constructor
23 """ 24 """
24 super().__init__() 25 super().__init__()
25 26
26 def kind(self): 27 def kind(self):
27 """ 28 """
28 Public method to get the markup kind. 29 Public method to get the markup kind.
29 30
30 @return string with markup kind 31 @return string with markup kind
31 @rtype str 32 @rtype str
32 """ 33 """
33 return "html" 34 return "html"
34 35
35 def hasBold(self): 36 def hasBold(self):
36 """ 37 """
37 Public method to indicate the availability of bold markup. 38 Public method to indicate the availability of bold markup.
38 39
39 @return flag indicating the availability of bold markup 40 @return flag indicating the availability of bold markup
40 @rtype bool 41 @rtype bool
41 """ 42 """
42 return True 43 return True
43 44
44 def bold(self, editor): 45 def bold(self, editor):
45 """ 46 """
46 Public method to generate bold text. 47 Public method to generate bold text.
47 48
48 @param editor reference to the editor to work on 49 @param editor reference to the editor to work on
49 @type Editor 50 @type Editor
50 """ 51 """
51 self.__insertMarkup("b", editor) 52 self.__insertMarkup("b", editor)
52 53
53 def hasItalic(self): 54 def hasItalic(self):
54 """ 55 """
55 Public method to indicate the availability of italic markup. 56 Public method to indicate the availability of italic markup.
56 57
57 @return flag indicating the availability of italic markup 58 @return flag indicating the availability of italic markup
58 @rtype bool 59 @rtype bool
59 """ 60 """
60 return True 61 return True
61 62
62 def italic(self, editor): 63 def italic(self, editor):
63 """ 64 """
64 Public method to generate italic text. 65 Public method to generate italic text.
65 66
66 @param editor reference to the editor to work on 67 @param editor reference to the editor to work on
67 @type Editor 68 @type Editor
68 """ 69 """
69 self.__insertMarkup("i", editor) 70 self.__insertMarkup("i", editor)
70 71
71 def hasStrikethrough(self): 72 def hasStrikethrough(self):
72 """ 73 """
73 Public method to indicate the availability of strikethrough markup. 74 Public method to indicate the availability of strikethrough markup.
74 75
75 @return flag indicating the availability of strikethrough markup 76 @return flag indicating the availability of strikethrough markup
76 @rtype bool 77 @rtype bool
77 """ 78 """
78 return True 79 return True
79 80
80 def strikethrough(self, editor): 81 def strikethrough(self, editor):
81 """ 82 """
82 Public method to generate strikethrough text. 83 Public method to generate strikethrough text.
83 84
84 @param editor reference to the editor to work on 85 @param editor reference to the editor to work on
85 @type Editor 86 @type Editor
86 """ 87 """
87 self.__insertMarkup("del", editor) 88 self.__insertMarkup("del", editor)
88 89
89 def headerLevels(self): 90 def headerLevels(self):
90 """ 91 """
91 Public method to determine the available header levels. 92 Public method to determine the available header levels.
92 93
93 @return supported header levels 94 @return supported header levels
94 @rtype int 95 @rtype int
95 """ 96 """
96 return 6 97 return 6
97 98
98 def header(self, editor, level): 99 def header(self, editor, level):
99 """ 100 """
100 Public method to generate a header. 101 Public method to generate a header.
101 102
102 @param editor reference to the editor to work on 103 @param editor reference to the editor to work on
103 @type Editor 104 @type Editor
104 @param level header level 105 @param level header level
105 @type int 106 @type int
106 """ 107 """
107 if level <= 6: 108 if level <= 6:
108 self.__insertMarkup("h{0}".format(level), editor) 109 self.__insertMarkup("h{0}".format(level), editor)
109 110
110 def hasCode(self): 111 def hasCode(self):
111 """ 112 """
112 Public method to indicate the availability of inline code markup. 113 Public method to indicate the availability of inline code markup.
113 114
114 @return flag indicating the availability of inline code markup 115 @return flag indicating the availability of inline code markup
115 @rtype bool 116 @rtype bool
116 """ 117 """
117 return True 118 return True
118 119
119 def code(self, editor): 120 def code(self, editor):
120 """ 121 """
121 Public method to generate inline code text. 122 Public method to generate inline code text.
122 123
123 @param editor reference to the editor to work on 124 @param editor reference to the editor to work on
124 @type Editor 125 @type Editor
125 """ 126 """
126 self.__insertMarkup("code", editor) 127 self.__insertMarkup("code", editor)
127 128
128 def hasCodeBlock(self): 129 def hasCodeBlock(self):
129 """ 130 """
130 Public method to indicate the availability of code block markup. 131 Public method to indicate the availability of code block markup.
131 132
132 @return flag indicating the availability of code block markup 133 @return flag indicating the availability of code block markup
133 @rtype bool 134 @rtype bool
134 """ 135 """
135 return True 136 return True
136 137
137 def codeBlock(self, editor): 138 def codeBlock(self, editor):
138 """ 139 """
139 Public method to generate code block text. 140 Public method to generate code block text.
140 141
141 @param editor reference to the editor to work on 142 @param editor reference to the editor to work on
142 @type Editor 143 @type Editor
143 """ 144 """
144 if editor is None: 145 if editor is None:
145 return 146 return
146 147
147 lineSeparator = editor.getLineSeparator() 148 lineSeparator = editor.getLineSeparator()
148 editor.beginUndoAction() 149 editor.beginUndoAction()
149 if editor.hasSelectedText(): 150 if editor.hasSelectedText():
150 newText = "<pre><code>{0}{1}</code></pre>{0}".format( 151 newText = "<pre><code>{0}{1}</code></pre>{0}".format(
151 lineSeparator, editor.selectedText()) 152 lineSeparator, editor.selectedText()
153 )
152 editor.replaceSelectedText(newText) 154 editor.replaceSelectedText(newText)
153 else: 155 else:
154 editor.insert("<pre><code>{0}{0}</code></pre>{0}".format( 156 editor.insert("<pre><code>{0}{0}</code></pre>{0}".format(lineSeparator))
155 lineSeparator))
156 cline, cindex = editor.getCursorPosition() 157 cline, cindex = editor.getCursorPosition()
157 editor.setCursorPosition(cline + 1, 0) 158 editor.setCursorPosition(cline + 1, 0)
158 editor.endUndoAction() 159 editor.endUndoAction()
159 160
160 def __insertMarkup(self, markup, editor, addEol=False): 161 def __insertMarkup(self, markup, editor, addEol=False):
161 """ 162 """
162 Private method to insert the specified markup. 163 Private method to insert the specified markup.
163 164
164 If the editor has selected text, this text is enclosed by the given 165 If the editor has selected text, this text is enclosed by the given
165 markup. If no text is selected, the markup is inserted at the cursor 166 markup. If no text is selected, the markup is inserted at the cursor
166 position and the cursor is positioned in between. 167 position and the cursor is positioned in between.
167 168
168 @param markup markup string to be inserted 169 @param markup markup string to be inserted
169 @type str 170 @type str
170 @param editor reference to the editor to work on 171 @param editor reference to the editor to work on
171 @type Editor 172 @type Editor
172 @param addEol flag indicating to add an eol string after the tag 173 @param addEol flag indicating to add an eol string after the tag
173 @type bool 174 @type bool
174 """ 175 """
175 if editor is None: 176 if editor is None:
176 return 177 return
177 178
178 lineSeparator = editor.getLineSeparator() if addEol else "" 179 lineSeparator = editor.getLineSeparator() if addEol else ""
179 editor.beginUndoAction() 180 editor.beginUndoAction()
180 if editor.hasSelectedText(): 181 if editor.hasSelectedText():
181 newText = "<{0}>{2}{1}</{0}>{2}".format( 182 newText = "<{0}>{2}{1}</{0}>{2}".format(
182 markup, editor.selectedText(), lineSeparator) 183 markup, editor.selectedText(), lineSeparator
184 )
183 editor.replaceSelectedText(newText) 185 editor.replaceSelectedText(newText)
184 else: 186 else:
185 editor.insert("<{0}>{1}{1}</{0}>{1}".format(markup, lineSeparator)) 187 editor.insert("<{0}>{1}{1}</{0}>{1}".format(markup, lineSeparator))
186 cline, cindex = editor.getCursorPosition() 188 cline, cindex = editor.getCursorPosition()
187 if addEol: 189 if addEol:
188 editor.setCursorPosition(cline + 1, 0) 190 editor.setCursorPosition(cline + 1, 0)
189 else: 191 else:
190 editor.setCursorPosition(cline, cindex + len(markup) + 2) 192 editor.setCursorPosition(cline, cindex + len(markup) + 2)
191 editor.endUndoAction() 193 editor.endUndoAction()
192 194
193 def hasHyperlink(self): 195 def hasHyperlink(self):
194 """ 196 """
195 Public method to indicate the availability of hyperlink markup. 197 Public method to indicate the availability of hyperlink markup.
196 198
197 @return flag indicating the availability of hyperlink markup 199 @return flag indicating the availability of hyperlink markup
198 @rtype bool 200 @rtype bool
199 """ 201 """
200 return True 202 return True
201 203
202 def hyperlink(self, editor): 204 def hyperlink(self, editor):
203 """ 205 """
204 Public method to generate hyperlink text. 206 Public method to generate hyperlink text.
205 207
206 @param editor reference to the editor to work on 208 @param editor reference to the editor to work on
207 @type Editor 209 @type Editor
208 """ 210 """
209 if editor is None: 211 if editor is None:
210 return 212 return
211 213
212 from .HyperlinkMarkupDialog import HyperlinkMarkupDialog 214 from .HyperlinkMarkupDialog import HyperlinkMarkupDialog
215
213 dlg = HyperlinkMarkupDialog(True, False) 216 dlg = HyperlinkMarkupDialog(True, False)
214 if dlg.exec() == QDialog.DialogCode.Accepted: 217 if dlg.exec() == QDialog.DialogCode.Accepted:
215 text, target, title = dlg.getData() 218 text, target, title = dlg.getData()
216 if not text: 219 if not text:
217 text = target 220 text = target
218 221
219 if title: 222 if title:
220 link = '<a href="{0}" title="{2}">{1}</a>'.format( 223 link = '<a href="{0}" title="{2}">{1}</a>'.format(target, text, title)
221 target, text, title)
222 else: 224 else:
223 link = '<a href="{0}">{1}</a>'.format(target, text) 225 link = '<a href="{0}">{1}</a>'.format(target, text)
224 226
225 editor.beginUndoAction() 227 editor.beginUndoAction()
226 cline, cindex = editor.getCursorPosition() 228 cline, cindex = editor.getCursorPosition()
227 editor.insert(link) 229 editor.insert(link)
228 editor.setCursorPosition(cline, cindex + len(link)) 230 editor.setCursorPosition(cline, cindex + len(link))
229 editor.endUndoAction() 231 editor.endUndoAction()
230 232
231 def hasLine(self): 233 def hasLine(self):
232 """ 234 """
233 Public method to indicate the availability of a horizontal line markup. 235 Public method to indicate the availability of a horizontal line markup.
234 236
235 @return flag indicating the availability of a horizontal line markup 237 @return flag indicating the availability of a horizontal line markup
236 @rtype bool 238 @rtype bool
237 """ 239 """
238 return True 240 return True
239 241
240 def line(self, editor): 242 def line(self, editor):
241 """ 243 """
242 Public method to generate a horizontal line text. 244 Public method to generate a horizontal line text.
243 245
244 @param editor reference to the editor to work on 246 @param editor reference to the editor to work on
245 @type Editor 247 @type Editor
246 """ 248 """
247 if editor is None: 249 if editor is None:
248 return 250 return
249 251
250 editor.beginUndoAction() 252 editor.beginUndoAction()
251 markup = "<hr />" 253 markup = "<hr />"
252 editor.insert(markup) 254 editor.insert(markup)
253 cline, cindex = editor.getCursorPosition() 255 cline, cindex = editor.getCursorPosition()
254 editor.setCursorPosition(cline, cindex + len(markup)) 256 editor.setCursorPosition(cline, cindex + len(markup))
255 editor.endUndoAction() 257 editor.endUndoAction()
256 258
257 def hasQuote(self): 259 def hasQuote(self):
258 """ 260 """
259 Public method to indicate the availability of block quote markup. 261 Public method to indicate the availability of block quote markup.
260 262
261 @return flag indicating the availability of block quote markup 263 @return flag indicating the availability of block quote markup
262 @rtype bool 264 @rtype bool
263 """ 265 """
264 return True 266 return True
265 267
266 def quote(self, editor): 268 def quote(self, editor):
267 """ 269 """
268 Public method to generate block quote text. 270 Public method to generate block quote text.
269 271
270 @param editor reference to the editor to work on 272 @param editor reference to the editor to work on
271 @type Editor 273 @type Editor
272 """ 274 """
273 self.__insertMarkup("blockquote", editor, True) 275 self.__insertMarkup("blockquote", editor, True)
274 276
275 def hasImage(self): 277 def hasImage(self):
276 """ 278 """
277 Public method to indicate the availability of image markup. 279 Public method to indicate the availability of image markup.
278 280
279 @return flag indicating the availability of image markup 281 @return flag indicating the availability of image markup
280 @rtype bool 282 @rtype bool
281 """ 283 """
282 return True 284 return True
283 285
284 def image(self, editor): 286 def image(self, editor):
285 """ 287 """
286 Public method to generate image text. 288 Public method to generate image text.
287 289
288 @param editor reference to the editor to work on 290 @param editor reference to the editor to work on
289 @type Editor 291 @type Editor
290 """ 292 """
291 if editor is None: 293 if editor is None:
292 return 294 return
293 295
294 from .ImageMarkupDialog import ImageMarkupDialog 296 from .ImageMarkupDialog import ImageMarkupDialog
297
295 dlg = ImageMarkupDialog(ImageMarkupDialog.HtmlMode) 298 dlg = ImageMarkupDialog(ImageMarkupDialog.HtmlMode)
296 if dlg.exec() == QDialog.DialogCode.Accepted: 299 if dlg.exec() == QDialog.DialogCode.Accepted:
297 address, altText, title, originalSize, width, height = ( 300 address, altText, title, originalSize, width, height = dlg.getData()
298 dlg.getData() 301
299 )
300
301 markup = '<img src="{0}"'.format(address) 302 markup = '<img src="{0}"'.format(address)
302 if altText: 303 if altText:
303 markup = '{0} alt="{1}"'.format(markup, altText) 304 markup = '{0} alt="{1}"'.format(markup, altText)
304 if title: 305 if title:
305 markup = '{0} title="{1}"'.format(markup, title) 306 markup = '{0} title="{1}"'.format(markup, title)
306 if not originalSize: 307 if not originalSize:
307 markup = '{0} width="{1}" height="{2}"'.format( 308 markup = '{0} width="{1}" height="{2}"'.format(markup, width, height)
308 markup, width, height) 309 markup = "{0} />".format(markup)
309 markup = '{0} />'.format(markup) 310
310
311 editor.beginUndoAction() 311 editor.beginUndoAction()
312 editor.insert(markup) 312 editor.insert(markup)
313 cline, cindex = editor.getCursorPosition() 313 cline, cindex = editor.getCursorPosition()
314 editor.setCursorPosition(cline, cindex + len(markup)) 314 editor.setCursorPosition(cline, cindex + len(markup))
315 editor.endUndoAction() 315 editor.endUndoAction()
316 316
317 def hasBulletedList(self): 317 def hasBulletedList(self):
318 """ 318 """
319 Public method to indicate the availability of bulleted list markup. 319 Public method to indicate the availability of bulleted list markup.
320 320
321 @return flag indicating the availability of bulleted list markup 321 @return flag indicating the availability of bulleted list markup
322 @rtype bool 322 @rtype bool
323 """ 323 """
324 return True 324 return True
325 325
326 def bulletedList(self, editor): 326 def bulletedList(self, editor):
327 """ 327 """
328 Public method to generate bulleted list text. 328 Public method to generate bulleted list text.
329 329
330 @param editor reference to the editor to work on 330 @param editor reference to the editor to work on
331 @type Editor 331 @type Editor
332 """ 332 """
333 self.__makeList(editor, "ul") 333 self.__makeList(editor, "ul")
334 334
335 def hasNumberedList(self): 335 def hasNumberedList(self):
336 """ 336 """
337 Public method to indicate the availability of numbered list markup. 337 Public method to indicate the availability of numbered list markup.
338 338
339 @return flag indicating the availability of numbered list markup 339 @return flag indicating the availability of numbered list markup
340 @rtype bool 340 @rtype bool
341 """ 341 """
342 return True 342 return True
343 343
344 def numberedList(self, editor): 344 def numberedList(self, editor):
345 """ 345 """
346 Public method to generate numbered list text. 346 Public method to generate numbered list text.
347 347
348 @param editor reference to the editor to work on 348 @param editor reference to the editor to work on
349 @type Editor 349 @type Editor
350 """ 350 """
351 self.__makeList(editor, "ol") 351 self.__makeList(editor, "ol")
352 352
353 def __makeList(self, editor, listType): 353 def __makeList(self, editor, listType):
354 """ 354 """
355 Private method to generate the desired list markup. 355 Private method to generate the desired list markup.
356 356
357 @param editor reference to the editor to work on 357 @param editor reference to the editor to work on
358 @type Editor 358 @type Editor
359 @param listType type of the desired list (should be ul or ol) 359 @param listType type of the desired list (should be ul or ol)
360 @type str 360 @type str
361 """ 361 """
362 if editor is None: 362 if editor is None:
363 return 363 return
364 364
365 lineSeparator = editor.getLineSeparator() 365 lineSeparator = editor.getLineSeparator()
366 editor.beginUndoAction() 366 editor.beginUndoAction()
367 if editor.hasSelectedText(): 367 if editor.hasSelectedText():
368 startLine, startIndex, endLine, endIndex = ( 368 startLine, startIndex, endLine, endIndex = editor.getSelection()
369 editor.getSelection()
370 )
371 if endIndex == 0: 369 if endIndex == 0:
372 endLine -= 1 370 endLine -= 1
373 for line in range(startLine, endLine + 1): 371 for line in range(startLine, endLine + 1):
374 editor.insertAt("</li>", line, len(editor.text(line).rstrip())) 372 editor.insertAt("</li>", line, len(editor.text(line).rstrip()))
375 editor.insertAt(" <li>", line, 0) 373 editor.insertAt(" <li>", line, 0)
376 if line == editor.lines() - 1: 374 if line == editor.lines() - 1:
377 editor.insertAt(lineSeparator, line, 1000) 375 editor.insertAt(lineSeparator, line, 1000)
378 editor.insertAt("</{1}>{0}".format(lineSeparator, listType), 376 editor.insertAt("</{1}>{0}".format(lineSeparator, listType), endLine + 1, 0)
379 endLine + 1, 0) 377 editor.insertAt("<{1}>{0}".format(lineSeparator, listType), startLine, 0)
380 editor.insertAt("<{1}>{0}".format(lineSeparator, listType),
381 startLine, 0)
382 editor.setCursorPosition(endLine + 3, 0) 378 editor.setCursorPosition(endLine + 3, 0)
383 else: 379 else:
384 listElements, ok = QInputDialog.getInt( 380 listElements, ok = QInputDialog.getInt(
385 None, 381 None,
382 QCoreApplication.translate("HtmlProvider", "Create List"),
386 QCoreApplication.translate( 383 QCoreApplication.translate(
387 "HtmlProvider", "Create List"), 384 "HtmlProvider", "Enter desired number of list elements:"
388 QCoreApplication.translate( 385 ),
389 "HtmlProvider", "Enter desired number of list elements:"), 386 0,
390 0, 0, 99, 1) 387 0,
388 99,
389 1,
390 )
391 if ok: 391 if ok:
392 if listElements == 0: 392 if listElements == 0:
393 listElements = 1 393 listElements = 1
394 cline, cindex = editor.getCursorPosition() 394 cline, cindex = editor.getCursorPosition()
395 listBody = ( 395 listBody = listElements * " <li></li>{0}".format(lineSeparator)
396 listElements * " <li></li>{0}".format(lineSeparator) 396 markup = "<{1}>{0}{2}</{1}>{0}".format(
397 lineSeparator, listType, listBody
397 ) 398 )
398 markup = "<{1}>{0}{2}</{1}>{0}".format(
399 lineSeparator, listType, listBody)
400 if cindex == 0: 399 if cindex == 0:
401 editor.insertAt(markup, cline, cindex) 400 editor.insertAt(markup, cline, cindex)
402 editor.setCursorPosition(cline + 1, 6) 401 editor.setCursorPosition(cline + 1, 6)
403 else: 402 else:
404 if cline == editor.lines() - 1: 403 if cline == editor.lines() - 1:

eric ide

mercurial