Custom Elements

text_element is the base class other element classes inherit from. It represents a text string that can be converted to various formats.

Each time steno is written, a stroke_text object is created containing the stroke and output text from Plover which is then inserted into the editor. stroke_text objects should make up most of the data in the editor, rather than text_element, used mainly for keyboard input due to edits.

The text in each paragraph of the editor is composed of various elements represent written (steno) text, typed text, or other special kinds of text, all of which subclass the base text_element class.

Each element has text can either be treated as a string of text that can be manipulated (sliced, modified, partially deleted) or as one unit.

Elements are stored together in an element_collection that is then stored in the userData() of a QTextBlock when shown in the GUI editor.

Each text_element (and classes that inherit from it) as well as element_collection can be converted to different representations, such as text, JSON, and RTF, with the to_text() returning the string representation to display in a QTextEdit.

Combining elements

Only strictly text and stroke elements can be combined through __add__ and __radd__, so while automatic_text subclasses stroke_text, the two should not be combined. This is primarily for the use of collapsing elements into word chunks, as pre and pare may be two stroke elements, but should be treated as one for wrapping, otherwise, steno wrapping may wrap in unwanted places.

Manipulating elements in element_collection

Slices of the class ie collection[0:4] is used to obtain element_collection of all elements within the collection in the range start, stop based on the functional lengths of each element. Use extract_steno to use text coordinates.

Indexing of class ie collection[1] is used to access each element of the collection (returns a element_collection class containing only one element). Use .data to access the element itself.

element_collection methods are heavily biased for stroke_text elements relative to other elements.

Checklist for creating a new element

  1. Determine element functional length

  2. Add any new attributes, check if ODF spec has corresponding equivalent, and use same names if possible

  3. Create:

    1. QTextEdit representation (to_text),

    2. letter to use in steno display (to_display),

    3. export text (if different from text) (to_export)

  4. Check if RTF spec or RTF/CRE spec has corresponding equivalent, then create formatted string by overriding, otherwise, just simple text (to_rtf)

  5. Create ODF element by overriding, otherwise just simple text (to_odf)

  6. Determine if element needs updating methods or not.

  7. Add to element_factory so able to generate element

  8. Create QUndoCommand if necessary, and add to element_actions generator

  9. Create GUI/shortcuts/functions for insertion

Element Classes

class steno_objects.text_element(text='', time=None)

Bases: UserString

The base text element used in editor.

Parameters:
  • text (str) – string that can be set

  • time (str) – time element is created in ISO milliseconds format

element

type of element, text

__len__()

return length of string

split()

Splits text string on whitespace (re from textwrapper).

Returns:

s list of elements containing each text piece separately, but same otherwise as original

Return type:

list

__add__(other)

Adds together text, and updates time from other.

Parameters:

other (text_element) – any type of element

Returns:

text_element object with updated attributes

Return type:

text_element

Raises:

NotImplemented – if type of other not text_element

__radd__(other)

Override __radd__ from Userstring so inherited classes can override.

Raises:

NotImplemented – __radd__ should not be needed with purely text_element objects

__getitem__(key)

Get from class dict based on key.

Parameters:

key – key

Returns:

returns new instance of class after deepcopy

__repr__()

Return representation as dict.

length()

Return functional length.

Returns:

functional length of element, length of text string

Return type:

int

from_dict(dictionary)

Populate class using a dict.

to_display()

Formatted string for display in GUI.

Should be a string for three lines, 1) icon letter, 2) element data, if any, 3) text

to_json()

Return dict of attributes.

to_text()

Return “text” representation as imagined for QTextEdit.

to_export()

Return text string for exported formats

to_rtf()

Return string representation with control groups from RTF/CRE spec as necessary.

to_odt(paragraph, document)

Populate ODF paragraph element with instance text.

Parameters:
  • paragraph – odfpy paragraph element

  • document – odfpy document that the paragraph (will) belongs to

replace_initial_tab(expand='    ')

Replace first tab in string.

Parameters:

