Coverage for control/typ/text.py : 87%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""Types of text."""
3import re
5from markdown import markdown
7from config import Config as C, Names as N
8from control.html import HtmlElements as H
9from control.utils import E, DOT
10from control.typ.base import TypeBase
13CW = C.web
15QQ = H.icon(CW.unknown[N.generic])
16Qq = H.icon(CW.unknown[N.generic], asChar=True)
18urlStart = re.compile(r"""^([a-zA-Z0-9_-]+)[:/]+(.*)""", re.I)
21class Text(TypeBase):
22 """Base class for text types: String, Url, Email, Markdown."""
23 widgetType = N.text
26class Url(Text):
27 """Type class for url strings."""
29 pattern = (
30 f"""^{N.http}s?://"""
31 """[A-Za-z0-9%_-]+\\.[A-Za-z0-9%_.-]+"""
32 """([/][^&?=]*)?"""
33 """([?&].*)?"""
34 """$"""
35 )
37 def normalize(cls, strVal):
38 normalVal = str(strVal).strip()
39 if not normalVal: 39 ↛ 40line 39 didn't jump to line 40, because the condition on line 39 was never true
40 return E
41 match = urlStart.match(normalVal)
42 if match:
43 protocol = match.group(1).lower()
44 rest = match.group(2)
45 if protocol not in {N.http, N.https}:
46 protocol = N.https
47 normalVal = f"{protocol}://{rest}"
48 else:
49 normalVal = f"https://{normalVal}"
50 if DOT not in normalVal:
51 normalVal += f"""{DOT}{N.org}"""
52 return normalVal
54 def toDisplay(self, val, markup=True):
55 if val is None: 55 ↛ 56line 55 didn't jump to line 56, because the condition on line 55 was never true
56 return None if markup is None else QQ if markup else Qq
57 valBare = self.normalize(str(val))
58 if markup is not None: 58 ↛ 60line 58 didn't jump to line 60, because the condition on line 58 was never false
59 valBare = H.he(valBare)
60 return H.a(valBare, valBare) if markup else valBare
63class Email(Text):
64 """Type class for email strings."""
66 pattern = """^[A-Za-z0-9][A-Za-z0-9_.-]*@[A-Za-z0-9_-]+\\.[A-Za-z0-9_.-]+$"""
68 def normalize(self, strVal):
69 normalVal = str(strVal).strip()
70 if not normalVal: 70 ↛ 71line 70 didn't jump to line 71, because the condition on line 70 was never true
71 return E
72 return normalVal
74 def toDisplay(self, val, markup=True):
75 if val is None: 75 ↛ 76line 75 didn't jump to line 76, because the condition on line 75 was never true
76 return None if markup is None else QQ if markup else Qq
77 valBare = self.normalize(str(val))
78 if markup is not None: 78 ↛ 80line 78 didn't jump to line 80, because the condition on line 78 was never false
79 valBare = H.he(valBare)
80 return H.a(valBare, valBare) if markup else valBare
83class Markdown(TypeBase):
84 """Type class for markdown text.
86 The `toDisplay` method will convert the markdown to HTML.
87 """
89 widgetType = N.markdown
91 def normalize(self, strVal):
92 return strVal.strip()
94 def fromStr(self, editVal):
95 return self.normalize(editVal)
97 def toDisplay(self, val, markup=True):
98 if val is None:
99 return None if markup is None else QQ if markup else Qq
100 return H.div(markdown(val)) if markup is True else val
102 def toEdit(self, val):
103 return val
105 def widget(self, val):
106 return H.textarea(val or E, cls="wvalue")