bookish package

Submodules

bookish.checkpoints module

class bookish.checkpoints.Checkpoints(userid, store, cachestore, maxnum=10)

Bases: object

autosave(path, content)
checkpoints(path)
clean_checkpoints(path)
delete_checkpoints(path)
get_autosave(path, encoding='utf8')
get_checkpoint(path, checkpointid, encoding='utf8')
has_autosave(path)
has_autosave_after(path, dt)
load_checkpoint(path, checkpointid, encoding='utf8')
move_checkpoints(path, newpath)
save_checkpoint(path, content, encoding='utf8')
bookish.checkpoints.drop_inline_diffs(diff)
bookish.checkpoints.merge_files(a, x, b)

bookish.coloring module

class bookish.coloring.Ansi

Bases: object

black = '\x1b[30m'
black_back = '\x1b[40m'
blue = '\x1b[34m'
blue_back = '\x1b[44m'
bright = '\x1b[1m'
cyan = '\x1b[36m'
cyan_back = '\x1b[46m'
dim = '\x1b[2m'
green = '\x1b[32m'
green_back = '\x1b[42m'
magenta = '\x1b[35m'
magenta_back = '\x1b[45m'
normal = '\x1b[22m'
red = '\x1b[31m'
red_back = '\x1b[41m'
reset = '\x1b[39m'
reset_all = '\x1b[0m'
reset_back = '\x1b[49m'
white = '\x1b[37m'
white_back = '\x1b[47m'
yellow = '\x1b[33m'
yellow_back = '\x1b[43m'
class bookish.coloring.CustomHtmlFormatter(hl_lines=None)

Bases: pygments.formatters.html.HtmlFormatter

wrap(source, outfile)

Wrap the source, which is a generator yielding individual lines, in custom generators. See docstring for format. Can be overridden.

bookish.coloring.code_chars(code)
bookish.coloring.cstring(code, string)
bookish.coloring.format_block(block, lexername=None, lexer=None, pre=False)
bookish.coloring.format_string(source, lexername=None, lexer=None, look='', hl_lines=None, pre=False)
bookish.coloring.lexer_for(name)

bookish.compat module

bookish.compat.array_frombytes(arry, bs)
bookish.compat.array_tobytes(arry)
bookish.compat.b(s)
bookish.compat.byte(num)
bookish.compat.config_get(config, section, name, fallback=None)
bookish.compat.config_getboolean(config, section, name, fallback=False)
bookish.compat.config_getint(config, section, name, fallback=0)
bookish.compat.htmlescape(s, quote=True)
bookish.compat.indent(text, prefix, predicate=None)

Adds ‘prefix’ to the beginning of selected lines in ‘text’.

If ‘predicate’ is provided, ‘prefix’ will only be added to the lines where ‘predicate(line)’ is True. If ‘predicate’ is not provided, it will default to adding ‘prefix’ to all non-empty lines that do not consist solely of whitespace characters.

bookish.compat.iteritems(o)
bookish.compat.iterkeys(o)
bookish.compat.itervalues(o)
bookish.compat.memoryview_(source, offset=None, length=None)
bookish.compat.next(o)
bookish.compat.u(s)
bookish.compat.with_metaclass(meta, base=<type 'object'>)

bookish.config module

class bookish.config.DefaultConfig

Bases: object

AUTOSAVE = True
AUTOSAVE_SECONDS = 10
BACKGROUND_INDEXING_INTERVAL = 60
CACHE_DIR = './cache'
CATEGORIES = ''
CHECKPOINT_MAX = 10
DEBUG = False
DEFAULT_LANGUAGE = 'en-us'
DEFAULT_LOCALE = 'en_US'
DEFAULT_TEMPLATE = '/templates/page.jinja2'
DOCUMENTS = []
EDITABLE = False
EDIT_STORE = None
ENABLE_BACKGROUND_INDEXING = False
EXTRA_DOCUMENTS = []
ICON_144 = '/images/logos/logo_144.png'
ICON_32 = '/images/logos/logo_32.png'
INDEX_DIR = './index'
INDEX_PAGE_NAME = 'index'
PAGES_CLASS = 'wikipages.WikiPages'
PYGMENTS_CSS = '/static/css/pygments/brightcolor.css'
SCSS_ASSET_DIR = '/static/scss/'
SEARCHABLES

Used by autodoc_mock_imports.

SEARCH_SHORTCUTS = []
SEARCH_TEMPLATE = '/templates/results.jinja2'
SECRET_KEY = 'dummy'
SUPPORT_DOCUMENTS = [{'source': '/home/jtomori/coding/houdini_additional_python_docs/python2.7libs/bookish/templates', 'type': 'mount', 'target': '/templates'}, {'source': '/home/jtomori/coding/houdini_additional_python_docs/python2.7libs/bookish/grammars', 'type': 'mount', 'target': '/grammars'}, {'source': '/home/jtomori/coding/houdini_additional_python_docs/python2.7libs/bookish/static', 'static': True, 'type': 'mount', 'target': '/static'}]
TEXTIFY_CLASS

alias of bookish.textify.TextifierBase

WIKI_EXT = '.txt'
WIKI_STYLE = '/templates/wiki.jinja2'
class bookish.config.TestConfig