expand (str) – string to replace tab with, default four spaces

class steno_objects.dummy_element(**kargs)

Bases: text_element

Dummy element used for testing.

element

type of element, `dummy`

length()

Return functional length.

Returns:

functional length of element, length of text string

Return type:

int

class steno_objects.pagebreak_element(**kargs)

Bases: text_element

Page break element for editor

__add__(other)

Adds together text, and updates time from other.

Parameters:

other (text_element) – any type of element

Returns:

text_element object with updated attributes

Return type:

text_element

Raises:

NotImplemented – if type of other not text_element

length()

Return functional length.

Returns:

functional length of element, length of text string

Return type:

int

to_display()

Formatted string for display in GUI.

Should be a string for three lines, 1) icon letter, 2) element data, if any, 3) text

to_rtf()

Return string representation with control groups from RTF/CRE spec as necessary.

to_text()

Return “text” representation as imagined for QTextEdit.

to_odt(paragraph, document)

Populate ODF paragraph element with instance text.

Parameters:
  • paragraph – odfpy paragraph element

  • document – odfpy document that the paragraph (will) belongs to

class steno_objects.stroke_text(stroke='', audiotime='', **kargs)

Bases: text_element

Stroke element used in editor.

Parameters:
  • stroke (str) – steno outline, separated by slashes

  • audiotime (str) – time of media at time of stroke

element

Type of element, stroke.

__add__(other)

Adds together stroke elements or stroke and text elements. Will only combine elements but not across word boundaries (spaces), can accept stroke_text and text_element but not others while updating necessary attributes.

Parameters:

other (stroke_element or text_element) – stroke_element or text_element

Returns:

stroke_text object with updated attributes

Return type:

stroke_text

Raises:

TypeError – if type of other not correct

__radd__(other)

Add together elements.

Parameters:

othertext_element object

Returns:

stroke_text object with updated attributes

Return type:

stroke_text

Raises:
  • NotImplemented – if type of other is not text_element

  • ValueError – if trying to combine across word boundaries

to_rtf()

Return string representation with control groups from RTF/CRE spec as necessary.

to_display()

Formatted string for display in GUI.

Should be a string for three lines, 1) icon letter, 2) element data, if any, 3) text

class steno_objects.image_text(path=None, width=None, height=None, **kargs)

Bases: text_element

Image element used in editor.

Parameters:
  • path (str or Path) – path to image

  • width (int) – pixel width of image

  • height (int) – pixel height of image

data

Representation of image when image cannot be rendered.

element

Type of element, image.

__add__(other)

Addition of elements to image is not allowed.

Raises:

NotImplemented – images cannot add or be added to other elements.

length()

Return functional length of image_text, 1.

Returns:

1

Return type:

int

to_display()

Formatted string for display in GUI.

Should be a string for three lines, 1) icon letter, 2) element data, if any, 3) text

to_rtf()

Return string representation with control groups from RTF/CRE spec as necessary.

to_odt(paragraph, document)

Populate ODF paragraph element with instance text.

Parameters:
  • paragraph – odfpy paragraph element

  • document – odfpy document that the paragraph (will) belongs to

class steno_objects.text_field(name=None, user_dict=plover_cat.constants.user_field_dict, **kargs)

Bases: text_element

Field element to use in editor.

Parameters:
  • name (str) – name of field

  • user_dict (dict) – transcript field dict, uses default user_field_dict if not supplied

element

Type of element, field

__add__(other)

No element can be added. Force use of __radd__.

Raises:

NotImplemented – addition not allowed

length()

Return functional length, 1

Returns:

1

Return type:

int

to_json()

Return dict of attributes.

to_display()

Formatted string for display in GUI.

Should be a string for three lines, 1) icon letter, 2) element data, if any, 3) text

to_text()

Return “text” representation as imagined for QTextEdit.

update()

Update data for display. Check the user_dict and assigns value to data, “updating” if the value in the dict for the name has been changed. The user_field_dict by default uses the global user_field_dict object. Need to specify if a different dict is to be used.

