Library Documentation
In addition to the easy to use command-line script, you can also write programs using the purdy library. The purdy command-line script uses this library to display a simple file to the screen.
Example Program
# reads 'my_code.py' and displays it to the screen with line numbers
from purdy.actions import Append
from purdy.content import Code
from purdy.ui import SimpleScreen
# Screen is the entry to showing content
screen = SimpleScreen(starting_line_number=1)
# Screen has one display area called "code_box", your actions need access
# to this to write the code
code_box = screen.code_box
# read 'my_code.py' and parse it using the Python 3 lexer
blob = Code('code.py', lexer_name='py3')
# actions are like slides in the slides show that is purdy
actions = [
# append the contents of the blob to the display code box
Append(code_box, blob),
]
# start the display event loop
screen.run(actions)
Every purdy library program needs to create a
Screen
or one of its children. The Screen is what
controls the display. Screen
and its children
provide one or more CodeBox
objects which is a
widget on the screen that displays code. You combine a series of
purdy.ui.actions
to display and alter the code. View more examples in
the Sample Code section.
Library API
UI (purdy.ui.py)
This module is the entry point for the code viewers. It is a lightweight proxy
to implementation of a screen. Screen implementations are found in
purdy.iscreen
. All programs using the purdy library need to create a
Screen
object or one of its children. The factory in this module
determines which actual implementation is loaded.
- class purdy.ui.CodeBox(starting_line_number=-1, auto_scroll=True, height=0, compact=False)
Specifies a box to contain code.
Screen
uses these to determine widget layout, subsequent actions are done within the context of this box. WhenCodeBox.build()
is called by aScreen
class a widget is built and this box is added to the screen.- Parameters:
starting_line_number – -1 means no line numbers, anything larger will be the first line number displayed. Defaults to -1
auto_scroll – When True,
purdy.widgets.CodeBox
created by this specification automatically scrolls to newly added content. Defaults to True.height – Number of lines the row containing this box should be. A value of 0 indicates automatic spacing. Defaults to 0.
compact – if False, the dividing line between this box and the next has a 1-line empty boundary. Parameter is ignored if there is no item after this one in the rows=[] listing. Defaults to False
- class purdy.ui.Screen(settings=None, rows=[], max_height=0)
Represents the main UI window for the TUI application. The layout is specified by passing in one or more
CodeBox
orTwinCodeBox
objects to the constructor. Each box will have a correspondingpurdy.widgets.CodeWidget
inside of the UI for displaying code.- Parameters:
settings – a settings dictionary object. Defaults to None which uses the default settings dictionary:
settings.settings
rows – a list containing one or more
CodeBox
orTwinCodeBox
definitions, to specify the layout of the screenmax_height – maximum display height in TUI mode, defaults to 0, meaning no max
Example:
from purdy.actions import AppendAll from purdy.content import Code from purdy.ui import Screen, CodeBox, TwinCodeBox screen = Screen(rows=[TwinCodeBox(height=8), CodeBox(auto_scroll=False)]) c1 = Code(contents_filename='c1.py', starting_line_number=1) c2 = Code(contents_filename='c2.py') c3 = Code(contents_filename='c3.py') actions = [ AppendAll(screen.code_boxes[0], c1), AppendAll(screen.code_boxes[1], c2), AppendAll(screen.code_boxes[2], c3), ] screen.run(actions)
The above would produce a screen with two rows, the first row having two
purdy.widgets.CodeWidget
objects side by side, the second having a single one. The top left box would have line numbers turned on, both top boxes are 8 lines tall, and the bottom box has auto scrolling turned off.The screen would be divided like this:
Command Line Parameters
Unless “deactivate_args” is set to True in
purdy.settings
(False by default), Screen will also parse command line arguments. This allows scripts calling the library to change their behaviour with switches.Supported switches are:
–debugsteps Print out the animation steps, grouped by Cell and exit
–export Print out the results of the actions
–exportrtf Print out the results of the actions in RTF format
- run(actions)
Calls the main display event loop. Does not return until the UI exits.
- class purdy.ui.SimpleScreen(settings=None, starting_line_number=-1, auto_scroll=True, max_height=0)
Convenience implementation of
Screen
that supports a singleCodeBox
. The code box is available asSimpleScreen.code_box
.- Parameters:
settings – a settings dictionary object. Defaults to None which uses the default settings dictionary:
settings.settings
starting_line_number – starting line number for the created code box
auto_scroll – When True, the class:ui.CodeBox automatically scrolls to newly added content. Defaults to True.
max_height – maximum display height in TUI mode, defaults to 0, meaning no max
- class purdy.ui.SplitScreen(settings=None, top_starting_line_number=-1, top_auto_scroll=True, bottom_starting_line_number=-1, bottom_auto_scroll=True, top_height=0, compact=False, max_height=0)
Convenience implementation of
Screen
that supports twoCodeBox
instances, stacked vertically and separated by a dividing line. The code boxes areSplitScreen.top
andSplitScreen.bottom
.- Parameters:
settings – a settings dictionary object. Defaults to None which uses the default settings dictionary:
settings.settings
top_starting_line_number – starting line number for the top code box
top_auto_scroll – When True, the top
ui.CodeBox
automatically scrolls to newly added content. Defaults to True.bottom_starting_line_number – starting line number for the bottom code box
bottom_auto_scroll – When True, the bottom
ui.CodeBox
automatically scrolls to newly added content. Defaults to True.top_height – Number of lines the top box should be. A value of 0 indicates top and bottom should be the same size. Defaults to 0.
compact – True if for the dividing line between the top and bottom screens is to have no margin. Defaults to False
max_height – maximum display height in TUI mode, defaults to 0, meaning no max
- class purdy.ui.TwinCodeBox(left_starting_line_number=-1, left_auto_scroll=True, left_weight=1, right_starting_line_number=-1, right_auto_scroll=True, right_weight=1, height=0, compact=False)
Specifies two side-by-side CodeBoxes. The contained CodeBoxes can be either accessed as twin.left and twin.right, or twin[0] and twin[1]. When
TwinCodeBox.build()
is called, the widgets are created and added to theScreen.code_boxes
list sequentially, i.e. a single TwinCodeBox results in two CodeBox items in Screen’s list.- Parameters:
left_starting_line_number –
right_starting_line_number – -1 to turn line numbers off, any higher value is the first number to display. Defaults to -1
left_auto_scroll –
right_auto_scroll – True to specify that scrolling happens automatically for the left and right boxes created by this spec. Defaults to True.
left_weight –
right_weight – relative weights for the widths of the columns, if the values are the same then the columns are the same width, otherwise the widths are formed based on the ratio of left:right. Example: left_weight=2, right_weight=1 means the left side will be twice the width of the right side. Both values default to 1.
height – number of lines for the row this set of boxes is in. The default of 0 specifies automatic height
compact – if False, the dividing line between this box and the next has a 1-line empty boundary. Parameter is ignored if there is no item after this one in the rows=[] listing. Defaults to False
Content
Reperesntations of source code are found in this module.
- class purdy.content.Code(filename='', text='', lexer_name='detect', purdy_lexer=None)
Represents source code from the user.
- Parameters:
filename – name of a file to read for content. If both this and text is given, filename is used first
text – a string containing code
lexer_name – name of lexer to use to tokenize the code, defaults to ‘detect’, attempting to auto detect the type of content. See
purdy.parser.PurdyLexer
for a list of available lexers.purdy_lexer – if lexer_name is “custom” this parameter is expected to contain a purdy.parser.PurdyLexer object.
- fold_lines(start, end)
Call this method to replace one or more lines with a vertical elipses, i.e. a fold of the code.
- Parameters:
start – line number of the listing to start code folding on. 1-indexed.
end – line number to fold until, inclusive (1-indexed).
- inline_replace(line_no, pos, content)
Replaces the contents of a line starting at pos with the new content
- Parameters:
line_no – number of the line to replace, 1-indexed
pos – position number to start the replacement at, 1-indexed
content – content to replace with
- insert_line(line_no, content)
Inserts the given line into the source, pushing the content down from the given line number
- Parameters:
line_no – number of the line to insert at, 1-indexed
content – content to insert
- left_justify()
Removes a consistent amount of leading whitespace from the front of each line so that at least one line is left-justified.
Warning
will not work with mixed tabs and spaces
- python_portion(name, header=None)
Treates the source in this object as Python and then finds either the named function, class, or assigned variable and replaces the source with only the found item.
Warning
If the named item is not found your source will be empty!
- Parameters:
name – dot notated name of a function or class. Examples: Foo.bar would find the bar method of class Foo or an inner function named bar in a function named Foo
header – optionally include another part of the source file before the parsed content. Typically used to include the header portion of a file. If given an integer, it will include the first X number of lines. If given a tuple “(x, y)” includes lines from x to y (inclusive)
- remove_double_blanks(trim_whitespace=True)
Removes the second of two blanks in a row. If trim_whitespace is True (default) a line with only whitespace is considered blank, otherwise it only looks for n
- remove_lines(line_no, count=1)
Removes one or more lines from the source listing.
- Parameters:
line_no – number of the line to remove, 1-indexed
count – number of lines to remove, defaults to 1
- replace_line(line_no, content)
Replaces the given line with new content
- Parameters:
line_no – number of the line to replace, 1-indexed
content – content to replace it with
- subset(start, end)
Returns a new Code object containing just the subset of lines identified in this call
- Parameters:
start – line number of the listing to start the subset at. 1-indexed
end – line number to finish the subset on, inclusive. 1-indexed.
- Returns:
Code object
Actions
Library users specify a series of actions that turn into the presentation animations in the Urwid client. An action is similar to a slide in a slide show, except it can both present and change lines of code on the screen.
All purdy library programs have the following basic structure:
screen = Screen(...)
actions = [ ... ]
screen.run(actions)
Each action gets translated into a series of steps defined in the
purdy.animation
module.
- class purdy.actions.Append(code_box, code, pauses=[])
Adds the content of a
purdy.content.Code
object to the end of apurdy.ui.CodeBox
.- Parameters:
code_box – the
purdy.ui.CodeBox
instance to insert code intocode – a
purdy.content.Code
object containing the source code to insert.pauses – optional list of
purdy.actions.Pause
objects that specify where to insert pauses in the output
- class purdy.actions.AppendPrompt(code_box, code, response)
This action is used to show a prompt and its response. It appends the content of a
purdy.content.Code
object to apurdy.ui.CodeBox
as a prompt, waits for the ‘right arrow’ key, then uses the typewriter animation to add the response to the same line.- Parameters:
code_box – the
purdy.ui.CodeBox
instance to append code intocode – a
purdy.content.Code
object containing the prompt code to insert.response – text to place after the prompt
- class purdy.actions.Clear(code_box)
Clears the contents of a
purdy.ui.CodeBox
.- Parameters:
code_box – the
purdy.ui.CodeBox
instance where the code is to be replaced
- class purdy.actions.Fold(code_box, position, end=-1)
Folds code by replacing one or more lines with a vertical elipses symbol.
- Parameters:
code_box – the
purdy.ui.CodeBox
instance to modifyposition – line number to begin the fold at. Position is 1-indexed.
end – line number to finish the folding at, inclusive. A value of -1 can be used to fold to the end of the box. Defaults to -1.
- class purdy.actions.Highlight(code_box, spec, highlight_on)
Cause one or more lines of code to have highlighting turned on or off
- Parameters:
code_box –
purdy.ui.CodeBox
to perform onspec – either a string containing comma separated and/or hyphen separated integers (e.g. “1,3,7-9”) or a list of integers specifying the lines in the code box to highlight. Line numbers are 1-indexed
highlight_on – True to turn highligthing on, False to turn it off
- class purdy.actions.HighlightChain(code_box, spec_list)
A common pattern with highlighting lines is to turn a highlight on for some set of lines, then turn it off and turn it on for more lines. This is a convenience wrapper to the
Highlight
action, turning items on and off in series.- Parameters:
code_box –
purdy.ui.CodeBox
to perform series of highlight onspec_list – a list of highlight specs (see
Highlight
for details on a spec)
- class purdy.actions.Insert(code_box, position, code, pauses=[])
Inserts the content of a
purdy.content.Code
object to a specified line in apurdy.ui.CodeBox
. Pushes content down, inserting at “1” is the beginning of the list. Position is 1-indexed- Parameters:
code_box – the
purdy.ui.CodeBox
instance to insert code intoposition – line number to insert code at. Position is 1-indexed. Content is pushed down, so a value of “1” inserts at the beginning. Negative indicies are supported. A value of “0” will append the code to the bottom.
code – a
purdy.content.Code
object containing the source code to insert.pauses – optional list of
purdy.actions.Pause
objects that specify where to insert pauses in the output
- class purdy.actions.Pause(line_no, duration)
Used by some actions to indicate a delay between output lines.
- Parameters:
line_no – line in block to insert pause after. Note that this does not differentiate between code and output, just lines in a block
duartion – time in seconds to delay (ints and floats supported)
- class purdy.actions.Remove(code_box, position, size)
Removes one or more lines of a
purdy.ui.CodeBox
.- Parameters:
code_box – the
purdy.ui.CodeBox
instance where the code is to be replacedposition – line number to replace the code at. Position is 1-indexed. Negative indicies are supported.
size – number of lines to remove.
- class purdy.actions.Replace(code_box, position, code)
Replaces one or more lines of a
purdy.ui.CodeBox
using the content of apurdy.content.Code
object. This action attempts to overwrite using the number of lines in thepurdy.content.Code
object passed in, it is up to you to make sure there is enough space in your CodeBox.- Parameters:
code_box – the
purdy.ui.CodeBox
instance where the code is to be replacedposition – line number to replace the code at. Position is 1-indexed. Negative indicies are supported.
code – a
purdy.content.Code
object containing the source code to insert.
- class purdy.actions.RunFunction(fn, undo, *args, **kwargs)
Calls the function passed in, allowing the execution of code during the playing of actions.
- Parameters:
fn – function to be called
undo – function to be called when this Action is undone, can be None
*args – any remaining arguments are passed to the functions when they are called
**kwargs – any remaining arguments are passed to the functions when they are called
- class purdy.actions.Section
Marker for the beginning of a section. In the TUI you can skip to the next section marker using “S”.
- class purdy.actions.Shell(code_box, cmd)
Runs a shell command via subprocess. Does not display the command (you’re better off using a typewriter command to show it, then use this to spit out the results). Command and results are added to the
purdy.ui.CodeBox
.- Parameters:
code_box – the
purdy.ui.CodeBox
instance where the code is to be appendedcmd – string containing the shell command and its paramters. Example:
ls -la
.
- class purdy.actions.Sleep(time)
Causes animations to pause for the given amount of time. Note that this action happens within a cell, so is considered part of the group of animation steps done together. For example if Append + Sleep + Append is part of the same cell it is all done/undone together.
- Parameters:
time – Either the amount of time to sleep in seconds (ints and floats supported), or a tuple containing a pair of times specifying the range of a random value to sleep.
- class purdy.actions.StopMovie
Causes the presentation
purdy.ui.Screen
to exit movie mode
- class purdy.actions.Suffix(code_box, position, source)
Adds the provided text to the end of an existing line in a
purdy.ui.CodeBox
.- Parameters:
code_box – the
purdy.ui.CodeBox
instance where the code is to be appendedposition – line number to replace the code at. Position is 1-indexed. Negative indicies are supported.
source – string containing content to append to the line
- class purdy.actions.Transition(code_box, code=None, code_box_to_copy=None)
Replaces the contents of a
purdy.ui.CodeBox
with new content, doing a wipe animation from top to bottom. Only one of code or code_box_to_copy should be given, both can be blank to transition to an empty screen.- Parameters:
code_box – the
purdy.ui.CodeBox
instance to perform the transition oncode – a
purdy.content.Code
object containing the source code replacing the existing content. Should not be used at the same time as code_box_to_copy parameter.code_box_to_copy – a code box containing rendered code to copy into this one to display. This is typically a
VirtualCodeBox
. Should not be used at the same time as code parameter.
- class purdy.actions.Wait
Causes the animations to wait for a right arrow key press before continuing.
Typewriter Actions
Typewriter actions display code using a typewriter animation. Code content is
displayed a letter at a time as if someone is typing. The
purdy.settings
module contains default values for typing speeds and
variance time between letters being pressed.
When the code in question is based on a console, the typewriter will wait for
the right arrow to be pressed whenever it sees a prompt. For example, when
appending Python REPL code, the >>>
will cause the interface to wait.
- class purdy.actions.AppendTypewriter(code_box, code, pauses=[])
Adds the content of a
purdy.content.Code
object to apurdy.ui.CodeBox
using the typewriter animation.- Parameters:
code_box – the
purdy.ui.CodeBox
instance to append code intocode – a
purdy.content.Code
object containing the source code to insert.pauses – optional list of
purdy.actions.Pause
objects that specify where to insert pauses in the output
- class purdy.actions.InsertTypewriter(code_box, position, code, pauses=[])
Inserts the contents of a
purdy.content.Code
object at the given position using the typewriter animation.- Parameters:
code_box – the
purdy.ui.CodeBox
instance to append code intoposition – line number to insert the code at. Position is 1-indexed.
code – a
purdy.content.Code
object containing the source code to insert.pauses – optional list of
purdy.actions.Pause
objects that specify where to insert pauses in the output
- class purdy.actions.SuffixTypewriter(code_box, position, source)
Adds the provided text to the end of an existing line in a
purdy.ui.CodeBox
using a typewriter animation.- Parameters:
code_box – the
purdy.ui.CodeBox
instance to append code intoposition – line number to insert the code at. Position is 1-indexed. Negative indicies are supported.
source – a string to be appended to the given line
Default Settings
- settings.settings
"""
Settings (purdy.settings.py)
============================
Defines the default settings for :class:`purdy.ui.Screen` objects, can be
overridden by passing an altered dictionary into the Screen's constructor.
"""
settings = {
# delay between characters appearing on screen (in milliseconds)
'delay':130,
# range of random time in milliseconds to change the delay; makes typing
# look more natural
'delay_variance':30,
# movie mode: instead of waiting for key presses, play like a movie, -1
# disables, otherwise value in milliseconds for delay between played steps
# (like 'delay' field
'movie_mode':-1,
# xterm colour mode, anything but 256 gives 16 colour mode
'colour':256,
# if True, stops Screen from running argparse
'deactivate_args':False,
# max height for presentation, only works in TUI mode, 0 == no max
'max_height':0,
}