Bases: bookish.config.DefaultConfig

DEBUG = True
bookish.config.expandpath(path)

bookish.convert module

class bookish.convert.ReWiki

Bases: HTMLParser.HTMLParser

handle_charref(name)
handle_comment(data)
handle_data(data)
handle_decl(data)
handle_endtag(tag)
handle_entityref(name)
handle_starttag(tag, attrs)
class bookish.convert.WikiWriter(stream)

Bases: object

block(obj, indent=0)
default_block(obj, indent=0)
default_span(obj)
do_bullet_block(obj, indent)
do_cell_block(obj, indent)
do_code_block(obj, indent)
do_code_span(obj)
do_comment_span(obj)
do_dt_block(obj, indent)
do_em_span(obj)
do_h_block(obj, indent)
do_hcell_block(obj, indent)
do_item_block(obj, indent)
do_keys_span(obj)
do_ord_block(obj, indent)
do_para_block(obj, indent)
do_prop_block(obj, indent)
do_pxml_block(obj, indent)
do_quote_span(obj)
do_strong_span(obj)
do_summary_block(obj, indent)
do_ui_span(obj)
do_var_span(obj)
do_xml_span(obj)
indent(spaces)
markup(run)
process_text(run)
span(obj)
text(run)
bookish.convert.dechar(text, charmap=[(u'\u201d', '"'), (u'\u201c', '"'), (u'\u2019', "'"), (u'\u2014', '---'), (u'\u2013', '--'), (u'\u2190', '<-'), (u'\u2192', '->'), (u'\u2264', '<='), (u'\u2265', '>='), (u'\u21d4', '<=>'), (u'\xbc', '1/4'), (u'\xbd', '1/2'), (u'\xbe', '3/4'), (u'\u2026', '...'), (u'\xd7', 'x'), (u'\xa9', '(c)'), (u'\u2122', '(tm)'), (u'\xae', '(r)')])

bookish.flaskapp module

exception bookish.flaskapp.NotModified(description=None, response=None)

Bases: werkzeug.exceptions.HTTPException

An HTTP “304 Not Modified” response.

code = 304
get_response(environment)

Get a response object. If one was passed to the exception it’s returned directly.

Parameters:environ – the optional environ for the request. This can be used to modify the response depending on how the request looked like.
Returns:a Response object or a subclass thereof.
bookish.flaskapp.after_request(response)
bookish.flaskapp.before_request()
bookish.flaskapp.debug_textify(path)
bookish.flaskapp.debug_tooltip(path)
bookish.flaskapp.debug_wiki_structure(path)
bookish.flaskapp.delete_wiki()
bookish.flaskapp.directory_list(pages, dirpath)
bookish.flaskapp.directory_page(pages, dirpath)

Renders a simple template to show the files in a directory.

bookish.flaskapp.edit_wiki(path)
bookish.flaskapp.field_contents(name)
bookish.flaskapp.format_code(source, lexername=None, pre=False)
bookish.flaskapp.get_indexer(app=None)
bookish.flaskapp.get_request_language(pages, path)

Get the human language from a flask request

bookish.flaskapp.get_request_userid()
bookish.flaskapp.get_store(app=None)
bookish.flaskapp.get_textifier()
bookish.flaskapp.get_wikipages(app=None)
bookish.flaskapp.icon_list()
bookish.flaskapp.internal_error(exception)
bookish.flaskapp.is_unconditional()

Returns True if the given flask request is unconditional (that is, cannot be served from a cache).

bookish.flaskapp.list_checkpoints()
bookish.flaskapp.list_dir()
bookish.flaskapp.list_wiki_forms()
bookish.flaskapp.load_checkpoint()
bookish.flaskapp.load_example()
bookish.flaskapp.load_wiki()
bookish.flaskapp.move_wiki()
bookish.flaskapp.new_dir()
bookish.flaskapp.null_rel(x)
bookish.flaskapp.page_not_found(exception)
bookish.flaskapp.preview_wiki()
bookish.flaskapp.save_wiki()
bookish.flaskapp.search_page()
bookish.flaskapp.send_file_partial(path, conditional)

Simple wrapper around send_file which handles HTTP 206 Partial Content (byte ranges) TODO: handle all send_file args, mirror send_file’s error handling (if it has any)

bookish.flaskapp.show(path)
bookish.flaskapp.tag_page(tag)
bookish.flaskapp.teardown(exception)
bookish.flaskapp.toc_page(path)
bookish.flaskapp.update_index()

bookish.flasksupport module

class bookish.flasksupport.BgIndex(app)

Bases: object

do_reindex()
reindex()
schedule_next()
start_indexer()
stop_indexing()
class bookish.flasksupport.Scss(app)

Bases: object

compile_scss(path)
find_scss(partials=False)
import_hook(path)
out_of_date(path)
output_path(path)
partials_have_changed()
recompile_all()
set_hooks()
update_scss()
bookish.flasksupport.setup(app)
bookish.flasksupport.setup_config(app, config_obj=None, config_file=None)
bookish.flasksupport.setup_logging(app)
bookish.flasksupport.setup_template_globals(app)
bookish.flasksupport.setup_template_loader(app)