to_rtf()

Return string representation with control groups from RTF/CRE spec as necessary.

to_odt(paragraph, document)

Populate ODF paragraph element with instance text.

Parameters:
  • paragraph – odfpy paragraph element

  • document – odfpy document that the paragraph (will) belongs to

class steno_objects.automatic_text(prefix='', suffix='', **kargs)

Bases: stroke_text

Automatic text element for editor, text added by editor, not user.

Use for text such as Q , ie set directly for question style.

Parameters:
  • prefix (str) – text to appear before string

  • suffix (str) – text to appear after string

element

Type of element, automatic

__add__(other)

No element can be added. Force use of __radd__.

Raises:

NotImplemented – addition not allowed.

__radd__(other)

No element can be added.

Raises:

NotImplemented__radd__ not allowed.

__len__()

Return length of prefix + text + suffix.

to_text()

Return “text” representation as imagined for QTextEdit.

length()

Return length of data, compare to __len__().

to_rtf()

Return string representation with control groups from RTF/CRE spec as necessary.

to_display()

Formatted string for display in GUI.

Should be a string for three lines, 1) icon letter, 2) element data, if any, 3) text

class steno_objects.conflict_text(choices=None, **kargs)

Bases: stroke_text

Not yet implemented

class steno_objects.index_text(prefix='Exhibit', indexname=0, description='', hidden=True, **kargs)

Bases: text_element

Index entry element for editor.

Parameters:
  • prefix (str) – prefix to place before “number”

  • indexname (int) – index that index entry belongs to

  • description (str) – index entry description

  • hidden (bool) – whether description should be shown in editor or hidden

element

Type of element, index

__add__(other)

No element can be added. Force use of __radd__.

Raises:

NotImplemented – addition not allowed.

__len__()

Return length of index entry text, may or may not include description.

length()

Return functional length, 1

Returns:

1

Return type:

int

to_text()

Return “text” representation as imagined for QTextEdit.

to_display()

Formatted string for display in GUI.

Should be a string for three lines, 1) icon letter, 2) element data, if any, 3) text

to_odt(paragraph, document)

Populate ODF paragraph element with instance text.

Parameters:
  • paragraph – odfpy paragraph element

  • document – odfpy document that the paragraph (will) belongs to

to_rtf()

Return string representation with control groups from RTF/CRE spec as necessary.

class steno_objects.redact_text(**kargs)

Bases: text_element

Not yet implemented

to_display()

Formatted string for display in GUI.

Should be a string for three lines, 1) icon letter, 2) element data, if any, 3) text

to_text()

Return “text” representation as imagined for QTextEdit.

steno_objects.translate_coords(len1, len2, pos)

Translate position from one sequence of cumulative lengths to another.

Parameters:
  • len1 (list[int]) – cumulative text lengths of elements (ie in display of editor)

  • len2 (list[int]) – cumulative functional lengths of elements, can be 1 or other int

  • pos (int) – position from first sequence to translate

Returns:

position in second sequence

Return type:

int

steno_objects.backtrack_coord(pos, backspace, text_len, func_len)

Return position after backspace, accounting for functional length of elements.

Parameters:
  • pos (int) – initial position in text

  • backspace (int) – hypothetical backspaces to mock

  • text_len (list[int]) – text lengths of elements

  • func_len (list[int]) – functional lengths of elements

Returns:

position after hypothetical backspaces, may be negative if more backspaces than length

Return type:

int

class steno_objects.element_factory

Bases: object

Factory for creating elements from data dict

gen_element(element_dict, user_field_dict=plover_cat.constants.user_field_dict)

Return element based on type.

Parameters:
  • element_dict (dict) – dict of element, likely from dict representation

  • user_field_dict (dict) – user field data

Returns:

element

Return type:

text_element or subclass

class steno_objects.element_collection(data=None)

Bases: UserList

Container for holding elements in list.

__str__()

Return string representation of all elements in container.

lengths()

Return list of functional lengths for each element.

lens()

Return list of “text” lengths for each element.

