manuskript/src/ui/editors/t2tFunctions.py
2015-06-07 22:06:57 +02:00

264 lines
7 KiB
Python

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from qt import *
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 in range(len(markupArray)):
m = markupArray[k]
open = False # Are we in an openned markup
d = 0
alreadySeen = []
for i in range(len(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 in range(len(markupArray)):
# The other array still have the same length
if j > k:
#Insert 2 for bold, 3 for italic, etc.
markupArray[j].insert(i + d, k + 2)
markupArray[j].insert(i + d, k + 2)
alreadySeen = []
d += 2
rText += text[i]
if open:
rText += markup[k]
for j in range(len(markupArray)):
# The other array still have the same length
if j > k:
#Insert 2 for bold, 3 for italic, etc.
markupArray[j].insert(i + d, k + 2)
markupArray[j].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")
r = QRegExp(r'(' + markup * 2 + ')(.+)(\s+)(' + markup * 2 + ')')
r.setMinimal(True)
text.replace(r, "\\1\\2\\4\\3")
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)