bookish.functions module

class bookish.functions.Missing

Bases: object

bookish.functions.attr(block, name, default=None)
bookish.functions.block_id(block)
bookish.functions.build_toc(docroot, basepath=None, block=None, i=0, depth=0, maxdepth=99)
bookish.functions.collapse(body, types=())
bookish.functions.engroup(blocks)
bookish.functions.find_all_breadth(obj, with_text=False)
bookish.functions.find_all_depth(obj)
bookish.functions.find_by_attr(top, name, value)
bookish.functions.find_by_type(top, typename)
bookish.functions.find_headings(block, depth=1, types=('h', 'section'))
bookish.functions.find_id(top, value)
bookish.functions.find_items(block, itemtype='item')
bookish.functions.find_spans_of_type(text, typename)
bookish.functions.find_with_attr(top, name)
bookish.functions.first(obj)
bookish.functions.first_by_attr(top, name, value)
bookish.functions.first_of_type(top, typename)
bookish.functions.first_span_of_type(text, typename)
bookish.functions.first_subblock_of_type(body, typename)
bookish.functions.first_subblock_string(block)
bookish.functions.first_subblock_text(block)
bookish.functions.has_option(s, key)
bookish.functions.icon_ref(val)
bookish.functions.last(obj)
bookish.functions.next_table_cell(block)
bookish.functions.random_id()
bookish.functions.random_name(length=5)
bookish.functions.remove_subblocks(body, exclude)
bookish.functions.retain_subblocks(body, include)
bookish.functions.slugify(text, lower=True)
bookish.functions.sort(obj, key=None)
bookish.functions.split_tags(tagstring)
bookish.functions.string(obj, before=None, after=None)

Converts the kinds of things you might get in a template to unicode. If it’s a string, returns the string. If it’s a list, recursively calls string() on the contents and joins them. If it’s a dictionary with a “text” key, calls string() on that. Otherwise, returns str(obj).

bookish.functions.subblock_by_id(body, idstring)
bookish.functions.subblocks_of_type(body, typename)
bookish.functions.subblocks_summary(block)
bookish.functions.text_replace(text, target, replacement)
bookish.functions.thing(x)
bookish.functions.topattr(block, name, default=None)

bookish.i18n module

bookish.i18n.is_language_supported(language, supported_languages)
bookish.i18n.language_detection()

Select the right language

  1. CookieLanguageMiddleware : Look at the cookie if exists
  2. HttpAcceptLanguageMiddleware : Look at the browser language settings
  3. DefaultLanguageMiddleware : Come back to english
bookish.i18n.normalize_language_name(language)

Attempts to normalize language names (e.g. en_us, en-US, etc.) to a lowercase, hyphenated form (en-us).

bookish.i18n.parse_accept_lang_header(lang_string)

Parses the lang_string, which is the body of an HTTP Accept-Language header, and returns a list of (lang, q-value), ordered by ‘q’ values.

Any format errors in lang_string results in an empty list being returned.

bookish.i18n.parse_http_accept_language(header_string, available_langs)

bookish.includes module

exception bookish.includes.CircularIncludeError

Bases: exceptions.Exception

bookish.includes.denull(blocks)
bookish.includes.get_finder(name, value)
bookish.includes.get_included(block, context, root)
bookish.includes.get_raw_source(block, context, root)
bookish.includes.load_include(block, context, root)
bookish.includes.load_include_impl(path, finder, key, unwrap, context, root)
bookish.includes.load_include_path(basepath, ref, context, root)
bookish.includes.make_include(ref, name=None, value=None, unwrap=None, retain=None, remove=None, newtype=None, newid=None)
bookish.includes.parse_include_path(incpath)
bookish.includes.spec_from_block(block, context)
bookish.includes.spec_from_path(basepath, ref)
bookish.includes.target(root, finder, unwrap)

bookish.paths module

bookish.paths.barename(path)

Returns the base name of the file named by the path, with any extension removed. If the resource is a directory, the base name is the empty string (“”).

>>> basename("/a/b.txt")
"b"
>>> basename("/a/b")
"b"
>>> basename("/a/b/")
""
bookish.paths.basename(path)

Returns the base name of the file named by the path. If the resource is a directory, the base name is the empty string (“”).

>>> basename("/a/b")
"b"
>>> basename("/a/b/")
""
bookish.paths.basepath(path)

Removes the extension from the end of a path.

bookish.paths.directory(path)

If the given path is a directory resource (ends with a slash), this returns the path unchanged. If it’s a file resource, returns the path of the file’s parent directory.

>>> parent("/a/b/")
"/a/b/"
>>> parent("/a/b")
"/a/"
bookish.paths.extension(path)

Returns the “extension” part of the base name of a resource path.

>>> extension("/a/b/foo.bar")
"bar"
>>> extension("/a/b/foo")
""
>>> extension("/a/b/foo.")
""
bookish.paths.is_abs(path)
bookish.paths.join(basepath, relpath)

Joins two path strings intelligently. If the first path specifies a file, the second path will be joined to the first path’s directory.

