Module tf.browser.wrap
Wrap material into HTML
Lower level functions for wrapping TF data into actual HTML that can be served.
Functions
def pageLinks(nResults, position, spread=10)
-
Expand source code Browse git
def pageLinks(nResults, position, spread=10): """Provide navigation links for results sets, big or small. It creates links around *position* in a set of `nResults`. The spread indicates how many links before and after *position* are generated in each column. There will be multiple columns. The right most column contains links to results `position - spread` to `position + spread`. Left of that there is a column for results `position - spread*spread` to `position + spread*spread`, stepping by `spread`. And so on, until the stepping factor becomes bigger than the result set. """ if spread <= 1: spread = 1 elif nResults == 0: lines = [] elif nResults == 1: lines = [(1,)] elif nResults == 2: lines = [(1, 2)] else: if position == 1 or position == nResults: commonLine = (1, nResults) else: commonLine = (1, position, nResults) lines = [] factor = 1 while factor <= nResults: curSpread = factor * spread first = _coarsify(position - curSpread, curSpread) last = _coarsify(position + curSpread, curSpread) left = tuple( n for n in range(first, last, factor) if n > 0 and n < position ) right = tuple( n for n in range(first, last, factor) if n > position and n <= nResults ) both = tuple( n for n in left + (position,) + right if n > 0 and n <= nResults ) if len(both) > 1: lines.append(both) factor *= spread lines.append(commonLine) html = "\n".join( '<div class="pline">' + " ".join( f'<a href="#" class="pnav {" focus" if position == p else ""}">{p}</a>' for p in line ) + "</div>" for line in reversed(lines) ) return html
Provide navigation links for results sets, big or small.
It creates links around position in a set of
nResults
. The spread indicates how many links before and after position are generated in each column.There will be multiple columns. The right most column contains links to results
position - spread
toposition + spread
.Left of that there is a column for results
position - spread*spread
toposition + spread*spread
, stepping byspread
.And so on, until the stepping factor becomes bigger than the result set.
def passageLinks(passages, sec0Type, sec0, sec1, tillLevel)
-
Expand source code Browse git
def passageLinks(passages, sec0Type, sec0, sec1, tillLevel): """Provide navigation links for passages, in the form of links to sections of level 0, 1 and 2 (books, chapters and verses). If `sec0` is not given, only a list of `sec0` links is produced. If `sec0` is given, but `sec1` not, a list of links for `sec1` within the given `sec0` is produced. If both `sec0` and `sec1` are given, the `sec1` entry is focused. """ sec0s = [] sec1s = [] for s0 in passages[0]: selected = str(s0) == str(sec0) sec0s.append( f'<a href="#" class="s0nav {" focus" if selected else ""}">{s0}</a>' ) if sec0: for s1 in passages[1]: selected = str(s1) == str(sec1) sec1s.append( f'<a href="#" class="s1nav {" focus" if selected else ""}">{s1}</a>' ) return ( f'<div class="sline"><span><span id="s0total"></span>' f' <span class="s0total">{sec0Type}s</span></span>' + "".join(sec0s) + '</div><div class="sline">' + "".join(sec1s) + "</div>" )
Provide navigation links for passages,
in the form of links to sections of level 0, 1 and 2 (books, chapters and verses).
If
sec0
is not given, only a list ofsec0
links is produced.If
sec0
is given, butsec1
not, a list of links forsec1
within the givensec0
is produced.If both
sec0
andsec1
are given, thesec1
entry is focused. def wrapColorMap(form)
-
Expand source code Browse git
def wrapColorMap(form): """Wraps the color map for query result highlighting into HTML. The color map is a dict, keyed by integers (the positions of atoms in a query template) and the values are RGB colours (as string) or the empty string. This dict is stored in `form["colorMap"]`. An extra hidden input field `colormapn` helps to read this dict from the other form elements. """ resetForm = form["resetForm"] if resetForm: colorMap = {} else: colorMap = form["colorMap"] colorMapN = len(colorMap) html = [] html.append( dedent( """ <details id="colormap" class="dstate"> <summary class="ilab">query highlighting</summary> <div> """ ) ) html.append(f"""<input type="hidden" name="colormapn" value="{colorMapN}">""") minC = """<a href="#" id="colormapmin">-</a>""" plusC = """<a href="#" id="colormapplus">+</a>""" empty = colorMapN == 0 for pos in range(1, colorMapN + 2): last = pos == colorMapN past = pos == colorMapN + 1 if past: thisHtml = f"""<div>{plusC}</div>""" if empty else "" else: color = colorMap.get(pos, "") or COLOR_DEFAULT thisHtml = dedent( f""" <div> <input type="color" class="clmap" pos="{pos}" name="colormap_{pos}" value="{color}" > {minC if last else ""} {plusC if last else ""} </div> """ ) html.append(thisHtml) html.append("</div></details>") return "\n".join(html)
Wraps the color map for query result highlighting into HTML.
The color map is a dict, keyed by integers (the positions of atoms in a query template) and the values are RGB colours (as string) or the empty string.
This dict is stored in
form["colorMap"]
. An extra hidden input fieldcolormapn
helps to read this dict from the other form elements. def wrapEColorMap(form)
-
Expand source code Browse git
def wrapEColorMap(form): """Wraps the edge color map for edge highlighting into HTML. The edge color map is a dict, keyed by pairs of integers (the nodes between which there is an edge) and values are RGB colours (as string). Each of the two integers in a pair may also be None (but not both). The color of `(n, None)` is used to color the outgoing edges from `n`, the color of (`(None, n)` is used to color the incoming edges from `n`. This dict is stored in `form["edgeHighlights"]`. An extra hidden input field `ecolormapn` helps to read this dict from the other form elements. """ resetForm = form["resetForm"] if resetForm: edgeHighlights = {} else: edgeHighlights = form["edgeHighlights"] eColorMapN = sum(len(ehl) for ehl in edgeHighlights.values()) html = [] html.append( dedent( """ <details id="edgefeatures" class="dstate"> <summary class="ilab">edge highlighting</summary> <table id="ecolordefs"> """ ) ) html.append(f"""<input type="hidden" name="ecolormapn" value="{eColorMapN}">""") def sortEdges(data): ((f, t), c) = data node = t if f is None else f if t is None else min((f, t)) kind = 2 if f is not None and t is not None else 1 if f is None else 0 return (kind, node, c) pos = 0 for eName in sorted(edgeHighlights): edgeInfo = edgeHighlights[eName] for ((f, t), color) in sorted(edgeInfo.items(), key=sortEdges): pos += 1 fRep = "any" if f is None else f fVal = "any" if f is None else f tRep = "any" if t is None else t tVal = "any" if t is None else t if not color: color = E_COLOR_DEF["t" if f is None else "f" if t is None else "b"] thisHtml = dedent( f""" <tr> <td><span class="ctype">{eName}</span></td> <td> <input type="color" class="eclmap" name="ecolormap_{pos}" value="{color}" > </td> <td><a href="#" pos="{pos}" class="ecolormapmin">-</a></td> <td><span class="nde">{fRep}</span></td> <td><span>{TO_SYM}</td> <td><span class="nde">{tRep}</span></td> </tr> <input type="hidden" name="edge_name_{pos}" value="{eName}"> <input type="hidden" name="edge_from_{pos}" value="{fVal}"> <input type="hidden" name="edge_to_{pos}" value="{tVal}"> """ ) html.append(thisHtml) html.append("</table>") newEHL = dedent( f""" <input type="hidden" name="ecolormap_new_1" value="{E_COLOR_DEF['b']}" > <input type="hidden" name="edge_name_new_1" value=""> <input type="hidden" name="edge_from_new_1" value=""> <input type="hidden" name="edge_to_new_1" value=""> <input type="hidden" name="ecolormap_new_2" value="{E_COLOR_DEF['f']}" > <input type="hidden" name="edge_name_new_2" value=""> <input type="hidden" name="edge_from_new_2" value=""> <input type="hidden" name="edge_to_new_2" value=""> <input type="hidden" name="ecolormap_new_3" value="{E_COLOR_DEF['t']}" > <input type="hidden" name="edge_name_new_3" value=""> <input type="hidden" name="edge_from_new_3" value=""> <input type="hidden" name="edge_to_new_3" value=""> """ ) html.append(newEHL) html.append("</details>") return "\n".join(html)
Wraps the edge color map for edge highlighting into HTML. The edge color map is a dict, keyed by pairs of integers (the nodes between which there is an edge) and values are RGB colours (as string). Each of the two integers in a pair may also be None (but not both). The color of
(n, None)
is used to color the outgoing edges fromn
, the color of ((None, n)
is used to color the incoming edges fromn
.This dict is stored in
form["edgeHighlights"]
. An extra hidden input fieldecolormapn
helps to read this dict from the other form elements. def wrapOptions(context, form)
-
Expand source code Browse git
def wrapOptions(context, form): """Wraps the boolean options, including the app-specific ones, into HTML.""" interfaceDefaults = context.interfaceDefaults defaults = {k: v for (k, v) in interfaceDefaults.items() if v is not None} resetForm = form["resetForm"] html = [] htmlMoved = {} helpHtml = [] for (option, default, acro, desc, long, move) in INTERFACE_OPTIONS: if option not in defaults: continue value = defaults[option] if resetForm else form[option] value = "checked" if value else "" outer = "span" if move else "div" thisHtml = ( f"<{outer}>" f'<input class="r" type="checkbox" id="{acro}" name="{option}" {value}/>' f' <span class="ilab" title="{option}">{desc}</span>' f"</{outer}>" ) helpHtml.append(f'<p><b title="{option}">{desc}</b> {long}</p>') if move: htmlMoved[option] = thisHtml else: html.append(thisHtml) return ("\n".join(html), htmlMoved, "\n".join(helpHtml))
Wraps the boolean options, including the app-specific ones, into HTML.
def wrapProvenance(form, provenance, setNames)
-
Expand source code Browse git
def wrapProvenance(form, provenance, setNames): utc_offset_sec = time.altzone if time.localtime().tm_isdst else time.timezone utc_offset = datetime.timedelta(seconds=-utc_offset_sec) now = ( datetime.datetime.now() .replace(microsecond=0, tzinfo=datetime.timezone(offset=utc_offset)) .isoformat() ) job = form["jobName"] author = form["author"] (appProvenance, dataProvenance) = provenance appHtml = "" appMd = "" sep = "" for d in appProvenance: d = dict(d) backend = d["backend"] bUrl = backendRep(backend, "url") bName = backendRep(backend, "name") org = d["org"] repo = d["repo"] commit = d["commit"] url = f"{bUrl}/{org}/{repo}/tree/{commit}" liveHtml = f'<a href="{url}">{commit}</a>' liveMd = f"[{commit}]({url})" appHtml += f"""\ <div class="pline"> <div class="pname">TF App:</div> <div class="pval">{org}/{repo} on {bName}</div> </div> <div class="p2line"> <div class="pname">commit</div> <div class="pval">{liveHtml}</div> </div>\ """ appMd += f"""{sep}TF app | {org}/{repo} on {bName} commit | {liveMd}""" sep = "\n" dataHtml = "" dataMd = "" sep = "" for d in dataProvenance: d = dict(d) corpus = d["corpus"] version = d["version"] release = d["release"] (liveText, liveUrl) = d["live"] liveHtml = f'<a href="{liveUrl}">{liveText}</a>' liveMd = f"[{liveText}]({liveUrl})" doi = d["doi"] doiUrl = f"{DOI_URL_PREFIX}/{doi}" doiHtml = f'<a href="{doiUrl}">{doi}</a>' if doi else DOI_DEFAULT doiMd = f"[{doi}]({doiUrl})" if doi else DOI_DEFAULT dataHtml += f"""\ <div class="pline"> <div class="pname">Data:</div> <div class="pval">{corpus}</div> </div> <div class="p2line"> <div class="pname">version</div> <div class="pval">{version}</div> </div> <div class="p2line"> <div class="pname">release</div> <div class="pval">{release}</div> </div> <div class="p2line"> <div class="pname">download</div> <div class="pval">{liveHtml}</div> </div> <div class="p2line"> <div class="pname">DOI</div> <div class="pval">{doiHtml}</div> </div>\ """ dataMd += f"""{sep}Data source | {corpus} version | {version} release | {release} download | {liveMd} DOI | {doiMd}""" sep = "\n" setHtml = "" setMd = "" if setNames: setNamesRep = ", ".join(setNames) setHtml += f"""\ <div class="psline"> <div class="pname">Sets:</div> <div class="pval">{setNamesRep} (<b>not exported</b>)</div> </div>\ """ setMd += f"""Sets | {setNamesRep} (**not exported**)""" tool = f"{NAME} {VERSION}" toolDoiUrl = f"{DOI_URL_PREFIX}/{DOI_TF}" toolDoiHtml = f'<a href="{toolDoiUrl}">{DOI_TF}</a>' toolDoiMd = f"[{DOI_TF}]({toolDoiUrl})" html = f""" <div class="pline">\ <div class="pname">Job:</div><div class="pval">{job}</div> </div> <div class="pline"> <div class="pname">Author:</div><div class="pval">{author}</div> </div> <div class="pline"> <div class="pname">Created:</div><div class="pval">{now}</div> </div> {dataHtml} {setHtml} <div class="pline"> <div class="pname">Tool:</div> <div class="pval">{tool} {toolDoiHtml}</div> </div> {appHtml}\ """ md = f""" meta | data --- | --- Job | {job} Author | {author} Created | {now} {dataMd} {setMd} Tool | {tool} {toolDoiMd} {appMd} """ return (html, md)
def wrapSelect(option, allowedValues, value, group, item, multiple)
-
Expand source code Browse git
def wrapSelect(option, allowedValues, value, group, item, multiple): """Provides a buttoned chooser for the node types. Some options need node types as values: `baseTypes`, `condenseType`, `hiddenType`. See `tf.advanced.options`. The chooser supports single value and multiple value mode. Parameters ---------- option: string The name of the option allowedValues: dict Keyed by option, the values are tuples of allowed values for that option in the right order. value: string | set of string The current value of the option. In the case of multiple values, this is a set of values. group: string An extra class name helping to group the relevant buttons together item: string An extra pair of class names for formatting each option line multiple: boolean If `True`, the options appear as check boxes, and multiple values can be selected. Otherwise, the options appear as radio boxes, of which at most one can be selected. Returns ------- string A HTML fragment containing the options with the current value(s) selected. """ html = [] for val in allowedValues[option]: logicValue = val in value if multiple else val == value checked = " checked " if logicValue else "" bType = "checkbox" if multiple else "radio" button = ( f'<input class="r {group}" type="{bType}" name="{option}" value="{val}"' f" {checked}/>" ) html.append( f'<div class="{item[0]}">{button} <span class="{item[1]}">{val}</span></div>' ) return "\n".join(html)
Provides a buttoned chooser for the node types.
Some options need node types as values:
baseTypes
,condenseType
,hiddenType
. Seetf.advanced.options
.The chooser supports single value and multiple value mode.
Parameters
option
:string
- The name of the option
allowedValues
:dict
- Keyed by option, the values are tuples of allowed values for that option in the right order.
value
:string | set
ofstring
- The current value of the option. In the case of multiple values, this is a set of values.
group
:string
- An extra class name helping to group the relevant buttons together
item
:string
- An extra pair of class names for formatting each option line
multiple
:boolean
- If
True
, the options appear as check boxes, and multiple values can be selected. Otherwise, the options appear as radio boxes, of which at most one can be selected.
Returns
string
- A HTML fragment containing the options with the current value(s) selected.