__len__()

Returns sum of len for each element.

__getitem__(key)

Return element_collection instance with copy of element(s) based on key.

element_count()

Return number of elements in collection, len of a list.

to_json()

Return list of serialized dict objects.

to_text()

Return text string combining all elements.

to_rtf()

Return string containing RTF representations of elements.

to_odt(paragraph, document)

Add each element to paragraph in ODF document

to_display()

Return list of display strings for elements

to_strokes()

Return strin with all strokes

remove(start, end)

Remove elements based on specified functional position start/stop.

Parameters:
  • start (int) – start position for remove

  • end (int) – end position for remove

Returns:

removed elements

Return type:

element_collection

insert(i, item)

Insert based on functional position. :param int i: position :param item: data to be inserted :return: item

stroke_pos_at_pos(pos)

Returns tuple of text start, stop for element at text pos.

element_pos(index)

Returns tuple of text start, stop for element at index in collection.

remove_steno(start, end)

Removes elements from start to end (text) position.

Returns:

element(s) removed

Return type:

element_collection

extract_steno(start, end)

Retrieve elements from start to end (text) position.

This does not modify original collection.

Parameters:
  • start (int) – starting text position

  • end (int) – ending text position

Returns:

element(s) between coordinates

Return type:

element_collection

insert_steno(pos, item)

Insert at text position.

This will split an element in collection if needed.

Parameters:
  • pos (int) – text position

  • itemelement_collection or single element

Returns:

item

starts_with(char)

Check if text starts with char.

Parameters:

char (str) – text to check

Returns:

True if collection text does start with char, False otherwise

Return type:

bool

ends_with(char)

Check if text ends with char

Parameters:

char (str) – text to check

Returns:

True if collection text ends with ``char, False otherwise

Return type:

bool

starts_with_element(element_type)

Check if first element is of type.

Parameters:

element_type (str) – any of the types for text_element or subclasses

Returns:

True if first element type matches element_type, False otherwise

Return type:

bool

ends_with_element(element_type)

Check if last element is of type.

Parameters:

element_type (str) – any of the types for text_element or subclasses

Returns:

True if last element type matches element_type, False otherwise

Return type:

bool

remove_end(char='\n')

Remove char end of text string for collection.

This will remove entire element if char is only text in element.

Parameters:

char (str) – string to remove, default \n

remove_begin(char)

Remove char from first element if text starts with char.

Parameters:

char (str) – string to remove

add_begin(char=' ')

Add char to beginning of first element.

Parameters:

char (str) – string to add, default one space character

add_end(char=' ')

Add char to end of last element.

Parameters:

char (str) – string to add, default one space character

stroke_count()

Counts the number of strokes in collection.

search_strokes(query)

Return text positions for matches to underlying strokes.

Parameters:

query (str) – steno outline

Returns:

tuple of start and end positions, None if no match

search_text(query)

Return text positions for matches to text.

Parameters:

query (str) – search text

Returns:

results of re.finditer search

collection_time(reverse=False)

Return earliest/latest timestamp in collection.

Parameters:

reverse (bool) – True by default for earliest, False for latest

Returns:

formatted timestamp string

audio_time(reverse=False)

Return earliest/latest audio timestamp in collection.

Parameters:

reverse (bool) – True by default for earliest, False for latest

Returns:

formatted timestamp string

replace_initial_tab(tab_replace='    ')

Replace initial tab in place within collection.

Parameters:

tab_replace (str) – string to replace tab character with, default four spaces

merge_elements()

Collapse collection elements using __add__ method.

class steno_objects.steno_wrapper(**kargs)

Bases: TextWrapper

Wrap text, but adapted for elements in element_collection.

Returns:

a list of lists of elements, not element_collection.

wrap(text: string) [string]

Reformat the single paragraph in ‘text’ so it fits in lines of no more than ‘self.width’ columns, and return a list of wrapped lines. Tabs in ‘text’ are expanded with string.expandtabs(), and all other whitespace characters (including newline) are converted to space.