>>> join("/a/b", "c")
"/a/b/c"
>>> join("/a/b/c", "d")
"/a/b/d"
>>> join("/a/b/c/", "../d")
"/a/b/d"
bookish.paths.norm_parts(path, out=None)

Returns a list of the normalized parts of the given path string. This means that special names such as “.” and “..” are applied, and multiple adjacent slashes are replaced with a single slash.

>>> norm_parts("/a/b//c/../d")
["/", "a/", "b/", "d"]
bookish.paths.normalize(path)

Returns a normalized version of the given path string. This means that special names such as “.” and “..” are applied, and multiple adjacent slashes are replaced with a single slash.

>>> normalize("/a/b//c/../d")
"/a/b/d"
bookish.paths.normalize_abs(path)

Like normalize() but raises an error if the given path is not absolute.

bookish.paths.parent(path)

Returns the parent directory path of the given resource.

>>> parent("/a/b/c")
"/a/"
>>> parent("/a/b/")
"/a/"
>>> parent("/")
"/"
bookish.paths.parts(path)

Yields the parts of the given path string:

>>> list(parts("/a/b/c"))

[“/”, “a/”, “b/”, “c”]

bookish.paths.relativize(basepath, targetpath)

Returns a relative path from the “base” resource to the “target” resource.

>>> relativize("/a/b", "c")
"c"
>>> relativize("/a/b/c", "/a/b/d/e")
"d/e"
>>> relativize("/a/b/c", "/d/e/f")
"../../d/e/f"
bookish.paths.split_dirpath(path)

Returns the parent path and the file name of a resource path.

>>> split_dirpath("/a/b/foo.bar")
("/a/b/", "foo.bar")
bookish.paths.split_extension(path)

Returns the base part and the extension part of the base name of a resource path.

>>> split_extension("/a/b/foo.bar")
("foo", "bar")
bookish.paths.split_fragment(path)

Returns the path and the fragment of a path/fragment combo.

>>> split_fragment("/a/b/foo#bar")
("/a/b/foo", "#bar")
bookish.paths.split_path_parts(path)

Returns a list of the names in the path.

>>> split_path_parts("/a/b/c")
["a", "b", "c"]
bookish.paths.strip_extension(name)

Removes any extension from the given string.

bookish.pipeline module

Bases: bookish.pipeline.LinkProcessor

Finds links in the content, looks up the linked document in the search index, and adds annotations to the link based on the linked document’s search fields.

add_attrs(*attrs)
default_attrs = ['title', 'type', 'icon', 'summary', 'container']
name = 'annotate'

Bases: bookish.pipeline.Processor

apply(block, context)
before = ('annotate',)
name = 'backlinks'
exception bookish.pipeline.CircularDependencyError

Bases: exceptions.Exception

class bookish.pipeline.DependencyGraph(vs=None)

Bases: object

add(v)
depends_on(v, prereq)
resolve(vs=None)
class bookish.pipeline.EmptyBlocks

Bases: bookish.pipeline.Processor

Removes blocks without any content. Ignores certain things.

apply(block, context)
name = 'empty'
class bookish.pipeline.Flow

Bases: bookish.pipeline.Processor

apply(block, context, root=None)
name = 'flow'
class bookish.pipeline.FullPaths

Bases: bookish.pipeline.LinkProcessor

Finds links in the content, and annotates them with the absolute path to the linked page.

name = 'fullpaths'
class bookish.pipeline.Groups(types=('bullet', 'ord', 'dt', 'item'), blacklist=('billboard', 'null'))

Bases: bookish.pipeline.Processor

Groups blocks of the same type “N” under “group_N” superblocks.

after = ('hierarchy', 'sections')
apply(block, context)
name = 'groups'
class bookish.pipeline.Hierarchy(attr='indent', default=0)

Bases: bookish.pipeline.Processor

Organizes a linear list of blocks into a hierarchy based on the relative values of a key (usually “indent”).

apply(block, context)
name = 'hierarchy'
class bookish.pipeline.Includes

Bases: bookish.pipeline.Processor

Finds include directives and replaces them with the included wiki content.

after = ('promote', 'properties')
apply(block, context)
name = 'includes'
class bookish.pipeline.JoinKeys

Bases: bookish.pipeline.TextModifier

Coalesces consecutive keys spans.

name = 'joinkeys'
text(text, context)
class bookish.pipeline.JoinText

Bases: bookish.pipeline.TextModifier

Joins adjacent runs of text together, so [“foo”, “bar”] becomes [“foobar”].

name = 'join'
text(text, context)
class bookish.pipeline.LinkProcessor

Bases: bookish.pipeline.Processor

Base class for processors of links.

apply(block, context, basepath=None)
text(context, text, basepath)
class bookish.pipeline.Metadata

Bases: bookish.pipeline.Processor

Adds some simple metadata to the JSON after it’s generated.

apply(block, context)
name = 'metadata'
class bookish.pipeline.Modifier

Bases: bookish.pipeline.Processor

A type of Processor that only modifies a single block at a time (that is, that doesn’t care about hierarchy). This allows them to be grouped together in a MultiModifier.

apply(block, context)
modify(block, context)
class bookish.pipeline.MultiModifier(modifiers)

Bases: bookish.pipeline.Processor

