eric6/QScintilla/MarkupProviders/HtmlProvider.py

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

eric ide

mercurial