mirror of
https://github.com/olivierkes/manuskript.git
synced 2024-05-17 11:22:28 +12:00
Purging some remaining t2tfiles
This commit is contained in:
parent
7e954eab5e
commit
47d87115e6
19
manuskript/ui/editors/MDFunctions.py
Normal file
19
manuskript/ui/editors/MDFunctions.py
Normal file
|
@ -0,0 +1,19 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import re
|
||||
|
||||
from PyQt5.QtCore import QRegExp
|
||||
from PyQt5.QtGui import QTextCursor
|
||||
|
||||
|
||||
def MDFormatSelection(editor, style):
|
||||
"""
|
||||
Formats the current selection of ``editor`` in the format given by ``style``,
|
||||
style being:
|
||||
0: bold
|
||||
1: italic
|
||||
2: code
|
||||
"""
|
||||
print("Formatting:", style, " (Unimplemented yet !)")
|
||||
# FIXME
|
|
@ -1,376 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import re
|
||||
|
||||
from PyQt5.QtCore import QRegExp
|
||||
from PyQt5.QtGui import QTextCursor
|
||||
|
||||
|
||||
def t2tFormatSelection(editor, style):
|
||||
"""
|
||||
Formats the current selection of ``editor`` in the format given by ``style``,
|
||||
style being:
|
||||
0: bold
|
||||
1: italic
|
||||
2: underline
|
||||
3: strike
|
||||
4: code
|
||||
5: tagged
|
||||
"""
|
||||
print("Formatting:", style)
|
||||
formatChar = "*/_-`'"[style]
|
||||
|
||||
# FIXME: doesn't work if selection spans over several blocks.
|
||||
|
||||
cursor = editor.textCursor()
|
||||
cursor.beginEditBlock()
|
||||
|
||||
if cursor.hasSelection():
|
||||
pass
|
||||
else:
|
||||
# If no selection, selects the word in which the cursor is now
|
||||
cursor.movePosition(QTextCursor.StartOfWord,
|
||||
QTextCursor.MoveAnchor)
|
||||
cursor.movePosition(QTextCursor.EndOfWord,
|
||||
QTextCursor.KeepAnchor)
|
||||
|
||||
if not cursor.hasSelection():
|
||||
# No selection means we are outside a word,
|
||||
# so we insert markup and put cursor in the middle
|
||||
cursor.insertText(formatChar * 4)
|
||||
cursor.setPosition(cursor.position() - 2)
|
||||
cursor.endEditBlock()
|
||||
editor.setTextCursor(cursor)
|
||||
# And we are done
|
||||
return
|
||||
|
||||
# Get start and end of selection
|
||||
start = cursor.selectionStart() - cursor.block().position()
|
||||
end = cursor.selectionEnd() - cursor.block().position()
|
||||
if start > end:
|
||||
start, end = end, start
|
||||
|
||||
# Whole block
|
||||
text = cursor.block().text()
|
||||
|
||||
# Adjusts selection to exclude the markup
|
||||
while text[start:start + 1] == formatChar:
|
||||
start += 1
|
||||
while text[end - 1:end] == formatChar:
|
||||
end -= 1
|
||||
|
||||
# Get the text without formatting, and the array of format
|
||||
fText, fArray = textToFormatArrayNoMarkup(text)
|
||||
# Get the translated start and end of selection in the unformated text
|
||||
tStart, tEnd = translateSelectionToUnformattedText(text, start, end)
|
||||
|
||||
# We want only the array that contains the propper formatting
|
||||
propperArray = fArray[style]
|
||||
|
||||
if 0 in propperArray[tStart:tEnd]:
|
||||
# have some unformated text in the selection, so we format the
|
||||
# whole selection
|
||||
propperArray = propperArray[:tStart] + [1] * \
|
||||
(tEnd - tStart) + propperArray[tEnd:]
|
||||
else:
|
||||
# The whole selection is already formatted, so we remove the
|
||||
# formatting
|
||||
propperArray = propperArray[:tStart] + [0] * \
|
||||
(tEnd - tStart) + propperArray[tEnd:]
|
||||
|
||||
fArray = fArray[0:style] + [propperArray] + fArray[style + 1:]
|
||||
|
||||
text = reformatText(fText, fArray)
|
||||
|
||||
# Replaces the whole block
|
||||
cursor.movePosition(QTextCursor.StartOfBlock)
|
||||
cursor.movePosition(QTextCursor.EndOfBlock,
|
||||
QTextCursor.KeepAnchor)
|
||||
cursor.insertText(text)
|
||||
|
||||
cursor.setPosition(end + cursor.block().position())
|
||||
|
||||
cursor.endEditBlock()
|
||||
|
||||
editor.setTextCursor(cursor)
|
||||
|
||||
|
||||
def t2tClearFormat(editor):
|
||||
"""Clears format on ``editor``'s current selection."""
|
||||
|
||||
cursor = editor.textCursor()
|
||||
cursor.beginEditBlock()
|
||||
|
||||
text = cursor.selectedText()
|
||||
t, a = textToFormatArrayNoMarkup(text)
|
||||
|
||||
cursor.insertText(t)
|
||||
cursor.endEditBlock()
|
||||
editor.setTextCursor(cursor)
|
||||
|
||||
|
||||
def textToFormatArray(text):
|
||||
"""
|
||||
Take some text and returns an array of array containing informations
|
||||
about how the text is formatted:
|
||||
r = [ [0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0],
|
||||
[0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1],
|
||||
...
|
||||
]
|
||||
Each sub-array is for one of the beautifier:
|
||||
0: bold
|
||||
1: italic
|
||||
2: underline
|
||||
3: strike
|
||||
4: code
|
||||
5: tagged
|
||||
|
||||
Each sub-array contains an element for each character of the text, with the
|
||||
value 1 if it is formatted in the specific format, -1 if it is markup, and
|
||||
0 otherwise.
|
||||
|
||||
removeMarks returns a both the array and a string, in which all of the
|
||||
formatting marks have been removed.
|
||||
"""
|
||||
|
||||
result = []
|
||||
|
||||
for markup in ["\*", "/", "_", "-", "`", "\'"]:
|
||||
|
||||
rList = []
|
||||
|
||||
r = QRegExp(r'(' + markup * 2 + ')(.+)(' + markup * 2 + ')')
|
||||
r.setMinimal(True)
|
||||
pos = r.indexIn(text, 0)
|
||||
lastPos = 0
|
||||
while pos >= 0:
|
||||
# We have a winner
|
||||
rList += [0] * (pos - lastPos)
|
||||
rList += [2] * 2
|
||||
rList += [1] * len(r.cap(2))
|
||||
rList += [2] * 2
|
||||
lastPos = pos + len(r.cap(0))
|
||||
pos = r.indexIn(text, len(rList))
|
||||
|
||||
if len(rList) < len(text):
|
||||
rList += [0] * (len(text) - len(rList))
|
||||
|
||||
result.append(rList)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def textToFormatArrayNoMarkup(text):
|
||||
"""
|
||||
Same as textToFormatArray, except that it removes all the markup from the
|
||||
text and returns two elements:
|
||||
the array
|
||||
the text without markup
|
||||
"""
|
||||
|
||||
r = textToFormatArray(text)
|
||||
result = [[], [], [], [], [], []]
|
||||
rText = ""
|
||||
|
||||
for i in range(len(text)):
|
||||
t = max([k[i] for k in r]) # kind of flattens all the format array
|
||||
if t != 2:
|
||||
rText += text[i]
|
||||
[result[k].append(r[k][i]) for k in range(len(r))]
|
||||
|
||||
return rText, result
|
||||
|
||||
|
||||
def translateSelectionToUnformattedText(text, start, end):
|
||||
"""
|
||||
Translate the start / end of selection from a formatted text to an
|
||||
unformatted one.
|
||||
"""
|
||||
r = textToFormatArray(text)
|
||||
|
||||
rStart, rEnd = start, end
|
||||
|
||||
for i in range(len(text)):
|
||||
t = max([k[i] for k in r]) # kind of flattens all the format array
|
||||
if t == 2: # t == 2 means this character is markup
|
||||
if i <= start: rStart -= 1
|
||||
if i < end: rEnd -= 1
|
||||
|
||||
return rStart, rEnd
|
||||
|
||||
|
||||
def translateSelectionToFormattedText(text, start, end):
|
||||
"""
|
||||
Translate the start / end of selection from a formatted text to an
|
||||
unformatted one.
|
||||
"""
|
||||
r = textToFormatArray(text)
|
||||
|
||||
rStart, rEnd = start, end
|
||||
|
||||
for i in range(len(text)):
|
||||
t = max([k[i] for k in r]) # kind of flattens all the format array
|
||||
if t == 2: # t == 2 means this character is markup
|
||||
if i <= start: rStart -= 1
|
||||
if i < end: rEnd -= 1
|
||||
|
||||
return rStart, rEnd
|
||||
|
||||
|
||||
def printArray(array):
|
||||
print(("".join([str(j) for j in array])))
|
||||
|
||||
|
||||
def printArrays(arrays):
|
||||
for i in arrays: printArray(i)
|
||||
|
||||
|
||||
def reformatText(text, markupArray):
|
||||
"""
|
||||
Takes a text without formatting markup, and an array generated by
|
||||
textToFormatArray, and adds the propper markup.
|
||||
"""
|
||||
|
||||
rText = ""
|
||||
markup = ["**", "//", "__", "--", "``", "''"]
|
||||
|
||||
for k, m in enumerate(markupArray):
|
||||
# m = markupArray[k]
|
||||
_open = False # Are we in an _openned markup
|
||||
d = 0
|
||||
alreadySeen = []
|
||||
for i, t in enumerate(text):
|
||||
insert = False
|
||||
if not _open and m[i] == 1:
|
||||
insert = True
|
||||
_open = True
|
||||
|
||||
if _open and m[i] == 0:
|
||||
insert = True
|
||||
_open = False
|
||||
if _open and m[i] > 1:
|
||||
z = i
|
||||
while m[z] == m[i]: z += 1
|
||||
if m[z] != 1 and not m[i] in alreadySeen:
|
||||
insert = True
|
||||
_open = False
|
||||
alreadySeen.append(m[i])
|
||||
if insert:
|
||||
rText += markup[k]
|
||||
for j, m2 in enumerate(markupArray):
|
||||
# The other array still have the same length
|
||||
if j > k:
|
||||
# Insert 2 for bold, 3 for italic, etc.
|
||||
m2.insert(i + d, k + 2)
|
||||
m2.insert(i + d, k + 2)
|
||||
alreadySeen = []
|
||||
d += 2
|
||||
rText += t
|
||||
if _open:
|
||||
rText += markup[k]
|
||||
for j, m2 in enumerate(markupArray):
|
||||
# The other array still have the same length
|
||||
if j > k:
|
||||
# Insert 2 for bold, 3 for italic, etc.
|
||||
m2.insert(i + d, k + 2)
|
||||
m2.insert(i + d, k + 2)
|
||||
text = rText
|
||||
rText = ""
|
||||
|
||||
# Clean up
|
||||
# Exclude first and last space of the markup
|
||||
for markup in ["\*", "/", "_", "-", "`", "\'"]:
|
||||
# r = QRegExp(r'(' + markup * 2 + ')(\s+)(.+)(' + markup * 2 + ')')
|
||||
# r.setMinimal(True)
|
||||
# text.replace(r, "\\2\\1\\3\\4")
|
||||
text = re.sub(r'(' + markup * 2 + ')(\s+?)(.+?)(' + markup * 2 + ')',
|
||||
"\\2\\1\\3\\4",
|
||||
text)
|
||||
# r = QRegExp(r'(' + markup * 2 + ')(.+)(\s+)(' + markup * 2 + ')')
|
||||
# r.setMinimal(True)
|
||||
# text.replace(r, "\\1\\2\\4\\3")
|
||||
text = re.sub(r'(' + markup * 2 + ')(.+?)(\s+?)(' + markup * 2 + ')',
|
||||
"\\1\\2\\4\\3",
|
||||
text)
|
||||
|
||||
return text
|
||||
|
||||
|
||||
def cleanFormat(text):
|
||||
"""Makes markup clean (removes doubles, etc.)"""
|
||||
t, a = textToFormatArrayNoMarkup(text)
|
||||
return reformatText(t, a)
|
||||
|
||||
|
||||
class State:
|
||||
NORMAL = 0
|
||||
TITLE_1 = 1
|
||||
TITLE_2 = 2
|
||||
TITLE_3 = 3
|
||||
TITLE_4 = 4
|
||||
TITLE_5 = 5
|
||||
NUMBERED_TITLE_1 = 6
|
||||
NUMBERED_TITLE_2 = 7
|
||||
NUMBERED_TITLE_3 = 8
|
||||
NUMBERED_TITLE_4 = 9
|
||||
NUMBERED_TITLE_5 = 10
|
||||
TITLES = [TITLE_1, TITLE_2, TITLE_3, TITLE_4, TITLE_5, NUMBERED_TITLE_1,
|
||||
NUMBERED_TITLE_2, NUMBERED_TITLE_3, NUMBERED_TITLE_4,
|
||||
NUMBERED_TITLE_5]
|
||||
# AREA
|
||||
COMMENT_AREA = 11
|
||||
CODE_AREA = 12
|
||||
RAW_AREA = 13
|
||||
TAGGED_AREA = 14
|
||||
# AREA MARKUP
|
||||
COMMENT_AREA_BEGINS = 15
|
||||
COMMENT_AREA_ENDS = 16
|
||||
CODE_AREA_BEGINS = 17
|
||||
CODE_AREA_ENDS = 18
|
||||
RAW_AREA_BEGINS = 19
|
||||
RAW_AREA_ENDS = 20
|
||||
TAGGED_AREA_BEGINS = 21
|
||||
TAGGED_AREA_ENDS = 22
|
||||
# LINE
|
||||
COMMENT_LINE = 30
|
||||
CODE_LINE = 31
|
||||
RAW_LINE = 32
|
||||
TAGGED_LINE = 33
|
||||
SETTINGS_LINE = 34
|
||||
BLOCKQUOTE_LINE = 35
|
||||
HORIZONTAL_LINE = 36
|
||||
HEADER_LINE = 37
|
||||
# LIST
|
||||
LIST_BEGINS = 40
|
||||
LIST_ENDS = 41
|
||||
LIST_EMPTY = 42
|
||||
LIST_BULLET = 43
|
||||
LIST_BULLET_ENDS = 44
|
||||
LIST = [40, 41, 42] + list(range(100, 201))
|
||||
# TABLE
|
||||
TABLE_LINE = 50
|
||||
TABLE_HEADER = 51
|
||||
# OTHER
|
||||
MARKUP = 60
|
||||
LINKS = 61
|
||||
MACRO = 62
|
||||
DEFAULT = 63
|
||||
|
||||
@staticmethod
|
||||
def titleLevel(state):
|
||||
"""
|
||||
Returns the level of the title, from the block state.
|
||||
"""
|
||||
return {
|
||||
State.TITLE_1: 1,
|
||||
State.TITLE_2: 2,
|
||||
State.TITLE_3: 3,
|
||||
State.TITLE_4: 4,
|
||||
State.TITLE_5: 5,
|
||||
State.NUMBERED_TITLE_1: 1,
|
||||
State.NUMBERED_TITLE_2: 2,
|
||||
State.NUMBERED_TITLE_3: 3,
|
||||
State.NUMBERED_TITLE_4: 4,
|
||||
State.NUMBERED_TITLE_5: 5,
|
||||
}.get(state, -1)
|
|
@ -1,547 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf8 -*-
|
||||
|
||||
|
||||
# This is aiming at implementing every rule from www.txt2tags.org/rules.html
|
||||
# But we're not there yet.
|
||||
|
||||
# FIXME: macro words not hilighted properly if at the begining of a line.
|
||||
|
||||
# TODO: parse %!postproc et !%preproc, et si la ligne se termine par une couleur en commentaire (%#FF00FF),
|
||||
# utiliser cette couleur pour highlighter. Permet des règles customisées par document, facilement.
|
||||
import re
|
||||
|
||||
from PyQt5.QtCore import QRegExp, QDir, QFileInfo
|
||||
from PyQt5.QtGui import QTextBlockFormat, QTextCursor, QTextCharFormat, QBrush
|
||||
|
||||
from manuskript.ui.editors.basicHighlighter import basicHighlighter
|
||||
from manuskript.ui.editors.blockUserData import blockUserData
|
||||
from manuskript.ui.editors.t2tFunctions import State, textToFormatArray
|
||||
from manuskript.ui.editors.t2tHighlighterStyle import t2tHighlighterStyle
|
||||
|
||||
|
||||
class t2tHighlighter(basicHighlighter):
|
||||
"""Syntax highlighter for the Txt2Tags language.
|
||||
"""
|
||||
|
||||
def __init__(self, editor, style="Default"):
|
||||
basicHighlighter.__init__(self, editor)
|
||||
|
||||
# Stupid variable that fixes the loss of QTextBlockUserData.
|
||||
self.thisDocument = editor.document()
|
||||
|
||||
self.style = t2tHighlighterStyle(self.editor, self._defaultCharFormat, style)
|
||||
|
||||
self.inDocRules = []
|
||||
|
||||
rules = [
|
||||
(r'^\s*[-=_]{20,}\s*$', State.HORIZONTAL_LINE),
|
||||
(r'^\s*(\+{1})([^\+].*[^\+])(\+{1})(\[[A-Za-z0-9_-]*\])?\s*$', State.NUMBERED_TITLE_1),
|
||||
(r'^\s*(\+{2})([^\+].*[^\+])(\+{2})(\[[A-Za-z0-9_-]*\])?\s*$', State.NUMBERED_TITLE_2),
|
||||
(r'^\s*(\+{3})([^\+].*[^\+])(\+{3})(\[[A-Za-z0-9_-]*\])?\s*$', State.NUMBERED_TITLE_3),
|
||||
(r'^\s*(\+{4})([^\+].*[^\+])(\+{4})(\[[A-Za-z0-9_-]*\])?\s*$', State.NUMBERED_TITLE_4),
|
||||
(r'^\s*(\+{5})([^\+].*[^\+])(\+{5})(\[[A-Za-z0-9_-]*\])?\s*$', State.NUMBERED_TITLE_5),
|
||||
(r'^\s*(={1})([^=].*[^=])(={1})(\[[A-Za-z0-9_-]*\])?\s*$', State.TITLE_1),
|
||||
(r'^\s*(={2})([^=].*[^=])(={2})(\[[A-Za-z0-9_-]*\])?\s*$', State.TITLE_2),
|
||||
(r'^\s*(={3})([^=].*[^=])(={3})(\[[A-Za-z0-9_-]*\])?\s*$', State.TITLE_3),
|
||||
(r'^\s*(={4})([^=].*[^=])(={4})(\[[A-Za-z0-9_-]*\])?\s*$', State.TITLE_4),
|
||||
(r'^\s*(={5})([^=].*[^=])(={5})(\[[A-Za-z0-9_-]*\])?\s*$', State.TITLE_5),
|
||||
(r'^%!.*$', State.SETTINGS_LINE),
|
||||
(r'^%[^!]?.*$', State.COMMENT_LINE),
|
||||
(r'^\t.+$', State.BLOCKQUOTE_LINE),
|
||||
(r'^(```)(.+)$', State.CODE_LINE),
|
||||
(r'^(""")(.+)$', State.RAW_LINE),
|
||||
(r'^(\'\'\')(.+)$', State.TAGGED_LINE),
|
||||
(r'^\s*[-+:] [^ ].*$', State.LIST_BEGINS),
|
||||
(r'^\s*[-+:]\s*$', State.LIST_ENDS),
|
||||
(r'^ *\|\| .*$', State.TABLE_HEADER),
|
||||
(r'^ *\| .*$', State.TABLE_LINE)
|
||||
]
|
||||
|
||||
# Generate rules to identify blocks
|
||||
State.Rules = [(QRegExp(pattern), state)
|
||||
for (pattern, state) in rules]
|
||||
State.Recursion = 0
|
||||
|
||||
def setDefaultCharFormat(self, cf):
|
||||
self._defaultCharFormat = cf
|
||||
self.setStyle()
|
||||
self.rehighlight()
|
||||
|
||||
def highlightBlock(self, text):
|
||||
"""Apply syntax highlighting to the given block of text.
|
||||
"""
|
||||
basicHighlighter.highlightBlockBefore(self, text)
|
||||
|
||||
# Check if syntax highlighting is enabled
|
||||
if self.style is None:
|
||||
default = QTextBlockFormat()
|
||||
QTextCursor(self.currentBlock()).setBlockFormat(default)
|
||||
print("t2tHighlighter.py: is style supposed to be None?")
|
||||
return
|
||||
|
||||
block = self.currentBlock()
|
||||
oldState = blockUserData.getUserState(block)
|
||||
self.identifyBlock(block)
|
||||
# formatBlock prevent undo/redo from working
|
||||
# TODO: find a todo/undo compatible way of formatting block
|
||||
# self.formatBlock(block)
|
||||
|
||||
state = blockUserData.getUserState(block)
|
||||
data = blockUserData.getUserData(block)
|
||||
inList = self.isList(block)
|
||||
|
||||
op = self.style.format(State.MARKUP)
|
||||
|
||||
# self.setFormat(0, len(text), self.style.format(State.DEFAULT))
|
||||
|
||||
# InDocRules: is it a settings which might have a specific rule,
|
||||
# a comment which contains color infos, or a include conf?
|
||||
# r'^%!p[or][se]t?proc[^\s]*\s*:\s*\'(.*)\'\s*\'.*\''
|
||||
rlist = [QRegExp(r'^%!p[or][se]t?proc[^\s]*\s*:\s*((\'[^\']*\'|\"[^\"]*\")\s*(\'[^\']*\'|\"[^\"]*\"))'),
|
||||
# pre/postproc
|
||||
QRegExp(r'^%.*\s\((.*)\)'), # comment
|
||||
QRegExp(r'^%!includeconf:\s*([^\s]*)\s*')] # includeconf
|
||||
for r in rlist:
|
||||
if r.indexIn(text) != -1:
|
||||
self.parseInDocRules()
|
||||
|
||||
# Format the whole line:
|
||||
for lineState in [
|
||||
State.BLOCKQUOTE_LINE,
|
||||
State.HORIZONTAL_LINE,
|
||||
State.HEADER_LINE,
|
||||
]:
|
||||
if not inList and state == lineState:
|
||||
self.setFormat(0, len(text), self.style.format(lineState))
|
||||
|
||||
for (lineState, marker) in [
|
||||
(State.COMMENT_LINE, "%"),
|
||||
(State.CODE_LINE, "```"),
|
||||
(State.RAW_LINE, "\"\"\""),
|
||||
(State.TAGGED_LINE, "'''"),
|
||||
(State.SETTINGS_LINE, "%!")
|
||||
]:
|
||||
if state == lineState and \
|
||||
not (inList and state == State.SETTINGS_LINE):
|
||||
n = 0
|
||||
# If it's a comment, we want to highlight all '%'.
|
||||
if state == State.COMMENT_LINE:
|
||||
while text[n:n + 1] == "%":
|
||||
n += 1
|
||||
n -= 1
|
||||
|
||||
# Apply Format
|
||||
self.setFormat(0, len(marker) + n, op)
|
||||
self.setFormat(len(marker) + n,
|
||||
len(text) - len(marker) - n,
|
||||
self.style.format(lineState))
|
||||
|
||||
# If it's a setting, we might do something
|
||||
if state == State.SETTINGS_LINE:
|
||||
# Target
|
||||
r = QRegExp(r'^%!([^\s]+)\s*:\s*(\b\w*\b)$')
|
||||
if r.indexIn(text) != -1:
|
||||
setting = r.cap(1)
|
||||
val = r.cap(2)
|
||||
if setting == "target" and \
|
||||
val in self.editor.main.targetsNames:
|
||||
self.editor.fileWidget.preview.setPreferredTarget(val)
|
||||
|
||||
# Pre/postproc
|
||||
r = QRegExp(r'^%!p[or][se]t?proc[^\s]*\s*:\s*((\'[^\']*\'|\"[^\"]*\")\s*(\'[^\']*\'|\"[^\"]*\"))')
|
||||
if r.indexIn(text) != -1:
|
||||
p = r.pos(1)
|
||||
length = len(r.cap(1))
|
||||
self.setFormat(p, length, self.style.makeFormat(base=self.format(p),
|
||||
fixedPitch=True))
|
||||
|
||||
# Tables
|
||||
for lineState in [State.TABLE_LINE, State.TABLE_HEADER]:
|
||||
if state == lineState:
|
||||
for i, t in enumerate(text):
|
||||
if t == "|":
|
||||
self.setFormat(i, 1, op)
|
||||
else:
|
||||
self.setFormat(i, 1, self.style.format(lineState))
|
||||
|
||||
# Lists
|
||||
# if text == " p": print(data.isList())
|
||||
if data.isList():
|
||||
r = QRegExp(r'^\s*[\+\-\:]? ?')
|
||||
r.indexIn(text)
|
||||
self.setFormat(0, r.matchedLength(), self.style.format(State.LIST_BULLET))
|
||||
# if state == State.LIST_BEGINS:
|
||||
# r = QRegExp(r'^\s*[+-:] ')
|
||||
# r.indexIn(text)
|
||||
# self.setFormat(0, r.matchedLength(), self.style.format(State.LIST_BULLET))
|
||||
|
||||
if state == State.LIST_ENDS:
|
||||
self.setFormat(0, len(text), self.style.format(State.LIST_BULLET_ENDS))
|
||||
|
||||
# Titles
|
||||
if not inList and state in State.TITLES:
|
||||
r = [i for (i, s) in State.Rules if s == state][0]
|
||||
pos = r.indexIn(text)
|
||||
if pos >= 0:
|
||||
f = self.style.format(state)
|
||||
# Uncomment for markup to be same size as title
|
||||
# op = self.formats(preset="markup",
|
||||
# base=self.formats(preset=state))
|
||||
self.setFormat(r.pos(2), len(r.cap(2)), f)
|
||||
self.setFormat(r.pos(1), len(r.cap(1)), op)
|
||||
self.setFormat(r.pos(3), len(r.cap(3)), op)
|
||||
|
||||
# Areas: comment, code, raw tagged
|
||||
for (begins, middle, ends) in [
|
||||
(State.COMMENT_AREA_BEGINS, State.COMMENT_AREA, State.COMMENT_AREA_ENDS),
|
||||
(State.CODE_AREA_BEGINS, State.CODE_AREA, State.CODE_AREA_ENDS),
|
||||
(State.RAW_AREA_BEGINS, State.RAW_AREA, State.RAW_AREA_ENDS),
|
||||
(State.TAGGED_AREA_BEGINS, State.TAGGED_AREA, State.TAGGED_AREA_ENDS),
|
||||
]:
|
||||
|
||||
if state == middle:
|
||||
self.setFormat(0, len(text), self.style.format(middle))
|
||||
elif state in [begins, ends]:
|
||||
self.setFormat(0, len(text), op)
|
||||
|
||||
# Inline formatting
|
||||
if state not in [
|
||||
# State.COMMENT_AREA,
|
||||
# State.COMMENT_LINE,
|
||||
State.RAW_AREA,
|
||||
State.RAW_LINE,
|
||||
State.CODE_AREA,
|
||||
State.CODE_LINE,
|
||||
State.TAGGED_AREA,
|
||||
State.TAGGED_LINE,
|
||||
State.SETTINGS_LINE,
|
||||
State.HORIZONTAL_LINE,
|
||||
] and state not in State.TITLES:
|
||||
formatArray = textToFormatArray(text)
|
||||
|
||||
# InDocRules
|
||||
for (r, c) in self.inDocRules:
|
||||
i = re.finditer(r.decode('utf8'), text, re.UNICODE)
|
||||
for m in i:
|
||||
f = self.format(m.start())
|
||||
l = m.end() - m.start()
|
||||
if "," in c:
|
||||
c1, c2 = c.split(",")
|
||||
self.setFormat(m.start(), l,
|
||||
self.style.makeFormat(color=c1, bgcolor=c2, base=f))
|
||||
else:
|
||||
self.setFormat(m.start(), l,
|
||||
self.style.makeFormat(color=c, base=f))
|
||||
|
||||
# Links
|
||||
if state not in [State.COMMENT_LINE, State.COMMENT_AREA]:
|
||||
r = QRegExp(r'\[(\[[^\]]*\])?[^\]]*\s*([^\s]+)\]')
|
||||
r.setMinimal(False)
|
||||
pos = r.indexIn(text)
|
||||
links = []
|
||||
while pos >= 0:
|
||||
# TODO: The text should not be formatted if [**not bold**]
|
||||
# if max([k[pos] for k in formatArray]) == 0 or 1 == 1:
|
||||
self.setFormat(pos, 1,
|
||||
self.style.format(State.MARKUP))
|
||||
self.setFormat(pos + 1, len(r.cap(0)) - 1,
|
||||
self.style.format(State.LINKS))
|
||||
self.setFormat(pos + len(r.cap(0)) - 1, 1,
|
||||
self.style.format(State.MARKUP))
|
||||
if r.pos(2) > 0:
|
||||
_f = QTextCharFormat(self.style.format(State.LINKS))
|
||||
_f.setForeground(QBrush(_f.foreground()
|
||||
.color().lighter()))
|
||||
_f.setFontUnderline(True)
|
||||
self.setFormat(r.pos(2), len(r.cap(2)), _f)
|
||||
|
||||
links.append([pos, len(r.cap(0))]) # To remember for the next highlighter (single links)
|
||||
pos = r.indexIn(text, pos + 1)
|
||||
|
||||
# Links like www.theologeek.ch, http://www.fsf.org, ...
|
||||
# FIXME: - "http://adresse et http://adresse" is detected also as italic
|
||||
# - some error, like "http://adress.htm." also color the final "."
|
||||
# - also: adresse@email.com, ftp://, www2, www3, etc.
|
||||
# - But for now, does the job
|
||||
r = QRegExp(r'http://[^\s]*|www\.[a-zA-Z0-9-_]+\.[a-zA-Z0-9-_]+[^\s]*')
|
||||
# r.setMinimal(True)
|
||||
pos = r.indexIn(text)
|
||||
while pos >= 0:
|
||||
for k in links:
|
||||
# print pos, k[0], k[1]
|
||||
if k[0] < pos < k[0] + k[1]: # already highlighted
|
||||
break
|
||||
else:
|
||||
self.setFormat(pos, len(r.cap(0)), self.style.format(State.LINKS))
|
||||
|
||||
pos = r.indexIn(text, pos + 1)
|
||||
|
||||
# Bold, Italic, Underline, Code, Tagged, Strikeout
|
||||
for i, t in enumerate(text):
|
||||
f = self.format(i)
|
||||
beautifiers = [k[i] for k in formatArray]
|
||||
self.setFormat(i, 1, self.style.beautifyFormat(f, beautifiers))
|
||||
|
||||
# Macro words
|
||||
for r in [r'(%%)\b\w+\b', r'(%%)\b\w+\b\(.+\)']:
|
||||
r = QRegExp(r)
|
||||
r.setMinimal(True)
|
||||
pos = r.indexIn(text)
|
||||
while pos >= 0:
|
||||
if max([k[pos] for k in formatArray]) == 0:
|
||||
self.setFormat(pos, len(r.cap(0)),
|
||||
self.style.format(State.MACRO))
|
||||
pos = r.indexIn(text, pos + 1)
|
||||
|
||||
# Highlighted word (for search)
|
||||
if self.editor.highlightWord:
|
||||
if self.editor.highligtCS and self.editor.highlightWord in text or \
|
||||
not self.editor.highlightCs and self.editor.highlightWord.lower() in text.lower():
|
||||
# if self.editor.highlightCS:
|
||||
# s = self.editor.highlightWord
|
||||
# else:
|
||||
# s = self.editor.highlightWord.toLower()
|
||||
# print(s)
|
||||
p = text.indexOf(self.editor.highlightWord, cs=self.editor.highlightCS)
|
||||
while p >= 0:
|
||||
self.setFormat(p, len(self.editor.highlightWord),
|
||||
self.style.makeFormat(preset="higlighted", base=self.format(p)))
|
||||
p = text.indexOf(self.editor.highlightWord, p + 1, cs=self.editor.highlightCS)
|
||||
|
||||
### Highlight Selection
|
||||
### TODO: way to slow, find another way.
|
||||
##sel = self.editor.textCursor().selectedText()
|
||||
##if len(sel) > 5: self.keywordRules.append((QRegExp(sel), "selected"))
|
||||
|
||||
## Do keyword formatting
|
||||
# for expression, style in self.keywordRules:
|
||||
# expression.setMinimal( True )
|
||||
# index = expression.indexIn(text, 0)
|
||||
|
||||
## There might be more than one on the same line
|
||||
# while index >= 0:
|
||||
# length = expression.cap(0).length()
|
||||
# f = self.formats(preset=style, base=self.formats(index))
|
||||
# self.setFormat(index, length, f)
|
||||
# index = expression.indexIn(text, index + length)
|
||||
|
||||
basicHighlighter.highlightBlockAfter(self, text)
|
||||
|
||||
def identifyBlock(self, block):
|
||||
"""Identifies what block type it is, and set userState and userData
|
||||
accordingly."""
|
||||
|
||||
text = block.text()
|
||||
data = blockUserData.getUserData(block)
|
||||
|
||||
# Header Lines
|
||||
# No header line here
|
||||
# if block.blockNumber() == 0:
|
||||
# block.setUserState(State.HEADER_LINE)
|
||||
# return
|
||||
# elif block.blockNumber() in [1, 2] and \
|
||||
# self.document().findBlockByNumber(0).text():
|
||||
# block.setUserState(State.HEADER_LINE)
|
||||
# return
|
||||
|
||||
state = 0
|
||||
inList = False
|
||||
blankLinesBefore = 0
|
||||
|
||||
# if text.contains(QRegExp(r'^\s*[-+:] [^ ].*[^-+]{1}\s*$')):
|
||||
if QRegExp(r'^\s*[-+:] [^ ].*[^-+]{1}\s*$').indexIn(text) != -1:
|
||||
state = State.LIST_BEGINS
|
||||
|
||||
# List stuff
|
||||
if self.isList(block.previous()) or state == State.LIST_BEGINS:
|
||||
inList = True
|
||||
|
||||
# listLevel and leadingSpaces
|
||||
# FIXME: not behaving exactly correctly...
|
||||
lastData = blockUserData.getUserData(block.previous())
|
||||
if state == State.LIST_BEGINS:
|
||||
leadingSpaces = QRegExp(r'[-+:]').indexIn(text, 0)
|
||||
data.setLeadingSpaces(leadingSpaces)
|
||||
|
||||
data.setListSymbol(text[leadingSpaces])
|
||||
if self.isList(block.previous()):
|
||||
# The last block was also a list.
|
||||
# We need to check if this is the same level, or a sublist
|
||||
if leadingSpaces > lastData.leadingSpaces():
|
||||
# This is a sublevel list
|
||||
data.setListLevel(lastData.listLevel() + 1)
|
||||
else:
|
||||
# This is same level
|
||||
data.setListLevel(lastData.listLevel())
|
||||
else:
|
||||
data.setListLevel(1)
|
||||
else:
|
||||
data.setListLevel(lastData.listLevel())
|
||||
data.setLeadingSpaces(lastData.leadingSpaces())
|
||||
data.setListSymbol(lastData.listSymbol())
|
||||
|
||||
# Blank lines before (two = end of list)
|
||||
blankLinesBefore = self.getBlankLines(block.previous())
|
||||
if not QRegExp(r'^\s*$').indexIn(block.previous().text()) != -1 and \
|
||||
not blockUserData.getUserState(block.previous()) in [State.COMMENT_LINE,
|
||||
State.COMMENT_AREA, State.COMMENT_AREA_BEGINS,
|
||||
State.COMMENT_AREA_ENDS]:
|
||||
blankLinesBefore = 0
|
||||
elif not blockUserData.getUserState(block.previous()) in \
|
||||
[State.COMMENT_LINE, State.COMMENT_AREA,
|
||||
State.COMMENT_AREA_BEGINS, State.COMMENT_AREA_ENDS]:
|
||||
blankLinesBefore += 1
|
||||
if blankLinesBefore == 2:
|
||||
# End of list.
|
||||
blankLinesBefore = 0
|
||||
inList = False
|
||||
if inList and QRegExp(r'^\s*$').indexIn(text) != -1:
|
||||
state = State.LIST_EMPTY
|
||||
|
||||
# Areas
|
||||
for (begins, middle, ends, marker) in [
|
||||
(State.COMMENT_AREA_BEGINS, State.COMMENT_AREA, State.COMMENT_AREA_ENDS, "^%%%\s*$"),
|
||||
(State.CODE_AREA_BEGINS, State.CODE_AREA, State.CODE_AREA_ENDS, "^```\s*$"),
|
||||
(State.RAW_AREA_BEGINS, State.RAW_AREA, State.RAW_AREA_ENDS, "^\"\"\"\s*$"),
|
||||
(State.TAGGED_AREA_BEGINS, State.TAGGED_AREA, State.TAGGED_AREA_ENDS, '^\'\'\'\s*$'),
|
||||
]:
|
||||
|
||||
if QRegExp(marker).indexIn(text) != -1:
|
||||
if blockUserData.getUserState(block.previous()) in [begins, middle]:
|
||||
state = ends
|
||||
break
|
||||
else:
|
||||
state = begins
|
||||
break
|
||||
if blockUserData.getUserState(block.previous()) in [middle, begins]:
|
||||
state = middle
|
||||
break
|
||||
|
||||
# Patterns (for lines)
|
||||
if not state:
|
||||
for (pattern, lineState) in State.Rules:
|
||||
pos = pattern.indexIn(text)
|
||||
if pos >= 0:
|
||||
state = lineState
|
||||
break
|
||||
|
||||
if state in [State.BLOCKQUOTE_LINE, State.LIST_ENDS]:
|
||||
# FIXME: doesn't work exactly. Closes only the current level, not
|
||||
# FIXME: the whole list.
|
||||
inList = False
|
||||
|
||||
if inList and not state == State.LIST_BEGINS:
|
||||
state += 100
|
||||
if blankLinesBefore:
|
||||
state += 100
|
||||
|
||||
block.setUserState(state)
|
||||
block.setUserData(data)
|
||||
|
||||
def formatBlock(self, block):
|
||||
"""
|
||||
Formats the block according to its state.
|
||||
"""
|
||||
# TODO: Use QTextDocument format presets, and QTextBlock's
|
||||
# TODO: blockFormatIndex. And move that in t2tHighlighterStyle.
|
||||
state = block.userState()
|
||||
blockFormat = QTextBlockFormat()
|
||||
|
||||
if state in [State.BLOCKQUOTE_LINE,
|
||||
State.HEADER_LINE] + State.LIST:
|
||||
blockFormat = self.style.formatBlock(block, state)
|
||||
|
||||
QTextCursor(block).setBlockFormat(blockFormat)
|
||||
|
||||
def getBlankLines(self, block):
|
||||
"""Returns if there is a blank line before in the list."""
|
||||
state = block.userState()
|
||||
if state >= 200:
|
||||
return 1
|
||||
else:
|
||||
return 0
|
||||
|
||||
def isList(self, block):
|
||||
"""Returns TRUE if the block is in a list."""
|
||||
if block.userState() == State.LIST_BEGINS or \
|
||||
block.userState() >= 100:
|
||||
return True
|
||||
|
||||
def setStyle(self, style="Default"):
|
||||
if style in t2tHighlighterStyle.validStyles:
|
||||
self.style = t2tHighlighterStyle(self.editor, self._defaultCharFormat, style)
|
||||
else:
|
||||
self.style = None
|
||||
self.rehighlight()
|
||||
|
||||
def setFontPointSize(self, size):
|
||||
self.defaultFontPointSize = size
|
||||
self.style = t2tHighlighterStyle(self.editor, self.style.name)
|
||||
self.rehighlight()
|
||||
|
||||
def parseInDocRules(self):
|
||||
oldRules = self.inDocRules
|
||||
self.inDocRules = []
|
||||
|
||||
t = self.thisDocument.toPlainText()
|
||||
|
||||
# Get all conf files
|
||||
confs = []
|
||||
lines = t.split("\n")
|
||||
for l in lines:
|
||||
r = QRegExp(r'^%!includeconf:\s*([^\s]*)\s*')
|
||||
if r.indexIn(l) != -1:
|
||||
confs.append(r.cap(1))
|
||||
|
||||
# Try to load conf files
|
||||
for c in confs:
|
||||
try:
|
||||
import codecs
|
||||
f = self.editor.fileWidget.file
|
||||
d = QDir.cleanPath(QFileInfo(f).absoluteDir().absolutePath() + "/" + c)
|
||||
file = codecs.open(d, 'r', "utf-8")
|
||||
except:
|
||||
print(("Error: cannot open {}.".format(c)))
|
||||
continue
|
||||
# We add the content to the current lines of the current document
|
||||
lines += file.readlines() # lines.extend(file.readlines())
|
||||
|
||||
# b = self.thisDocument.firstBlock()
|
||||
lastColor = ""
|
||||
|
||||
# while b.isValid():
|
||||
for l in lines:
|
||||
text = l # b.text()
|
||||
r = QRegExp(r'^%!p[or][se]t?proc[^\s]*\s*:\s*(\'[^\']*\'|\"[^\"]*\")\s*(\'[^\']*\'|\"[^\"]*\")')
|
||||
if r.indexIn(text) != -1:
|
||||
rule = r.cap(1)[1:-1]
|
||||
# Check if there was a color-comment above that post/preproc bloc
|
||||
if lastColor:
|
||||
self.inDocRules.append((str(rule), lastColor))
|
||||
# Check if previous block is a comment like it should
|
||||
else:
|
||||
previousText = lines[lines.indexOf(l) - 1] # b.previous().text()
|
||||
r = QRegExp(r'^%.*\s\((.*)\)')
|
||||
if r.indexIn(previousText) != -1:
|
||||
lastColor = r.cap(1)
|
||||
self.inDocRules.append((str(rule), lastColor))
|
||||
else:
|
||||
lastColor = ""
|
||||
# b = b.next()
|
||||
|
||||
if oldRules != self.inDocRules:
|
||||
# Rules have changed, we need to rehighlight
|
||||
# print("Rules have changed.", len(self.inDocRules))
|
||||
# self.rehighlight() # Doesn't work (seg fault), why?
|
||||
pass
|
||||
# b = self.thisDocument.firstBlock()
|
||||
# while b.isValid():
|
||||
# for (r, c) in self.inDocRules:
|
||||
# r = QRegExp(r)
|
||||
# pos = r.indexIn(b.text())
|
||||
# if pos >= 0:
|
||||
# print("rehighlighting:", b.text())
|
||||
# self.rehighlightBlock(b)
|
||||
# break
|
||||
# b = b.next()
|
|
@ -1,252 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf8 -*-
|
||||
|
||||
|
||||
# TODO: creates a general way to generate styles (and edit/import/export)
|
||||
from PyQt5.QtCore import QRegExp, Qt
|
||||
from PyQt5.QtGui import QFont, QTextBlockFormat, QColor, QFontMetrics, QTextCharFormat
|
||||
from PyQt5.QtWidgets import qApp
|
||||
|
||||
from manuskript.ui.editors.blockUserData import blockUserData
|
||||
from manuskript.ui.editors.t2tFunctions import State
|
||||
|
||||
|
||||
class t2tHighlighterStyle():
|
||||
"""Style for the Syntax highlighter for the Txt2Tags language.
|
||||
"""
|
||||
|
||||
validStyles = ["Default", "Monospace"]
|
||||
|
||||
def __init__(self, editor, charFormat, name="Default"):
|
||||
|
||||
self.editor = editor
|
||||
self.name = name
|
||||
self._defaultCharFormat = charFormat
|
||||
|
||||
# Defaults
|
||||
# self.defaultFontPointSize = self.editor.defaultFontPointSize
|
||||
self.defaultFontFamily = qApp.font().family()
|
||||
self.tabStopWidth = 40
|
||||
|
||||
self.setupEditor()
|
||||
|
||||
if self.name == "Default":
|
||||
self.initDefaults()
|
||||
# Temporary other theme
|
||||
elif self.name == "Monospace":
|
||||
self.defaultFontFamily = "Monospace"
|
||||
self.initDefaults()
|
||||
for i in self.styles:
|
||||
f = self.styles[i]
|
||||
f.setFontFixedPitch(True)
|
||||
f.setFontFamily(self.defaultFontFamily)
|
||||
f.setFontPointSize(self._defaultCharFormat.font().pointSize())
|
||||
self.styles[i] = f
|
||||
|
||||
def setupEditor(self):
|
||||
self.editor.setTabStopWidth(self.tabStopWidth)
|
||||
|
||||
def initDefaults(self):
|
||||
self.styles = {}
|
||||
for i in [State.CODE_AREA,
|
||||
State.CODE_LINE,
|
||||
State.COMMENT_AREA,
|
||||
State.COMMENT_LINE,
|
||||
State.SETTINGS_LINE,
|
||||
State.BLOCKQUOTE_LINE,
|
||||
State.RAW_AREA,
|
||||
State.RAW_LINE,
|
||||
State.TAGGED_AREA,
|
||||
State.TAGGED_LINE,
|
||||
State.TITLE_1,
|
||||
State.TITLE_2,
|
||||
State.TITLE_3,
|
||||
State.TITLE_4,
|
||||
State.TITLE_5,
|
||||
State.NUMBERED_TITLE_1,
|
||||
State.NUMBERED_TITLE_2,
|
||||
State.NUMBERED_TITLE_3,
|
||||
State.NUMBERED_TITLE_4,
|
||||
State.NUMBERED_TITLE_5,
|
||||
State.TABLE_HEADER,
|
||||
State.TABLE_LINE,
|
||||
State.HORIZONTAL_LINE,
|
||||
State.MARKUP,
|
||||
State.LIST_BULLET,
|
||||
State.LIST_BULLET_ENDS,
|
||||
State.LINKS,
|
||||
State.MACRO,
|
||||
State.DEFAULT,
|
||||
State.HEADER_LINE]:
|
||||
self.styles[i] = self.makeFormat(preset=i)
|
||||
|
||||
def format(self, state):
|
||||
return self.styles[state]
|
||||
|
||||
def beautifyFormat(self, base, beautifiers):
|
||||
"""Apply beautifiers given in beautifiers array to format"""
|
||||
if max(beautifiers) == 2:
|
||||
return self.makeFormat(preset=State.MARKUP, base=base)
|
||||
else:
|
||||
if beautifiers[0]: # bold
|
||||
base.setFontWeight(QFont.Bold)
|
||||
if beautifiers[1]: # italic
|
||||
base.setFontItalic(True)
|
||||
if beautifiers[2]: # underline
|
||||
base.setFontUnderline(True)
|
||||
if beautifiers[3]: # strikeout
|
||||
base.setFontStrikeOut(True)
|
||||
if beautifiers[4]: # code
|
||||
base = self.makeFormat(base=base, preset=State.CODE_LINE)
|
||||
if beautifiers[5]: # tagged
|
||||
base = self.makeFormat(base=base, preset=State.TAGGED_LINE)
|
||||
return base
|
||||
|
||||
def formatBlock(self, block, state):
|
||||
"""Apply transformation to given block."""
|
||||
blockFormat = QTextBlockFormat()
|
||||
|
||||
if state == State.BLOCKQUOTE_LINE:
|
||||
# Number of tabs
|
||||
n = block.text().indexOf(QRegExp(r'[^\t]'), 0)
|
||||
blockFormat.setIndent(0)
|
||||
blockFormat.setTextIndent(-self.tabStopWidth * n)
|
||||
blockFormat.setLeftMargin(self.tabStopWidth * n)
|
||||
# blockFormat.setRightMargin(self.editor.contentsRect().width()
|
||||
# - self.editor.lineNumberAreaWidth()
|
||||
# - fm.width("X") * self.editor.LimitLine
|
||||
# + self.editor.tabStopWidth())
|
||||
blockFormat.setAlignment(Qt.AlignJustify)
|
||||
if self.name == "Default":
|
||||
blockFormat.setTopMargin(5)
|
||||
blockFormat.setBottomMargin(5)
|
||||
elif state == State.HEADER_LINE:
|
||||
blockFormat.setBackground(QColor("#EEEEEE"))
|
||||
elif state in State.LIST:
|
||||
data = blockUserData.getUserData(block)
|
||||
if str(data.listSymbol()) in "+-":
|
||||
blockFormat.setBackground(QColor("#EEFFEE"))
|
||||
else:
|
||||
blockFormat.setBackground(QColor("#EEEEFA"))
|
||||
n = blockUserData.getUserData(block).leadingSpaces() + 1
|
||||
|
||||
f = QFontMetrics(QFont(self.defaultFontFamily,
|
||||
self._defaultCharFormat.font().pointSize()))
|
||||
fm = f.width(" " * n +
|
||||
blockUserData.getUserData(block).listSymbol())
|
||||
blockFormat.setTextIndent(-fm)
|
||||
blockFormat.setLeftMargin(fm)
|
||||
if blockUserData.getUserState(block) == State.LIST_BEGINS and \
|
||||
self.name == "Default":
|
||||
blockFormat.setTopMargin(5)
|
||||
return blockFormat
|
||||
|
||||
def makeFormat(self, color='', style='', size='', base='', fixedPitch='',
|
||||
preset='', title_level='', bgcolor=''):
|
||||
"""
|
||||
Returns a QTextCharFormat with the given attributes, using presets.
|
||||
"""
|
||||
|
||||
_color = QColor()
|
||||
# _format = QTextCharFormat()
|
||||
# _format.setFont(self.editor.font())
|
||||
# size = _format.fontPointSize()
|
||||
_format = QTextCharFormat(self._defaultCharFormat)
|
||||
|
||||
# Base
|
||||
if base:
|
||||
_format = base
|
||||
|
||||
# Presets
|
||||
if preset in [State.CODE_AREA, State.CODE_LINE, "code"]:
|
||||
style = "bold"
|
||||
color = "black"
|
||||
fixedPitch = True
|
||||
_format.setBackground(QColor("#EEEEEE"))
|
||||
|
||||
if preset in [State.COMMENT_AREA, State.COMMENT_LINE, "comment"]:
|
||||
style = "italic"
|
||||
color = "darkGreen"
|
||||
|
||||
if preset in [State.SETTINGS_LINE, "setting", State.MACRO]:
|
||||
# style = "italic"
|
||||
color = "magenta"
|
||||
|
||||
if preset in [State.BLOCKQUOTE_LINE]:
|
||||
color = "red"
|
||||
|
||||
if preset in [State.HEADER_LINE]:
|
||||
size *= 2
|
||||
# print size
|
||||
|
||||
if preset in [State.RAW_AREA, State.RAW_LINE, "raw"]:
|
||||
color = "blue"
|
||||
|
||||
if preset in [State.TAGGED_AREA, State.TAGGED_LINE, "tagged"]:
|
||||
color = "purple"
|
||||
|
||||
if preset in State.TITLES:
|
||||
style = "bold"
|
||||
color = "darkRed" if State.titleLevel(preset) % 2 == 1 else "blue"
|
||||
size = (self._defaultCharFormat.font().pointSize()
|
||||
+ 11 - 2 * State.titleLevel(preset))
|
||||
|
||||
if preset == State.TABLE_HEADER:
|
||||
style = "bold"
|
||||
color = "darkMagenta"
|
||||
|
||||
if preset == State.TABLE_LINE:
|
||||
color = "darkMagenta"
|
||||
|
||||
if preset == State.LIST_BULLET:
|
||||
color = "red"
|
||||
style = "bold"
|
||||
fixedPitch = True
|
||||
|
||||
if preset == State.LIST_BULLET_ENDS:
|
||||
color = "darkGray"
|
||||
fixedPitch = True
|
||||
|
||||
if preset in [State.MARKUP, "markup"]:
|
||||
color = "darkGray"
|
||||
|
||||
if preset in [State.HORIZONTAL_LINE]:
|
||||
color = "cyan"
|
||||
fixedPitch = True
|
||||
|
||||
if preset == State.LINKS:
|
||||
color = "blue"
|
||||
# style="underline"
|
||||
|
||||
if preset == "selected":
|
||||
_format.setBackground(QColor("yellow"))
|
||||
|
||||
if preset == "higlighted":
|
||||
bgcolor = "yellow"
|
||||
|
||||
# if preset == State.DEFAULT:
|
||||
# size = self.defaultFontPointSize
|
||||
# _format.setFontFamily(self.defaultFontFamily)
|
||||
|
||||
# Manual formatting
|
||||
if color:
|
||||
_color.setNamedColor(color)
|
||||
_format.setForeground(_color)
|
||||
if bgcolor:
|
||||
_color.setNamedColor(bgcolor)
|
||||
_format.setBackground(_color)
|
||||
|
||||
if 'bold' in style:
|
||||
_format.setFontWeight(QFont.Bold)
|
||||
if 'italic' in style:
|
||||
_format.setFontItalic(True)
|
||||
if 'strike' in style:
|
||||
_format.setFontStrikeOut(True)
|
||||
if 'underline' in style:
|
||||
_format.setFontUnderline(True)
|
||||
if size:
|
||||
_format.setFontPointSize(size)
|
||||
if fixedPitch:
|
||||
_format.setFontFixedPitch(True)
|
||||
|
||||
return _format
|
|
@ -11,6 +11,7 @@ from manuskript.enums import Outline
|
|||
from manuskript.functions import AUC
|
||||
from manuskript.functions import toString
|
||||
from manuskript.models.outlineModel import outlineModel
|
||||
from manuskript.ui.editors.MDFunctions import MDFormatSelection
|
||||
from manuskript.ui.editors.MMDHighlighter import MMDHighlighter
|
||||
from manuskript.ui.editors.basicHighlighter import basicHighlighter
|
||||
from manuskript.ui.editors.textFormat import textFormat
|
||||
|
@ -456,16 +457,12 @@ class textEditView(QTextEdit):
|
|||
def applyFormat(self, _format):
|
||||
|
||||
if self._textFormat == "md":
|
||||
# FIXME
|
||||
print("Not implemented yet.")
|
||||
|
||||
# Model: from t2tFunctions
|
||||
# if self._textFormat == "t2t":
|
||||
# if _format == "Bold":
|
||||
# t2tFormatSelection(self, 0)
|
||||
# elif _format == "Italic":
|
||||
# t2tFormatSelection(self, 1)
|
||||
# elif _format == "Underline":
|
||||
# t2tFormatSelection(self, 2)
|
||||
# elif _format == "Clear":
|
||||
# t2tClearFormat(self)
|
||||
if _format == "Bold":
|
||||
MDFormatSelection(self, 0)
|
||||
elif _format == "Italic":
|
||||
MDFormatSelection(self, 1)
|
||||
elif _format == "Code":
|
||||
MDFormatSelection(self, 2)
|
||||
elif _format == "Clear":
|
||||
MDFormatSelection(self)
|
||||
|
|
Loading…
Reference in a new issue