Processor that wraps multiple Modifier objects. This object walks the document tree and calls each modifier on each block.

add(modifier)
apply(block, context)
class bookish.pipeline.Parents

Bases: bookish.pipeline.Processor

Annotates the current document with information about its parent documents, including their subtopics, allowing the template to display things like breadcrumbs and a tree view.

apply(block, context)
static get_parent_path(pages, path, block)
name = 'parents'
static parent_info(prevpath, json, path)
class bookish.pipeline.Pipe(processors)

Bases: bookish.pipeline.Processor

Processor that wraps multiple processor objects and calls them each in turn.

add(other)
apply(block, context)
processor_by_class(cls)
class bookish.pipeline.Processor

Bases: object

Base class for objects that walk a document tree modifying the blocks in place.

add(other)
apply(block, context)
name = ''
class bookish.pipeline.Promote

Bases: bookish.pipeline.Processor

Finds blocks where a bit of xml or an include is the only thing in the block, and “promotes” that span up to block level.

apply(block, context)
name = 'promote'
class bookish.pipeline.Properties

Bases: bookish.pipeline.Processor

Changes “property” blocks into attributes on the parent block. Make sure this runs after Hierarchy.

after = ('sortheadings',)
apply(block, context)
name = 'properties'
class bookish.pipeline.RenumberHeadings

Bases: bookish.pipeline.Processor

Adds “level” keys to headings indicating their level in the heading hierarchy.

after = ('sortheadings', 'includes')
apply(block, context, level=2)
name = 'renumberheadings'
class bookish.pipeline.RunSearches

Bases: bookish.pipeline.Processor

Finds various items that run searches and replaces them with the search results.

apply(block, context, root=None)
default_fields = ['path', 'title', 'summary', 'type', 'icon', 'status', 'tags']
static get_results(block, context)
name = 'searches'
class bookish.pipeline.Sections

Bases: bookish.pipeline.Processor

Sets the “text” on sections if it wasn’t given, and changes the “type” of plain items inside a section to a type based on the section name. For example, a plain item inside a @properties section becomes type properties_item.

after = ('hierarchy',)
apply(block, context, itemtype=None)
name = 'sections'
class bookish.pipeline.Shortcuts

Bases: bookish.pipeline.TextModifier

Finds shortcuts and looks for a method corresponding to the shortcut’s scheme to process it. You must subclass this to get it to do anything.

name = 'shortcuts'
text(text, context)
class bookish.pipeline.SortHeadings

Bases: bookish.pipeline.Processor

Implements “linear” header style, where blocks simply come after headers at the same indent, instead of being indented under the heading. This processor looks for headings without bodies and pulls any subsequent blocks into them.

after = ('hierarchy', 'promote')
apply(block, context)
name = 'sortheadings'
class bookish.pipeline.Tables

Bases: bookish.pipeline.Processor

Because of the way simple tables are marked up, you end up with a cell block for each row, where each rightward cell is the only child of the cell to its left. This processor re-organizes this into a more render-friendly structure.

after = ('hierarchy',)
apply(block, context)
name = 'tables'
class bookish.pipeline.TextModifier

Bases: bookish.pipeline.Modifier

Special subclass of Modifier that only modifies text nodes.

modify(block, context)
text(text, context)
class bookish.pipeline.Title

Bases: bookish.pipeline.Processor

Finds the page title and summary blocks and copies their text up to the root for easier access by other code.

apply(block, context)
name = 'title'
class bookish.pipeline.Toc

Bases: bookish.pipeline.Processor

apply(block, context)
before = ('annotate',)
name = 'toc'
class bookish.pipeline.TreeProcessor

Bases: bookish.pipeline.Processor

Middle-ware for processors that might have to process every block in the tree. Does the work of traversing the tree, calling modify(block, context) at each block. If the modify method returns True, the processor recursively processes each child of the block.

apply(block, context)
modify(block, context)
bookish.pipeline.default_post_pipeline()
bookish.pipeline.default_pre_pipeline()
bookish.pipeline.make_pipeline(objs)

bookish.search module

Used by autodoc_mock_imports.

bookish.stores module

class bookish.stores.DictionaryStore(dictionary, writable=False)

Bases: bookish.stores.Store

Presents a dictionary mapping path strings to bytes objects as a page store.

Supports the list_all(path) method but does not support directories (list_dir always returns [] and is_dir always returns False).

Does not support last modified times (last_modified always returns 0).

etag(path)
exists(path)

Returns True if the given path exists in this store.

is_dir(path)

Returns True if the given path represents a directory in this store.

last_modified(path)

Returns a datetime object

list_all(path='/')
list_dir(path)

Lists the file names under the given path.

make_dir(path, create_intermediate=False)

Creates a new directory at the given path.

open(path, mode='rb')

Returns a file-like object for reading the given path.

size(path)

Returns the size (in bytes) of the file at the given path.

writable(path)

Returns True if the given path can be created/overwritten.

write_file(path, bytestring)
class bookish.stores.FileStore(dirpath)

Bases: bookish.stores.Store

Represents a directory in the filesystem.

delete(path)

Deletes the underlying file for the given path.

etag(path)
exists(path)

