MarkdownView is a Pythonista UI library component. It is a drop-in replacement for ui.TextView that supports both editing markdown tagged text and viewing it as HTML.
##Contents
- Features
- Quick start
- Link behavior
- Additional keys
- Component motivation and design principles
- Constructor
- Attributes
- Methods
- To do
- Integrated markdown editing and HTML viewing modes - end editing and HTML is shown, click somewhere on the HTML text and markdown editing starts in the same position.
- Markdown editing supported by additional keys. (Thanks JonB for help on Obj-C.)
- Implements ui.TextView API for easy integration to existing code.
- Customizable through attributes or CSS.
##Quick start
Download (from Github) both the MarkdownView.py
script and this readme.md
file into same directory, and you can run the script in Pythonista to view and try out editing this readme file.
Import MarkdownView as a module and use wherever you would use a TextView. Markdown text can be set and accessed with the text attribute. Implement a delegate with textview_did_end_editing
or textview_did_change
method - see the end of the MarkdownView.py file for an example.
When you click a link in the HTML view:
http:
andhttps:
links are opened in Safari- Document-internal links (
#something
) are followed within MarkdownView file:
links are opened in Pythonista built-in browser- All other links like
twitter:
are opened as defined by the OS, i.e. in the relevant app, if installed.
You can change the handling of internal and external links by implementing a proxy with either or both of the following methods. Both should return True if MarkdownView should load the link.
webview_should_load_internal_link(webview, url)
webview_should_load_external_link(webview, url)
Extra keys help with markdown editing, but are in no way required, and can be turned off with additional_keys = False
argument at instantiation. Please refer to markdown syntax if not already familiar.
Keys:
- ⇥ - Indent - Repeat adds more spaces, 2 at a time.
- ⇤ - Outdent - Removes 2 spaces at time.
- > - Quote - Repeat adds levels; there is no special support for removing levels.
- [] - Links and images - If a range is selected, the contents of the range is used for both visible text and the link; for images, you have to add the exclamation mark at the front.
- # - Headings - Adds a level with each click; fourth click removes all hashes.
1.
- Numbered list - Replaces unordered list markers if present. Repeat removes. Indenting increases the list level.- • - Bullet list - Regular unordered list, otherwise like the numbered list.
_
- Emphasis - If a range is selected, inserts an underscore at both ends of the selection. Once for emphasis, twice for strong, three times for both. Fourth time removes the underscores.- ` - Backtick - Insert backtick or backticks around selection to indicate code. Removes backticks if already there.
For all of the above, where it makes sense, if several lines are selected, applies the change to all the lines regardless of whether they have been selected only partially.
- Provide some rich-text editing capabilities for Pythonista UI scripts
- In a format that is not locked to specific propietary format & program
- Easy to deploy to an existing solution
- Is robust (unlike straight HTML that tends to get confusing with styles etc.)
- Make markdown editing as easy as possible, with the transition between editing and viewing as seamless as possible (no 'Edit' button)
- Do not require thinking about or taking screen space for UI elements like toolbars (i.e. be conscious of and support small screens like iPhone)
- Is lightweight, understandable and manageable by a Python programmer (which would not be the case when using e.g. TinyMCE in a WebView)
- Not a web browser
MarkdownView(frame = None, flex = None, background_color = None, name = None, accessory_keys = True, extras = [], css = None)
Parameters:
frame
,flex
,background_color
,name
- As standard for a view.accessory_keys
- Whether to enable the additional keys for markdown editing or not; see the section on additional keys, above.extras
- Any markdown2 extras you want active, as an array of strings. As an example, this document relies on"header-ids"
for the table of contents links.css
- Provide your own CSS styles as a string; see the attribute description, below.
alignment
- As TextView, affects WebView as wellautocapitalization_type
- As TextViewautocorrection_type
- As TextViewauto_content_inset
- As TextViewbackground_color
- As TextView, affects WebView as wellcss
- Provide your own CSS styles, or set to an empty string to get the WebView defaults. Note that if you provide this, you have to provide all styles, not just your additions. Include$font_size
,$font_family
,$text_color
and$text_align
keywords in the appropriate places if you still want to have e.g. thefont
attribute ofMarkdownView
affect also theWebView
.delegate
- Set an object that handlesTextView
andWebView
delegated method calls. Following methods are supported:textview_should_begin_editing
,textview_did_begin_editing
,textview_did_end_editing
,textview_should_change
,textview_did_change
,textview_did_change_selection
webview_should_start_load
(deprecated by the custom methods below),webview_did_start_load
,webview_did_finish_load
,webview_did_fail_load
- And the two custom methods; see the section on link behavior for details:
webview_should_load_internal_link
,webview_should_load_external_link
editable
- True by default. Setting to False means you get the HTML view only. Could be useful if your app has different users and modes for "editor" and "viewer".editing
- True if currently in markdown editing modefont
- As TextView, affects WebView as wellkeyboard_type
- As TextViewmargins
- Tuple (), default is no marginsscales_page_to_fit
- as WebViewselectable
- As TextView, does not affect WebViewselected_range
- As TextView, does not work on WebView modespellchecking_type
- As TextViewtext
- The markdown texttext_color
- As TextView, affects WebView as well
preferred_size()
- returns a size (width, height) tuple based on what size the component would want to be, based on its contents. This is based on the TextView or the WebView contents, depending on whether we are currently editing or not. If you want to explicitly use one or the other, pass ausing=markdown
orusing=html
parameter. You can control min/max dimensions returned by providing some of the following parameters:min_width
,max_width
,min_height
,max_height
. (The processing of these parameters is optimized for horizontal text.)replace_range()
- as TextViewsize_to_fit()
- sizes the component based on the TextView or the WebView contents, depending on whether we are currently editing or not. Seepreferred_size()
for optional parameters.to_html()
- returns the HTML of the WebView. This contains all MarkdownView-specific styles and JavaScript code. If you need just the markdown content converted to HTML, includecontent_only=True
as a parameter.
- Increase reliability of the HTML-to-markdown transition
- Swipe right to go back after following an in-document link