Text highlighting¶
HighlightedText(source, layers=None)
Highlighting of a text by layers, in the manner of the style checkers: every layer marks the fragments of a text that a statistic counts - long sentences, complex words, the passive. The data source is a text or a Doc object of spaCy. The result shows in Jupyter as HTML with styles and a legend; to_html returns the markup, and highlights keeps the fragments for a rendering of one's own. Fragments of different layers may overlap.
Raises:
SourceTypeError- a source that is neither a string nor aDoc;SourceError- a source without words;ParameterError- layers that are not a name or a list of names, a layer that is unknown or one that needs an annotation the source lacks.
A layer of the long sentences in a subclass.
from anyts.visualizers import Highlight, HighlightedText
class Highlighter(HighlightedText):
layers_desc = {"long_sents": "long sentence"}
default_layers = ("long_sents",)
layer_styles = {"long_sents": "background: #fef9c3;"}
css_prefix = "demo"
def find(self, layer, words, sents, doc):
return [
Highlight(sent.start, sent.end, layer, f"{sent.n_words} words")
for sent in sents
if sent.n_words >= 8
]
ht = Highlighter("The cat sleeps. The dog barks at the cat that sleeps on the mat.")
ht.highlights
(Highlight(start=16, end=64, layer='long_sents', note='11 words'),)
Parameters¶
| Parameter | Type | Default | Description |
|---|---|---|---|
source |
str / Doc |
- | Data source (a string or a Doc object) |
layers |
list[str] / str |
None |
Layers of the highlighting; if not given, the default layers the source allows; "all" - every layer allowed |
Attributes¶
| Attribute | Type | Description |
|---|---|---|
text |
str |
Text of the data source |
layers |
tuple[str] |
Layers turned on, in the order of drawing |
highlights |
tuple[Highlight] |
Highlighted fragments, sorted by their start and then by descending end |
counts |
dict[str, int] |
Number of fragments of every layer |
Highlight(start, end, layer, note='')
A fragment of the highlighting: an immutable object with the parameters as its fields.
| Field | Type | Default | Description |
|---|---|---|---|
start |
int |
- | Position of the first character of the fragment in the text |
end |
int |
- | Position after the last character of the fragment |
layer |
str |
- | Layer of the highlighting |
note |
str |
'' |
Explanation of the fragment for the tooltip |
Methods¶
to_html(legend=True, css=True) returns the HTML markup of the highlighted text: a div of the class <prefix>-highlight with the legend, its counts and the text, where a highlighted segment is a span of the classes <prefix>-hl and <prefix>-hl-<layer> with the notes in its title; <prefix> is css_prefix. Overlapping fragments of different layers give segments with several classes, in the order of drawing. Line breaks (\n, \r\n, \r) become character references, one per break, so the markup can go into Markdown.
| Parameter | Type | Default | Description |
|---|---|---|---|
legend |
bool |
True |
Add the legend with the counts of the fragments |
css |
bool |
True |
Add the styles of the layers |
The class method css() returns the styles to_html adds: the container, the legend and the text under the classes of css_prefix, the declarations of layer_styles for every layer, and a dark colour of the text on the layers with a background.
ht.to_html(legend=False, css=False)
'<div class="demo-highlight"><div class="demo-highlight-text">The cat sleeps. <span class="demo-hl demo-hl-long_sents" title="11 words">The dog barks at the cat that sleeps on the mat.</span></div></div>'
Helpers of the layers¶
The helpers and the finders of the layers are in anyts.visualizers.highlight.
Word(start, end, text, pos=None, lemma=None)
A word with its position in the text and, when known, its part of speech and lemma.
Sent(start, end, n_words)
A sentence with its position and number of words.
get_doc_words(doc)
The words of iter_doc_tokens with their positions, a byte order mark at the start of the text left out, with the part of speech and the lemma when the Doc has them.
iter_doc_sents(doc)
The sentences of the boundaries of a Doc as triples of the start, the end and the text; the whitespace tokens at the edges of a sentence are left out, and a sentence of whitespace alone is skipped.
get_text_sents(spans, words)
The sentences given by their positions with their numbers of words; a word belongs to the sentence of its first character.
group_words_by_sents(words, sents)
The words of every sentence; the words out of the sentences are skipped.
tokens_span(tokens)
The positions of the fragment that covers some tokens, without the punctuation and the whitespace at its edges.
split_segments(length, highlights)
The segments of a text with the same set of fragments: their bounds are the starts and the ends of all the fragments, and overlapping or nested fragments give segments with several layers.
Finders of the layers¶
The layers the languages share are found by functions that take the language as parameters: the notes of the fragments (callables where they read a number, so a language writes its plural forms; English by default), the counts of syllables, the normalized forms of the words, the stems, the matcher of the connectors. A subclass calls them from its find. A value that cannot be called for a parameter that takes a function, such as count_syllables, normalize or stem, raises SourceTypeError.
Long sentences¶
find_long_sents(sents, long_sent_word_factor, note=None)
The layer long_sents: the sentences of long_sent_word_factor words or more.
| Parameter | Type | Default | Description |
|---|---|---|---|
sents |
list[Sent] |
- | Sentences with their positions and numbers of words |
long_sent_word_factor |
int |
- | Minimum number of words of a long sentence |
note |
Callable[[int], str] |
None |
Note of a sentence by its number of words |
A long_sent_word_factor that is not an integer of at least one raises ParameterError.
Complex words¶
find_complex_words(words, complex_syl_factor, count_syllables, note=None)
The layer complex_words: the words of complex_syl_factor syllables of count_syllables or more.
| Parameter | Type | Default | Description |
|---|---|---|---|
words |
list[Word] |
- | Words with their positions |
complex_syl_factor |
int |
- | Minimum number of syllables of a complex word |
count_syllables |
Callable[[str], int] |
- | Number of the syllables of a word |
note |
Callable[[int], str] |
None |
Note of a word by its number of syllables |
A complex_syl_factor that is not an integer of at least one raises ParameterError.
Single words¶
find_words(words, is_match, layer, note='')
A layer of single words, such as stopwords, rare words or verbal nouns: the words the check is_match of a language accepts.
| Parameter | Type | Default | Description |
|---|---|---|---|
words |
list[Word] |
- | Words with their positions, parts of speech and lemmas |
is_match |
Callable[[Word], bool] |
- | Whether a word is a fragment of the layer |
layer |
str |
- | Layer of the highlighting |
note |
str |
'' |
Note of every fragment |
Phrases¶
find_phrase_highlights(words, phrases, layer, note=None, normalize=str.lower)
A layer of the phrases of a list, such as compound prepositions, clichés or parentheticals. The phrases are matched by the normalized forms of their words, each normalized alone as in the text (find_phrases). A mapping gives their variants - contractions, forms of verbs - with the phrase each stands for; of the variants that normalize alike the first wins. A set of phrases is read in order (in_order). A fragment spans the phrase in the text; its note reads the phrase of the list, in quotes by default.
| Parameter | Type | Default | Description |
|---|---|---|---|
words |
list[Word] |
- | Words with their positions |
phrases |
list[str] / dict[str, str] |
- | Phrases, words separated by spaces, or their variants with the phrase of each |
layer |
str |
- | Layer of the highlighting |
note |
Callable[[str], str] |
None |
Note of a fragment by its phrase |
normalize |
Callable[[str], str] |
str.lower |
Normalized form of a word |
Phrases that are not a collection of strings or a mapping of strings raise SourceTypeError.
Connectors¶
find_connector_highlights(words, sents, matcher, note=None, pos=None, text=None, blocked=None)
The layer connectors: the connectors of a ConnectorMatcher of the language inside every sentence, in the whole text when the sentences are None; a one-word connector is checked by its part of speech when a word of the sentence has one - its own, or that of the hook pos. With the text, a character of is_punctuation between two words is a punctuation mark, which the rules of the matcher do not read through; a quote, an apostrophe and the hyphen that joins two parts of a word are none. No connector starts at a word the hook blocked rules out, such as one its parse makes no connector. The note gives the text, the class and the kind of the connector by default.
| Parameter | Type | Default | Description |
|---|---|---|---|
words |
list[Word] |
- | Words with their positions and parts of speech |
sents |
list[Sent] |
- | Sentences with their positions |
matcher |
ConnectorMatcher |
- | Matcher of the connectors of a language |
note |
Callable[[Connector], str] |
None |
Note of a connector |
pos |
Callable[[Word], str] |
None |
Part of speech of a word for the matcher |
text |
str |
None |
Text of the words, for the punctuation marks between them |
blocked |
Callable[[Word], bool] |
None |
Whether no connector starts at a word |
A hook that cannot be called or a text that is not a string raises SourceTypeError.
Split predicates¶
find_split_predicate_highlights(pairs, note=None)
The layer split_predicates: a fragment for every pair of a light verb and its noun a language finds, from the first word of the pair to the last; the note reads their lemmas by default.
| Parameter | Type | Default | Description |
|---|---|---|---|
pairs |
list[tuple[Token, Token]] |
- | Light verb and noun of every split predicate |
note |
Callable[[Token, Token], str] |
None |
Note of a pair |
Runs of alliteration¶
calc_alliteration_runs(words, frequencies, threshold=0.001, stem=list, is_transparent=None)
The runs of two or more neighbouring words with a consonant of frequencies in the stem of each (the stem of a language leaves out the endings that repeat by agreement) and a probability below the threshold. The probability under an independent spread of the consonants is the product over the words of \(1 - (1 - f)^n\), \(f\) the frequency of the consonant and \(n\) the length of the stem. A transparent word - by default one shorter than ALLITERATION_MIN_WORD_LEN (3) letters, a stopword for a language - neither breaks nor continues a run; the words are taken in lower case. A run is a triple of the index of its first word, the index after its last word and its consonant, in the order of the text.
| Parameter | Type | Default | Description |
|---|---|---|---|
words |
list[str] |
- | Words of a sentence |
frequencies |
dict[str, float] |
- | Consonants to look for with their frequencies |
threshold |
float |
0.001 |
Probability threshold (anyts.constants.ALLITERATION_THRESHOLD) |
stem |
Callable[[str], list[str]] |
list |
Sounds or letters of the stem of a word; the letters of the word by default |
is_transparent |
Callable[[str], bool] |
None |
Whether a word neither breaks nor continues a run |
Words that are not a list of strings and frequencies that are not a mapping of strings to numbers raise SourceTypeError, and a frequency outside [0, 1] or a threshold outside (0, 1] ParameterError.
Alliteration¶
find_alliteration(words, sents, frequencies, threshold=0.001, stem=list, is_transparent=None, note=None)
The layer alliteration: the runs of calc_alliteration_runs inside every sentence, in the whole text when the sentences are None.
| Parameter | Type | Default | Description |
|---|---|---|---|
words |
list[Word] |
- | Words with their positions |
sents |
list[Sent] |
- | Sentences with their positions |
frequencies |
dict[str, float] |
- | Consonants to look for with their frequencies, as in calc_alliteration_runs |
threshold |
float |
0.001 |
Probability threshold (anyts.constants.ALLITERATION_THRESHOLD) |
stem |
Callable[[str], list[str]] |
list |
Sounds or letters of the stem of a word; the letters of the word by default |
is_transparent |
Callable[[str], bool] |
None |
Whether a word neither breaks nor continues a run |
note |
Callable[[str], str] |
None |
Note of a run by its consonant |
The frequencies and the threshold raise the errors of calc_alliteration_runs.
For library developers¶
Language hooks of a subclass
The core has no layers of its own: a language library subclasses HighlightedText and sets its layers and their search.
| Hook | Kind | Description |
|---|---|---|
layers_desc |
class attribute | The layers in the order of drawing with their names in the legend, dict[str, str] |
default_layers |
class attribute | The layers on by default, among those the source allows, tuple[str] |
layer_annotations |
class attribute | The annotations of a Doc a layer needs (DEP, POS, LEMMA...), dict[str, tuple[str]]; a layer without them is available for a string too |
layer_styles |
class attribute | The CSS declarations of every layer, dict[str, str]; the text of a layer with a background keeps a dark colour on it |
css_prefix |
class attribute | The prefix of the CSS classes, str |
find(layer, words, sents, doc) |
method | The fragments of a layer: a list of Highlight from the words and the sentences of the text and the Doc (None for a string) |
iter_words(text), iter_sents(text) |
methods | The words and the sentences of a string as triples of the start, the end and the text; by default those of the default tokenizers of WordsExtractor and SentsExtractor |
doc_words(doc) |
method | The words of a Doc; by default get_doc_words |
annotation_names |
class attribute | Names of the annotations in the message of a layer a source does not allow, dict[str, str]; English by default |
messages |
class attribute | Messages of the errors by key; MESSAGES by default |
The sentences of a Doc come from its boundaries, or from iter_sents over its text when it has none or partial ones (has_sents). iter_sents gets the parts of a text between blank lines one by one, so a blank line always ends a sentence; a sentence holds the words of doc_words or iter_words that start in it. find runs in __init__: a subclass stores its own parameters, checked by check_params, before calling the __init__ of the base, and may find its layers with the finders of the layers. A fragment of another layer, an empty one or one outside the text raises ParameterError; a find that does not return Highlight objects, and an iter_words or an iter_sents whose triples are not ascending integer bounds inside the text with the text of each, SourceTypeError.
In the core the layers are empty and css_prefix is anyts.
check_params(long_sent_word_factor, complex_syl_factor, alliteration_threshold, *, messages=MESSAGES)
Checks the parameters of the highlighting: a number of words or syllables that is not an integer of at least one, or a threshold outside the interval (0, 1], raises ParameterError.