Returns True if the given path exists in this store.

file_path(path)

Returns the filesystem equivalent of the given virtual path, if it has one, otherwise None.

is_dir(path)

Returns True if the given path represents a directory in this store.

last_modified(path)

Returns a datetime object

list_dir(path)

Lists the file names under the given path.

make_dir(path, create_intermediate=False)

Creates a new directory at the given path.

move(path, newpath)

Moves the underlying file to the new path.

open(path, mode='rb')

Returns a file-like object for reading the given path.

size(path)

Returns the size (in bytes) of the file at the given path.

writable(path)

Returns True if the given path can be created/overwritten.

class bookish.stores.MountStore(child, prefix)

Bases: bookish.stores.WrappingStore

Mounts a child store at a “sub-directory”, for use in an OverlayStore.

content(path, encoding='utf8')

Convenience method to return the string content of the file at the given path.

Parameters:encoding

the name of the encoding to use to decode the file’s bytes. Default is "utf8". If you use encoding=None the

method returns the raw bytestring.
exists(path)

Returns True if the given path exists in this store.

is_dir(path)

Returns True if the given path represents a directory in this store.

list_all(path='/')
list_dir(path)

Lists the file names under the given path.

class bookish.stores.OverlayStore(*stores)

Bases: bookish.stores.Store

Overlays the contents of a number of sub-stores. When the methods are called with a path, this store tries its sub-stores in order, and fulfills the request using the first sub-store found that contains the path.

append(store)
close()
content(path, encoding='utf8')

Convenience method to return the string content of the file at the given path.

Parameters:encoding

the name of the encoding to use to decode the file’s bytes. Default is "utf8". If you use encoding=None the

method returns the raw bytestring.
delete(path)

Deletes the underlying file for the given path.

etag(path)
exists(path)

Returns True if the given path exists in this store.

extend(stores)
file_path(path)

Returns the filesystem equivalent of the given virtual path, if it has one, otherwise None.

is_dir(path)

Returns True if the given path represents a directory in this store.

last_modified(path)

Returns a datetime object

list_all(path='/')
list_dir(path)

Lists the file names under the given path.

make_dir(path, create_intermediate=False)

Creates a new directory at the given path.

open(path, mode='rb')

Returns a file-like object for reading the given path.

size(path)

Returns the size (in bytes) of the file at the given path.

store_for(path)
writable(path)

Returns True if the given path can be created/overwritten.

write_file(path, bytestring)
exception bookish.stores.ResourceNotFoundError

Bases: exceptions.Exception

class bookish.stores.Store

Bases: object

Base class for page storage objects.

close()
content(path, encoding='utf8')

Convenience method to return the string content of the file at the given path.

Parameters:encoding

the name of the encoding to use to decode the file’s bytes. Default is "utf8". If you use encoding=None the

method returns the raw bytestring.
delete(path)

Deletes the underlying file for the given path.

etag(path)
exists(path)

Returns True if the given path exists in this store.

file_path(path)

Returns the filesystem equivalent of the given virtual path, if it has one, otherwise None.

is_dir(path)

Returns True if the given path represents a directory in this store.

last_modified(path)

Returns a datetime object

list_all(path='/')
list_dir(path)

Lists the file names under the given path.

make_dir(path, create_intermediate=False)

Creates a new directory at the given path.

move(path, newpath)

Moves the underlying file to the new path.

open(path, mode='rb')

Returns a file-like object for reading the given path.

size(path)

Returns the size (in bytes) of the file at the given path.

store_for(path)
writable(path)

Returns True if the given path can be created/overwritten.

write_file(path, bytestring)
class bookish.stores.StringStore

Bases: bookish.stores.Store

Base class for stores that more naturally return generate strings than file-like objects

content(path, encoding='utf8')

Convenience method to return the string content of the file at the given path.

Parameters:encoding

the name of the encoding to use to decode the file’s bytes. Default is "utf8". If you use encoding=None the

method returns the raw bytestring.
open(path, mode='rb')

Returns a file-like object for reading the given path.

class bookish.stores.SubStore(child, prefix)

Bases: bookish.stores.WrappingStore

“Extracts” a “sub-directory” of a child store and presents it as a top-level store.

class bookish.stores.WrappingStore(child)

Bases: bookish.stores.Store

Base class for PageStore implementations that wrap “child” stores.

close()
delete(path)

Deletes the underlying file for the given path.

etag(path)
exists(path)

Returns True if the given path exists in this store.

file_path(path)

Returns the filesystem equivalent of the given virtual path, if it has one, otherwise None.

is_dir(path)

Returns True if the given path represents a directory in this store.

last_modified(path)

Returns a datetime object

list_all(path='/')
list_dir(path)

Lists the file names under the given path.

make_dir(path, create_intermediate=False)

Creates a new directory at the given path.

open(path, mode='rb')

Returns a file-like object for reading the given path.

size(path)

Returns the size (in bytes) of the file at the given path.

writable(path)

Returns True if the given path can be created/overwritten.

class bookish.stores.ZipStore(zipfilepath)

Bases: bookish.stores.Store

Represents the files inside a zip archive.

close()
content(path, encoding='utf8')

Convenience method to return the string content of the file at the given path.

Parameters:encoding

the name of the encoding to use to decode the file’s bytes. Default is "utf8". If you use encoding=None the

method returns the raw bytestring.
etag(path)
exists(path)

Returns True if the given path exists in this store.

is_dir(path)

Returns True if the given path represents a directory in this store.

last_modified(path)

Returns a datetime object

list_all(path='/')
list_dir(path)

Lists the file names under the given path.

open(path, mode='r')

Returns a file-like object for reading the given path.

size(path)

Returns the size (in bytes) of the file at the given path.

zipinfo(path)
static zipname(path)
class bookish.stores.ZipTree(dirpath)

Bases: bookish.stores.Store

Looks for a zip file corresponding to the first part of a path, and if it finds one, looks inside that zip file for the rest of the path. This essentially makes zip files at the root level look like directories.

close()
content(path, encoding='utf8')

Convenience method to return the string content of the file at the given path.

Parameters:encoding

the name of the encoding to use to decode the file’s bytes. Default is "utf8". If you use encoding=None the

method returns the raw bytestring.
etag(path)
exists(path)

Returns True if the given path exists in this store.

is_dir(path)

Returns True if the given path represents a directory in this store.

last_modified(path)

Returns a datetime object

list_all(path='/')
list_dir(path)

Lists the file names under the given path.

open(path, mode='rb')

Returns a file-like object for reading the given path.

size(path)

Returns the size (in bytes) of the file at the given path.

bookish.stores.expandpath(path)
bookish.stores.file_etag(fpath)
bookish.stores.store_from_spec(spec)
bookish.stores.utc_offset()

bookish.styles module

class bookish.styles.JinjaStoreLoader(store, prefix='/templates/')

Bases: jinja2.loaders.BaseLoader

Jinja template loader that loads templates from a Bookish storage object.

get_source(environment, template_path)

Get the template source, filename and reload helper for a template. It’s passed the environment and template name and has to return a tuple in the form (source, filename, uptodate) or raise a TemplateNotFound error if it can’t locate the template.

The source part of the returned tuple must be the source of the template as unicode string or a ASCII bytestring. The filename should be the name of the file on the filesystem if it was loaded from there, otherwise None. The filename is used by python for the tracebacks if no loader extension is used.

The last item in the tuple is the uptodate function. If auto reloading is enabled it’s always called to check if the template changed. No arguments are passed so the function must store the old state somewhere (for example in a closure). If it returns False the template will be reloaded.

list_templates(extensions=None, filter_func=None)

Iterates over all templates. If the loader does not support that it should raise a TypeError which is the default behavior.

class bookish.styles.Stylesheet(env, templatename, index_page_name)

Bases: object

context_and_function(basepath, jsondata, extras=None)

Returns a Jinja context function you can use to transform a JSON document using the rules contained in this style’s template.

static default_rule(jinctx, obj, render)
render(basepath, jsondata)

bookish.testing module

bookish.testing.find_missing(pages, images=True, links=True, prefix='/', callback=None)

bookish.textify module

class bookish.textify.BookishTextifier(root, left=0, top=0, bottom=0, width=72, vars=None, charfilter=True)

Bases: bookish.textify.TextifierBase

bullet_block(block)
bullet_group_block(block)
dt_block(block)
em_span(span)
h_block(block)
item_block(block)
keys_span(span)
list_block(block)
note_block(block)
ord_block(block)
ord_group_block(block)
para_block(block)
pre_block(block)
section_block(block)
strong_span(span)
subtopics_block(block)
tip_block(block)
var_span(span)
warning_block(block)
class bookish.textify.TextFrame(parent, left=0, top=0, bottom=0, width=72, padding_top=0, padding_bottom=0, replacements=None, buffered=False, vars=None, charfilter=None, charmap=None, xform=None)

Bases: object

display_vars = ['left', 'top', 'bottom', 'width', 'replacements', 'buffered', 'vars']
emit(string, indent=0, wrap=True, first='', rest='', upper=False, lower=False, normalize=True, before='', after='')
finish()
get(name)
getvalue()
inc(name)
write(string)
class bookish.textify.TextifierBase(root, left=0, top=0, bottom=0, width=72, vars=None, charfilter=True)

Bases: object

blank_lines(n)
emit(text, indent=0, wrap=True, top=0, bottom=0, first=u'', rest=u'', upper=False, lower=False, before='', after='')
emit_block_text(block, **kwargs)
find(block, ave, **vars)
frame
pop()
push(indent=0, left=None, top=0, bottom=0, width=None, padding_top=0, padding_bottom=0, replacements=None, buffered=False, charfilter=None, charmap=None, xform=None, **kwargs)
render(block, ns=None)
render_body(body, eat_top=True, **kwargs)
render_span(span)
render_super(block)
render_text(text)
transform()
write(string)
bookish.textify.addindent(first, subsequent, text, trim=False)
bookish.textify.dechar(text, charmap=((u'\u201d', '"'), (u'\u201c', '"'), (u'\u2019', "'"), (u'\u2014', '---'), (u'\u2013', '--'), (u'\u2190', '<-'), (u'\u2192', '->'), (u'\u2264', '<='), (u'\u2265', '>='), (u'\u21d4', '<=>'), (u'\u25b8', '>'), (u'\xbc', '1/4'), (u'\xbd', '1/2'), (u'\xbe', '3/4'), (u'\u2026', '...'), (u'\xd7', 'x'), (u'\xa9', '(c)'), (u'\u2122', '(tm)'), (u'\xae', '(r)'), (u'\u02da', 'deg'), (u'\u03c0', 'pi'), (u'\u03c3', 'sigma')))
bookish.textify.format_block(text, left=0, width=72, wrap=True, first='', rest='', upper=False, lower=False, xform=None, charfilter=True, charmap=None, normalize=True)
bookish.textify.join(arg, *args)

bookish.util module

class bookish.util.Context(m=None, parent=None)

Bases: object

first()
get(key, default=None)
has_keys()
items(seen=None)
keys()
push(m=None)
update(m)
values()
class bookish.util.DbLruCache(maxsize=100)

Bases: object

Double-barrel least-recently-used cache decorator. This is a simple LRU algorithm that keeps a primary and secondary dict. Keys are checked in the primary dict, and then the secondary. Once the primary dict fills up, the secondary dict is cleared and the two dicts are swapped.

Keys must be hashable.

get(key)
put(key, value)
class bookish.util.TempDB

Bases: object

class bookish.util.TempDir

Bases: object

bookish.util.builtin_grammar(name)
bookish.util.class_from_name(name, namespace=None, classdict=None)
bookish.util.decode_named_entity(name)
bookish.util.dump_tree(block, stream=None, tab=0)
bookish.util.dumps_tree(block)
bookish.util.file_paths(dirpath, include=None, exclude=None, callback=None)
bookish.util.find_object(name, blacklist=None, whitelist=None)

Imports and returns an object given a fully qualified name.

>>> find_object("whoosh.analysis.StopFilter")
<class 'whoosh.analysis.StopFilter'>
bookish.util.flatten_text(obj)

Returns a string containing just the string values from the given “text” list. The function recursively descends into “text” keys found on non-string spans in the list.

bookish.util.get_prefixed_paths(pages, prefix)
bookish.util.join_text(text)

Joins adjacent strings in a “text” list together. This function recursively descends into “text” keys found on non-string spans in the list.

bookish.util.json_file(filename)
bookish.util.make_id(name)
bookish.util.make_rel_fn(basepath, index_page_name)
bookish.util.memoize(f)
bookish.util.normalize_text(tx)
bookish.util.normalize_ws(s)
bookish.util.object_from_item(config, section, option, cls=None, namespace=None, classdict=None)
bookish.util.objects_from_items(items, namespace=None, classdict=None)
bookish.util.pyliteral(value, fallback_to_string=False)
bookish.util.random_id(length=10)
bookish.util.timing(*args, **kwds)

bookish.wikipages module

class bookish.wikipages.PageCache(cachedir)

Bases: object

cache_path(path)
delete_path(path)
empty()
ext = '.json'
get_cached_json(pages, sourcepath)
put_cache(cachepath, jsondata)
exception bookish.wikipages.Redirect(newpath)

Bases: exceptions.Exception

class bookish.wikipages.WikiPages(store, env, cachedir=None, caching=True, languages=None, page_template=None, page_style=None, mem_cache_size=10, index_page_name='index', wiki_ext='.txt', default_language='en-us', logger=None)

Bases: object

available_languages(path)
content(path, reformat=False, encoding='utf8')
default_style = '/templates/wiki.jinja2'
default_template = '/templates/page.jinja2'
etag(path, locale=None)
exists(path)
file_path(path)

Takes a virtual server path and translates it into a “real” file path, or None if the resource does not exist in a file.

find_source(path, locales=None)
full_path(origin, relpath)
html(path, templatename=None, stylesname=None, conditional=True, save_to_cache=True, language=None, searcher=None, extras=None, allow_redirect=False)
is_index_page(path)
is_wiki(path)
is_wiki_source(path)
json(path, wcontext=None, ext='.json', conditional=True, postprocess=True, save_to_cache=True, extra_context=None, searcher=None, allow_redirect=False, allow_fragment=False, steps=None, profiling=False, use_string=None)
json_to_html(path, jsondata, templatename=None, stylesname=None, extras=None, searcher=None)
last_modified(path)
post_pipe()
pre_pipe()
preview(path, content, templatename=None, stylesname=None, language=None, searcher=None, extras=None)
reformat_text(text)
size(path)
source_path(path, locale=None)
string_to_json(path, content, wcontext=None, searcher=None, extras=None, postprocess=True)
style(templatename)
wiki_context(path, conditional=True, save_to_cache=True, searcher=None, profiling=False)
bookish.wikipages.block(typename, indent, text, role=None, **kwargs)
bookish.wikipages.generate_id(block)
bookish.wikipages.get_section(body, sectionid)
bookish.wikipages.head(eqs, indent, text, **kwargs)
bookish.wikipages.parse_string(src)
bookish.wikipages.recordchars(block, startchar, endchar)
bookish.wikipages.remove_duplicates(ls)
bookish.wikipages.span(typename, text, **kwargs)

Module contents