diff options
author | Zearin <zearin@gonk.net> | 2011-10-05 17:05:31 -0400 |
---|---|---|
committer | Zearin <zearin@gonk.net> | 2011-10-05 17:05:31 -0400 |
commit | aa19e3b9c9f03f7320c2d5470fa977ed0bbdeeab (patch) | |
tree | 97d86fe3a03114be08aac12a7097aa80ac03bc2a /docs | |
download | cmd2-aa19e3b9c9f03f7320c2d5470fa977ed0bbdeeab.tar.gz |
Initial import.
Copy of the Python module cmd2 by Catherine Devlin. Note that this is
NOT the official copy (it’s at
http://www.assembla.com/spaces/python-cmd2/wiki ). I’d rather just
work using git + GitHub instead of hg + Assembla. ☺
OTOH, I fully intend to submit changes back to the official repo on
Assembla—so don’t be shy, fork away. I’m happy for any help!
Diffstat (limited to 'docs')
44 files changed, 2674 insertions, 0 deletions
diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..76bdbe2 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,89 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = +BUILDDIR = _build + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . + +.PHONY: help clean html dirhtml pickle json htmlhelp qthelp latex changes linkcheck doctest + +help: + @echo "Please use \`make <target>' where <target> is one of" + @echo " html to make standalone HTML files" + @echo " dirhtml to make HTML files named index.html in directories" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " qthelp to make HTML files and a qthelp project" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " changes to make an overview of all changed/added/deprecated items" + @echo " linkcheck to check all external links for integrity" + @echo " doctest to run all doctests embedded in the documentation (if enabled)" + +clean: + -rm -rf $(BUILDDIR)/* + +html: + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + +dirhtml: + $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml + @echo + @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." + +pickle: + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +json: + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in $(BUILDDIR)/htmlhelp." + +qthelp: + $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp + @echo + @echo "Build finished; now you can run "qcollectiongenerator" with the" \ + ".qhcp project file in $(BUILDDIR)/qthelp, like this:" + @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/cmd2.qhcp" + @echo "To view the help file:" + @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/cmd2.qhc" + +latex: + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex + @echo + @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." + @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ + "run these through (pdf)latex." + +changes: + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes + @echo + @echo "The overview file is in $(BUILDDIR)/changes." + +linkcheck: + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in $(BUILDDIR)/linkcheck/output.txt." + +doctest: + $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest + @echo "Testing of doctests in the sources finished, look at the " \ + "results in $(BUILDDIR)/doctest/output.txt." diff --git a/docs/alternatives.rst b/docs/alternatives.rst new file mode 100644 index 0000000..bbf2ae2 --- /dev/null +++ b/docs/alternatives.rst @@ -0,0 +1,50 @@ +============================ +Alternatives to cmd and cmd2 +============================ + +For programs that do not interact with the user in a continuous loop - +programs that simply accept a set of arguments from the command line, return +results, and do not keep the user within the program's environment - all +you need are sys_\ .argv (the command-line arguments) and optparse_ +(for parsing UNIX-style options and flags). + +.. _optparse: http://docs.python.org/library/optparse.html#module-optparse + +.. _sys: http://docs.python.org/library/sys.html#module-sys + +.. _curses: http://docs.python.org/library/curses.html#module-curses + +.. _cmd: http://docs.python.org/library/cmd.html#module-cmd + +The curses_ module produces applications that interact via a plaintext +terminal window, but are not limited to simple text input and output; +they can paint the screen with options that are selected from using the +cursor keys. However, programming a curses_-based application is not as +straightforward as using cmd_. + +Several packages in PyPI enable interactive command-line applications +approximately similar in concept to cmd_ applications. None of them +share cmd2's close ties to cmd, but they may be worth investigating +nonetheless. + + * CmdLoop_ + * cly_ + * CmDO_ (As of Feb. 2010, webpage is missing.) + * pycopia-CLI_ + +cmdln_, another package in PyPI, is an extension to cmd_ and, though it +doesn't retain full cmd_ compatibility, shares its basic structure with +cmd_. + +.. _cmdln: http://pypi.python.org/pypi/cmdln + +.. _CmdLoop: http://pypi.python.org/pypi/CmdLoop + +.. _cly: http://pypi.python.org/pypi/cly + +.. _CmDO: http://pypi.python.org/pypi/CmDO/0.7 + +.. _pycopia-CLI: http://pypi.python.org/pypi/pycopia-CLI/1.0 + +I've found several alternatives to cmd in the Cheese Shop - CmdLoop, cly, CMdO, and pycopia. cly looks wonderful, but I haven't been able to get it working under Windows, and that's a show-stopper for many potential sqlpython users. In any case, none of the alternatives are based on cmd - they're written from scratch, which means that a cmd-based app would need complete rewriting to use them. I like sticking close to the Standard Library whenever possible. cmd2 lets you do that. + diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..131a187 --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,198 @@ +# -*- coding: utf-8 -*- +# +# cmd2 documentation build configuration file, created by +# sphinx-quickstart on Wed Feb 10 12:05:28 2010. +# +# This file is execfile()d with the current directory set to its containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys, os + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +#sys.path.append(os.path.abspath('.')) + +# -- General configuration ----------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx', 'sphinx.ext.todo'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'cmd2' +copyright = u'2010, Catherine Devlin' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '0.6.0' +# The full version, including alpha/beta/rc tags. +release = '0.6.0' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of documents that shouldn't be included in the build. +#unused_docs = [] + +# List of directories, relative to source directory, that shouldn't be searched +# for source files. +exclude_trees = ['_build'] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + + +# -- Options for HTML output --------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. Major themes that come with +# Sphinx are currently 'default' and 'sphinxdoc'. +html_theme = 'default' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# "<project> v<release> documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_use_modindex = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a <link> tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = '' + +# Output file base name for HTML help builder. +htmlhelp_basename = 'cmd2doc' + + +# -- Options for LaTeX output -------------------------------------------------- + +# The paper size ('letter' or 'a4'). +#latex_paper_size = 'letter' + +# The font size ('10pt', '11pt' or '12pt'). +#latex_font_size = '10pt' + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]). +latex_documents = [ + ('index', 'cmd2.tex', u'cmd2 Documentation', + u'Catherine Devlin', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# Additional stuff for the LaTeX preamble. +#latex_preamble = '' + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_use_modindex = True + + +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = {'http://docs.python.org/': None} diff --git a/docs/freefeatures.rst b/docs/freefeatures.rst new file mode 100644 index 0000000..8795261 --- /dev/null +++ b/docs/freefeatures.rst @@ -0,0 +1,207 @@ +=================================== +Features requiring no modifications +=================================== + +These features are provided "for free" to a cmd_-based application +simply by replacing ``import cmd`` with ``import cmd2 as cmd``. + +.. _cmd: http://docs.python.org/library/cmd.html#module-cmd + +Script files +============ + +Text files can serve as scripts for your ``cmd2``-based +application, with the ``load``, ``save``, and ``edit`` +commands. + +.. automethod:: cmd2.Cmd.do_load + +.. automethod:: cmd2.Cmd.do_save + +.. automethod:: cmd2.Cmd.do_edit + +Comments +======== + +Comments are omitted from the argument list +before it is passed to a ``do_`` method. By +default, both Python-style and C-style comments +are recognized; you may change this by overriding +``app.commentGrammars`` with a different pyparsing_ +grammar. + +Comments can be useful in :ref:`scripts`. Used +in an interactive session, they may indicate +mental imbalance. + +:: + + def do_speak(self, arg): + self.stdout.write(arg + '\n') + +:: + + (Cmd) speak it was /* not */ delicious! # Yuck! + it was delicious! + +.. _pyparsing: http://pyparsing.wikispaces.com/ + +Commands at invocation +====================== + +You can send commands to your app as you invoke it by +including them as extra arguments to the program. +``cmd2`` interprets each argument as a separate +command, so you should enclose each command in +quotation marks if it is more than a one-word command. + +:: + + cat@eee:~/proj/cmd2/example$ python example.py "say hello" "say Gracie" quit + hello + Gracie + cat@eee:~/proj/cmd2/example$ + + +Output redirection +================== + +As in a Unix shell, output of a command can be redirected: + + - sent to a file with ``>``, as in ``mycommand args > filename.txt`` + - piped (``|``) as input to operating-system commands, as in + ``mycommand args | wc`` + - sent to the paste buffer, ready for the next Copy operation, by + ending with a bare ``>``, as in ``mycommand args >``.. Redirecting + to paste buffer requires software to be installed on the operating + system, pywin32_ on Windows or xclip_ on \*nix. + +If your application depends on mathematical syntax, ``>`` may be a bad +choice for redirecting output - it will prevent you from using the +greater-than sign in your actual user commands. You can override your +app's value of ``self.redirector`` to use a different string for output redirection:: + + class MyApp(cmd2.Cmd): + redirector = '->' + +:: + + (Cmd) say line1 -> out.txt + (Cmd) say line2 ->-> out.txt + (Cmd) !cat out.txt + line1 + line2 + +.. _pywin32: http://sourceforge.net/projects/pywin32/ +.. _xclip: http://www.cyberciti.biz/faq/xclip-linux-insert-files-command-output-intoclipboard/ + +Python +====== + +The ``py`` command will run its arguments as a Python +command. Entered without arguments, it enters an +interactive Python session. That session can call +"back" to your application with ``cmd("")``. Through +``self``, it also has access to your application +instance itself. (If that thought terrifies you, +you can set the ``locals_in_py`` parameter to ``False``. +See see :ref:`parameters`) + +:: + + (Cmd) py print("-".join("spelling")) + s-p-e-l-l-i-n-g + (Cmd) py + Python 2.6.4 (r264:75706, Dec 7 2009, 18:45:15) + [GCC 4.4.1] on linux2 + Type "help", "copyright", "credits" or "license" for more information. + (CmdLineApp) + + py <command>: Executes a Python command. + py: Enters interactive Python mode. + End with `Ctrl-D` (Unix) / `Ctrl-Z` (Windows), `quit()`, 'exit()`. + Non-python commands can be issued with `cmd("your command")`. + + >>> import os + >>> os.uname() + ('Linux', 'eee', '2.6.31-19-generic', '#56-Ubuntu SMP Thu Jan 28 01:26:53 UTC 2010', 'i686') + >>> cmd("say --piglatin {os}".format(os=os.uname()[0])) + inuxLay + >>> self.prompt + '(Cmd) ' + >>> self.prompt = 'Python was here > ' + >>> quit() + Python was here > + +Searchable command history +========================== + +All cmd_-based applications have access to previous commands with +the up- and down- cursor keys. + +All cmd_-based applications on systems with the ``readline`` module +also provide `bash-like history list editing`_. + +.. _`bash-like history list editing`: http://www.talug.org/events/20030709/cmdline_history.html + +``cmd2`` makes a third type of history access available, consisting of these commands: + +.. automethod:: cmd2.Cmd.do_history + +.. automethod:: cmd2.Cmd.do_list + +.. automethod:: cmd2.Cmd.do_run + +Quitting the application +======================== + +``cmd2`` pre-defines a ``quit`` command for you (with +synonyms ``exit`` and simply ``q``). +It's trivial, but it's one less thing for you to remember. + + +Abbreviated commands +==================== + +``cmd2`` apps will accept shortened command names +so long as there is no ambiguity. Thus, if +``do_divide`` is defined, then ``divid``, ``div``, +or even ``d`` will suffice, so long as there are +no other commands defined beginning with *divid*, +*div*, or *d*. + +This behavior can be turned off with ``app.abbrev`` (see :ref:`parameters`) + +Misc. pre-defined commands +========================== + +Several generically useful commands are defined +with automatically included ``do_`` methods. + +.. automethod:: cmd2.Cmd.do_quit + +.. automethod:: cmd2.Cmd.do_pause + +.. automethod:: cmd2.Cmd.do_shell + +( ``!`` is a shortcut for ``shell``; thus ``!ls`` +is equivalent to ``shell ls``.) + + +Transcript-based testing +======================== + +If the entire transcript (input and output) of a successful session of +a ``cmd2``-based app is copied from the screen and pasted into a text +file, ``transcript.txt``, then a transcript test can be run against it:: + + python app.py --test transcript.txt + +Any non-whitespace deviations between the output prescribed in ``transcript.txt`` and +the actual output from a fresh run of the application will be reported +as a unit test failure. (Whitespace is ignored during the comparison.) + +Regular expressions can be embedded in the transcript inside paired ``/`` +slashes. These regular expressions should not include any whitespace +expressions. + diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..58feacc --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,72 @@ +.. cmd2 documentation master file, created by + sphinx-quickstart on Wed Feb 10 12:05:28 2010. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +cmd2 +==== + +A python package for building powerful command-line interpreter (CLI) +programs. Extends the Python Standard Library's cmd_ package. + + +.. _`cmd2 project page`: http://www.assembla.com/wiki/show/python-cmd2 +.. _`project bug tracker`: http://trac-hg.assembla.com/python-cmd2/report/1 + +.. _cmd: http://docs.python.org/library/cmd.html#module-cmd + +The basic use of ``cmd2`` is identical to that of cmd_. + +1. Create a subclass of ``cmd2.Cmd``. Define attributes and + ``do_*`` methods to control its behavior. Throughout this documentation, + we will assume that you are naming your subclass ``App``:: + + from cmd2 import Cmd + class App(Cmd): + # customized attributes and methods here + +2. Instantiate ``App`` and start the command loop:: + + app = App() + app.cmdloop() + +Resources +--------- + +* cmd_ +* `project bug tracker`_ +* `cmd2 project page`_ +* `PyCon 2010 presentation <http://us.pycon.org/2010/conference/talks/#proposal_link_153>`_, + *Easy Command-Line Applications with cmd and cmd2*: + :doc:`slides <pycon2010/pycon2010>`, + `video <http://python.mirocommunity.com/video/1533/easy-command-line-applications>`_ + +These docs will refer to ``App`` as your ``cmd2.Cmd`` +subclass, and ``app`` as an instance of ``App``. Of +course, in your program, you may name them whatever +you want. + +Contents: + +.. toctree:: + :maxdepth: 2 + + overview + example + freefeatures + settingchanges + unfreefeatures + alternatives + +Compatibility +============= + +Tested and working with Python 2.5, 2.6, 2.7, 3.1; Jython 2.5 + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` + diff --git a/docs/make.bat b/docs/make.bat new file mode 100755 index 0000000..3e88e03 --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,113 @@ +@ECHO OFF + +REM Command file for Sphinx documentation + +set SPHINXBUILD=sphinx-build +set BUILDDIR=_build +set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% . +if NOT "%PAPER%" == "" ( + set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% +) + +if "%1" == "" goto help + +if "%1" == "help" ( + :help + echo.Please use `make ^<target^>` where ^<target^> is one of + echo. html to make standalone HTML files + echo. dirhtml to make HTML files named index.html in directories + echo. pickle to make pickle files + echo. json to make JSON files + echo. htmlhelp to make HTML files and a HTML help project + echo. qthelp to make HTML files and a qthelp project + echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter + echo. changes to make an overview over all changed/added/deprecated items + echo. linkcheck to check all external links for integrity + echo. doctest to run all doctests embedded in the documentation if enabled + goto end +) + +if "%1" == "clean" ( + for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i + del /q /s %BUILDDIR%\* + goto end +) + +if "%1" == "html" ( + %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/html. + goto end +) + +if "%1" == "dirhtml" ( + %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml + echo. + echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. + goto end +) + +if "%1" == "pickle" ( + %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle + echo. + echo.Build finished; now you can process the pickle files. + goto end +) + +if "%1" == "json" ( + %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json + echo. + echo.Build finished; now you can process the JSON files. + goto end +) + +if "%1" == "htmlhelp" ( + %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp + echo. + echo.Build finished; now you can run HTML Help Workshop with the ^ +.hhp project file in %BUILDDIR%/htmlhelp. + goto end +) + +if "%1" == "qthelp" ( + %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp + echo. + echo.Build finished; now you can run "qcollectiongenerator" with the ^ +.qhcp project file in %BUILDDIR%/qthelp, like this: + echo.^> qcollectiongenerator %BUILDDIR%\qthelp\cmd2.qhcp + echo.To view the help file: + echo.^> assistant -collectionFile %BUILDDIR%\qthelp\cmd2.ghc + goto end +) + +if "%1" == "latex" ( + %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex + echo. + echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. + goto end +) + +if "%1" == "changes" ( + %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes + echo. + echo.The overview file is in %BUILDDIR%/changes. + goto end +) + +if "%1" == "linkcheck" ( + %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck + echo. + echo.Link check complete; look for any errors in the above output ^ +or in %BUILDDIR%/linkcheck/output.txt. + goto end +) + +if "%1" == "doctest" ( + %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest + echo. + echo.Testing of doctests in the sources finished, look at the ^ +results in %BUILDDIR%/doctest/output.txt. + goto end +) + +:end diff --git a/docs/overview.rst b/docs/overview.rst new file mode 100644 index 0000000..cb0c80e --- /dev/null +++ b/docs/overview.rst @@ -0,0 +1,17 @@ + +======== +Overview +======== + +``cmd2`` is an extension of cmd_, the Python Standard Library's module for +creating simple interactive command-line applications. + +``cmd2`` can be used as a drop-in replacement for cmd_. Simply importing ``cmd2`` +in place of cmd_ will add many features to an application without any further +modifications. + +Understanding the use of cmd_ is the first step in learning the use of ``cmd2``. +Once you have read the cmd_ docs, return here to learn the ways that ``cmd2`` +differs from cmd_. + +.. _cmd: http://docs.python.org/library/cmd.html
\ No newline at end of file diff --git a/docs/pycon2010/akkad.png b/docs/pycon2010/akkad.png Binary files differnew file mode 100644 index 0000000..57799e9 --- /dev/null +++ b/docs/pycon2010/akkad.png diff --git a/docs/pycon2010/apple.jpg b/docs/pycon2010/apple.jpg Binary files differnew file mode 100644 index 0000000..2148af3 --- /dev/null +++ b/docs/pycon2010/apple.jpg diff --git a/docs/pycon2010/fileutil.py b/docs/pycon2010/fileutil.py new file mode 100644 index 0000000..5e754b5 --- /dev/null +++ b/docs/pycon2010/fileutil.py @@ -0,0 +1,12 @@ +import glob +import os.path + +for fullfilename in glob.glob('/home/cat/proj/cmd2/*.py'): + (dirpath, fname) = os.path.split(fullfilename) + stats = os.stat(fullfilename) + binds['path'] = dirpath + binds['name'] = fname + binds['bytes'] = stats.st_size + cmd("""INSERT INTO cat.files (path, name, bytes) + VALUES (%(path)s, %(name)s, %(bytes)s)""") +quit() diff --git a/docs/pycon2010/graph.py b/docs/pycon2010/graph.py new file mode 100644 index 0000000..96ffde7 --- /dev/null +++ b/docs/pycon2010/graph.py @@ -0,0 +1,41 @@ +from turtle import * +pu() +goto(-400,-400) + +def label(txt): + write(txt, font=('Arial', 20, 'italic')) +hideturtle() +width(6) + +def line(len, _label): + start = pos() + pd() + forward(len) + pu() + forward(30) + pd() + label(_label) + pu() + goto(start) + +def tech(x, y, _label): + pu() + goto(x, y) + pd() + write(_label, font=('Arial', 40, 'bold')) + pu() + +line(600, "Easy to write") +left(90) +line(600, "Easy to use") + +tech(-360, 160, 'GUI') +tech(-390, 100, 'AJAX') +tech(-300, -10, 'webapp') +tech(190, -380, 'CLU') +tech(60, -320, 'TUI') +tech(100, -210, 'cmd') +tech(80, -80, 'cmd2') + +while True: + pass
\ No newline at end of file diff --git a/docs/pycon2010/hook.jpg b/docs/pycon2010/hook.jpg Binary files differnew file mode 100644 index 0000000..819370d --- /dev/null +++ b/docs/pycon2010/hook.jpg diff --git a/docs/pycon2010/pirate.py b/docs/pycon2010/pirate.py new file mode 100644 index 0000000..98db50e --- /dev/null +++ b/docs/pycon2010/pirate.py @@ -0,0 +1,7 @@ +from cmd import Cmd + +class Pirate(Cmd): + pass + +pirate = Pirate() +pirate.cmdloop()
\ No newline at end of file diff --git a/docs/pycon2010/pirate2.py b/docs/pycon2010/pirate2.py new file mode 100644 index 0000000..e2c4960 --- /dev/null +++ b/docs/pycon2010/pirate2.py @@ -0,0 +1,18 @@ +from cmd import Cmd +# using ``do_`` methods + +class Pirate(Cmd): + gold = 3 + def do_loot(self, arg): + 'Seize booty from a passing ship.' + self.gold += 1 + print('Now we gots {0} doubloons' + .format(self.gold)) + def do_drink(self, arg): + 'Drown your sorrrows in rrrum.' + self.gold -= 1 + print('Now we gots {0} doubloons' + .format(self.gold)) + +pirate = Pirate() +pirate.cmdloop() diff --git a/docs/pycon2010/pirate3.py b/docs/pycon2010/pirate3.py new file mode 100644 index 0000000..7977a8d --- /dev/null +++ b/docs/pycon2010/pirate3.py @@ -0,0 +1,21 @@ +from cmd import Cmd +# using hook + +class Pirate(Cmd): + gold = 3 + def do_loot(self, arg): + 'Seize booty from a passing ship.' + self.gold += 1 + def do_drink(self, arg): + 'Drown your sorrrows in rrrum.' + self.gold -= 1 + def precmd(self, line): + self.initial_gold = self.gold + return line + def postcmd(self, stop, line): + if self.gold != self.initial_gold: + print('Now we gots {0} doubloons' + .format(self.gold)) + +pirate = Pirate() +pirate.cmdloop() diff --git a/docs/pycon2010/pirate4.py b/docs/pycon2010/pirate4.py new file mode 100644 index 0000000..5de9c21 --- /dev/null +++ b/docs/pycon2010/pirate4.py @@ -0,0 +1,27 @@ +from cmd import Cmd +# using arguments + +class Pirate(Cmd): + gold = 3 + def do_loot(self, arg): + 'Seize booty from a passing ship.' + self.gold += 1 + def do_drink(self, arg): + '''Drown your sorrrows in rrrum. + + drink [n] - drink [n] barrel[s] o' rum.''' + try: + self.gold -= int(arg) + except: + if arg: + print('''What's "{0}"? I'll take rrrum.'''.format(arg)) + self.gold -= 1 + def precmd(self, line): + self.initial_gold = self.gold + return line + def postcmd(self, stop, line): + if self.gold != self.initial_gold: + print('Now we gots {0} doubloons'.format(self.gold)) + +pirate = Pirate() +pirate.cmdloop()
\ No newline at end of file diff --git a/docs/pycon2010/pirate5.py b/docs/pycon2010/pirate5.py new file mode 100644 index 0000000..7add463 --- /dev/null +++ b/docs/pycon2010/pirate5.py @@ -0,0 +1,35 @@ +from cmd import Cmd +# quitting + +class Pirate(Cmd): + gold = 3 + def do_loot(self, arg): + 'Seize booty from a passing ship.' + self.gold += 1 + def do_drink(self, arg): + '''Drown your sorrrows in rrrum. + + drink [n] - drink [n] barrel[s] o' rum.''' + try: + self.gold -= int(arg) + except: + if arg: + print('''What's "{0}"? I'll take rrrum.'''.format(arg)) + self.gold -= 1 + def precmd(self, line): + self.initial_gold = self.gold + return line + def postcmd(self, stop, line): + if self.gold != self.initial_gold: + print('Now we gots {0} doubloons' + .format(self.gold)) + if self.gold < 0: + print("Off to debtorrr's prison.") + stop = True + return stop + def do_quit(self, arg): + print("Quiterrr!") + return True + +pirate = Pirate() +pirate.cmdloop() diff --git a/docs/pycon2010/pirate6.py b/docs/pycon2010/pirate6.py new file mode 100644 index 0000000..4a03fed --- /dev/null +++ b/docs/pycon2010/pirate6.py @@ -0,0 +1,39 @@ +from cmd2 import Cmd +# prompts and defaults + +class Pirate(Cmd): + gold = 3 + prompt = 'arrr> ' + def default(self, line): + print('What mean ye by "{0}"?' + .format(line)) + def do_loot(self, arg): + 'Seize booty from a passing ship.' + self.gold += 1 + def do_drink(self, arg): + '''Drown your sorrrows in rrrum. + + drink [n] - drink [n] barrel[s] o' rum.''' + try: + self.gold -= int(arg) + except: + if arg: + print('''What's "{0}"? I'll take rrrum.'''.format(arg)) + self.gold -= 1 + def precmd(self, line): + self.initial_gold = self.gold + return line + def postcmd(self, stop, line): + if self.gold != self.initial_gold: + print('Now we gots {0} doubloons' + .format(self.gold)) + if self.gold < 0: + print("Off to debtorrr's prison.") + stop = True + return stop + def do_quit(self, arg): + print("Quiterrr!") + return True + +pirate = Pirate() +pirate.cmdloop() diff --git a/docs/pycon2010/pirate7.py b/docs/pycon2010/pirate7.py new file mode 100644 index 0000000..25ff582 --- /dev/null +++ b/docs/pycon2010/pirate7.py @@ -0,0 +1,46 @@ +from cmd2 import Cmd +# prompts and defaults + +class Pirate(Cmd): + gold = 3 + prompt = 'arrr> ' + def default(self, line): + print('What mean ye by "{0}"?'.format(line)) + def do_loot(self, arg): + 'Seize booty from a passing ship.' + self.gold += 1 + def do_drink(self, arg): + '''Drown your sorrrows in rrrum. + + drink [n] - drink [n] barrel[s] o' rum.''' + try: + self.gold -= int(arg) + except: + if arg: + print('''What's "{0}"? I'll take rrrum.'''.format(arg)) + self.gold -= 1 + def precmd(self, line): + self.initial_gold = self.gold + return line + def postcmd(self, stop, line): + if self.gold != self.initial_gold: + print('Now we gots {0} doubloons' + .format(self.gold)) + if self.gold < 0: + print("Off to debtorrr's prison.") + stop = True + return stop + def do_quit(self, arg): + print("Quiterrr!") + return True + default_to_shell = True + multilineCommands = ['sing'] + terminators = Cmd.terminators + ['...'] + songcolor = 'blue' + settable = Cmd.settable + 'songcolor Color to ``sing`` in (red/blue/green/cyan/magenta, bold, underline)' + Cmd.shortcuts.update({'~': 'sing'}) + def do_sing(self, arg): + print(self.colorize(arg, self.songcolor)) + +pirate = Pirate() +pirate.cmdloop() diff --git a/docs/pycon2010/pirate8.py b/docs/pycon2010/pirate8.py new file mode 100644 index 0000000..3e80b24 --- /dev/null +++ b/docs/pycon2010/pirate8.py @@ -0,0 +1,57 @@ +from cmd2 import Cmd, options, make_option +# prompts and defaults + +class Pirate(Cmd): + gold = 3 + prompt = 'arrr> ' + def default(self, line): + print('What mean ye by "{0}"?'.format(line)) + def do_loot(self, arg): + 'Seize booty from a passing ship.' + self.gold += 1 + def do_drink(self, arg): + '''Drown your sorrrows in rrrum. + + drink [n] - drink [n] barrel[s] o' rum.''' + try: + self.gold -= int(arg) + except: + if arg: + print('''What's "{0}"? I'll take rrrum.'''.format(arg)) + self.gold -= 1 + def precmd(self, line): + self.initial_gold = self.gold + return line + def postcmd(self, stop, line): + if self.gold != self.initial_gold: + print('Now we gots {0} doubloons' + .format(self.gold)) + if self.gold < 0: + print("Off to debtorrr's prison.") + stop = True + return stop + def do_quit(self, arg): + print("Quiterrr!") + return True + default_to_shell = True + multilineCommands = ['sing'] + terminators = Cmd.terminators + ['...'] + songcolor = 'blue' + settable = Cmd.settable + 'songcolor Color to ``sing`` in (red/blue/green/cyan/magenta, bold, underline)' + Cmd.shortcuts.update({'~': 'sing'}) + def do_sing(self, arg): + print(self.colorize(arg, self.songcolor)) + @options([make_option('--ho', type='int', default=2, + help="How often to chant 'ho'"), + make_option('-c', '--commas', + action="store_true", + help="Intersperse commas")]) + def do_yo(self, arg, opts): + chant = ['yo'] + ['ho'] * opts.ho + separator = ', ' if opts.commas else ' ' + chant = separator.join(chant) + print('{0} and a bottle of {1}' + .format(chant, arg)) + +pirate = Pirate() +pirate.cmdloop() diff --git a/docs/pycon2010/pycon2010.rst b/docs/pycon2010/pycon2010.rst new file mode 100644 index 0000000..0b3b7a4 --- /dev/null +++ b/docs/pycon2010/pycon2010.rst @@ -0,0 +1,382 @@ +================================================ +Easy command-line interpreters with cmd and cmd2 +================================================ + +:author: Catherine Devlin +:date: 2010-02-20 +:slides: http://pypi.python.org/pypi/cmd2 + +Web 2.0 +======= + +.. image:: web-2-0-logos.gif + :height: 350px + +But first... +============ + +.. image:: sargon.jpg + :height: 250px + +.. image:: akkad.png + :height: 250px + +Sargon the Great + Founder of Akkadian Empire + +.. twenty-third century BC + +In between +========== + +.. image:: apple.jpg + :height: 250px + +Command-Line Interface + Unlike the Akkadian Empire, + the CLI will never die. + +Defining CLI +============ + +Also known as + +- "Line-oriented command interpreter" +- "Command-line interface" +- "Shell" + +1. Accepts free text input at prompt +2. Outputs lines of text +3. (repeat) + +Examples +======== + +.. class:: big + + * Bash, Korn, zsh + * Python shell + * screen + * Zork + * SQL clients: psql, SQL*\Plus, mysql... + * ed + +.. ``ed`` proves that CLI is sometimes the wrong answer. + +!= Command Line Utilities +========================= + +.. class:: big + + (``ls``, ``grep``, ``ping``, etc.) + + 1. Accept arguments at invocation + 2. execute + 3. terminate + + Use ``sys.argv``, ``optparse`` + +!="Text User Interface" +======================= + +* Use entire (session) screen +* I/O is *not* line-by-line +* See ``curses``, ``urwid`` + +.. image:: urwid.png + :height: 250px + + +Decide your priorities +====================== + +.. image:: strategy.png + :height: 350px + +A ``cmd`` app: pirate.py +======================== + +:: + + from cmd import Cmd + + class Pirate(Cmd): + pass + + pirate = Pirate() + pirate.cmdloop() + +.. Nothing here... but history and help + +.. ctrl-r for bash-style history + +Fundamental prrrinciple +======================= + +.. class:: huge + + ``(Cmd) foo a b c`` + + becomes + + ``self.do_foo('a b c')`` + +``do_``-methods: pirate2.py +=========================== + +:: + + class Pirate(Cmd): + gold = 3 + def do_loot(self, arg): + 'Seize booty frrrom a passing ship.' + self.gold += 1 + print('Now we gots {0} doubloons' + .format(self.gold)) + def do_drink(self, arg): + 'Drown your sorrrows in rrrum.' + self.gold -= 1 + print('Now we gots {0} doubloons' + .format(self.gold)) + +.. do_methods; more help + +Hooks +===== + +.. image:: hook.jpg + :height: 250px + +:: + + self.preloop() + self.postloop() + self.precmd(line) + self.postcmd(stop, line) + +Hooks: pirate3.py +================= + +:: + + def do_loot(self, arg): + 'Seize booty from a passing ship.' + self.gold += 1 + def do_drink(self, arg): + 'Drown your sorrrows in rrrum.' + self.gold -= 1 + def precmd(self, line): + self.initial_gold = self.gold + return line + def postcmd(self, stop, line): + if self.gold != self.initial_gold: + print('Now we gots {0} doubloons' + .format(self.gold)) + +Arguments: pirate4.py +===================== + +:: + + def do_drink(self, arg): + '''Drown your sorrrows in rrrum. + + drink [n] - drink [n] barrel[s] o' rum.''' + try: + self.gold -= int(arg) + except: + if arg: + print('''What's "{0}"? I'll take rrrum.''' + .format(arg)) + self.gold -= 1 + +quitting: pirate5.py +==================== + +:: + + def postcmd(self, stop, line): + if self.gold != self.initial_gold: + print('Now we gots {0} doubloons' + .format(self.gold)) + if self.gold < 0: + print("Off to debtorrr's prison.") + stop = True + return stop + def do_quit(self, arg): + print("Quiterrr!") + return True + +prompts, defaults: pirate6.py +============================= + +:: + + prompt = 'arrr> ' + def default(self, line): + print('What mean ye by "{0}"?' + .format(line)) + +Other CLI packages +================== + +.. class:: big + + * CmdLoop + * cly + * CMdO + * pycopia + * cmdlin + * cmd2 + +Demo +==== + +.. class:: huge + + Convert ``cmd`` app to ``cmd2`` + +cmd2 +==== + +.. image:: schematic.png + :height: 350px + +As you wish, Guido +================== + +.. class:: huge + + Python 3 compatible + +(um, mostly) + +Absolutely free +=============== + +Script files + +Commands at invocation + +Output redirection + +Python + +Transcript testing + +But wait, there's more +====================== + + * Abbreviated commands + * Shell commands + * Quitting + * Timing + * Echo + * Debug + +Minor changes: pirate7.py +========================= + +:: + + default_to_shell = True + multilineCommands = ['sing'] + terminators = Cmd.terminators + ['...'] + songcolor = 'blue' + settable = Cmd.settable + 'songcolor Color to ``sing`` in (red/blue/green/cyan/magenta, bold, underline)' + Cmd.shortcuts.update({'~': 'sing'}) + def do_sing(self, arg): + print(self.colorize(arg, self.songcolor)) + +Now how much would you pay? +=========================== + +options / flags + +Quiet (suppress feedback) + +BASH-style ``select`` + +Parsing: terminators, suffixes + +Options: pirate8.py +=================== + +:: + + @options([make_option('--ho', type='int', default=2, + help="How often to chant 'ho'"), + make_option('-c', '--commas', + action="store_true", + help="Intersperse commas")]) + def do_yo(self, arg, opts): + chant = ['yo'] + ['ho'] * opts.ho + separator = ', ' if opts.commas else ' ' + chant = separator.join(chant) + print('{0} and a bottle of {1}' + .format(chant, arg)) + +Serious example: sqlpython +========================== + +.. class:: big + + ``cmd``-based app by Luca Canali @ CERN + + Replacement for Oracle SQL\*Plus + + Now ``cmd2``-based; postgreSQL; MySQL + +File reporter +============= + +.. class:: huge + + Gather info: Python + + Store: postgresql + + Report: html + +fileutil.py +=========== + +:: + + import glob + import os.path + + for fullfilename in glob.glob('/home/cat/proj/cmd2/*.py'): + (dirpath, fname) = os.path.split(fullfilename) + stats = os.stat(fullfilename) + binds['path'] = dirpath + binds['name'] = fname + binds['bytes'] = stats.st_size + cmd("""INSERT INTO cat.files (path, name, bytes) + VALUES (%(path)s, %(name)s, %(bytes)s)""") + quit() + +sqlpython features +================== + +.. class:: big + + * from ``cmd2``: scripts, redirection, + py, etc. + * multiple connections + * UNIX: ls, cat, grep + * Special output + + +Thank you +========= + +.. class:: big + + http://pypi.python.org/pypi/cmd2 + + http://catherinedevlin.blogspot.com + + http://catherinedevlin.pythoneers.com + + diff --git a/docs/pycon2010/refresh.bash b/docs/pycon2010/refresh.bash new file mode 100755 index 0000000..26827b5 --- /dev/null +++ b/docs/pycon2010/refresh.bash @@ -0,0 +1 @@ +rst2s5.py --theme-url ui/pycon pycon2010.rst pycon2010.html diff --git a/docs/pycon2010/sargon.jpg b/docs/pycon2010/sargon.jpg Binary files differnew file mode 100644 index 0000000..5960f1e --- /dev/null +++ b/docs/pycon2010/sargon.jpg diff --git a/docs/pycon2010/schematic.png b/docs/pycon2010/schematic.png Binary files differnew file mode 100644 index 0000000..d4b3909 --- /dev/null +++ b/docs/pycon2010/schematic.png diff --git a/docs/pycon2010/schematic.py b/docs/pycon2010/schematic.py new file mode 100644 index 0000000..8077485 --- /dev/null +++ b/docs/pycon2010/schematic.py @@ -0,0 +1,32 @@ +from turtle import * +hideturtle() +width(6) +pensize = 10 +pu() +goto(0,-400) + +def rectangle(x, y, _label): + pu() + seth(0) + backward(x / 2) + fontsize = 40 + pd() + for i in range(2): + forward(x) + left(90) + forward(y) + left(90) + pu() + forward(x / 2) + left(90) + forward(y / 2 - fontsize) + pd() + write(_label, align='center', font=('Arial', fontsize, 'bold')) + +rectangle(800, 80, 'cmd') +pu() +forward(80) +rectangle(200, 400, 'cmd2') + +while True: + pass diff --git a/docs/pycon2010/script.txt b/docs/pycon2010/script.txt new file mode 100644 index 0000000..c638b1a --- /dev/null +++ b/docs/pycon2010/script.txt @@ -0,0 +1,5 @@ +loot +loot +drink /* arrr */ 2 # matey +drink chardonnay + diff --git a/docs/pycon2010/strategy.png b/docs/pycon2010/strategy.png Binary files differnew file mode 100644 index 0000000..7d6afdc --- /dev/null +++ b/docs/pycon2010/strategy.png diff --git a/docs/pycon2010/transcript.txt b/docs/pycon2010/transcript.txt new file mode 100644 index 0000000..d00e44f --- /dev/null +++ b/docs/pycon2010/transcript.txt @@ -0,0 +1,12 @@ +arrr> loot +Now we gots 4 doubloons +arrr> loot +Now we gots 5 doubloons +arrr> drink 3 +Now we gots 2 doubloons +arrr> drink chardonnay +What's "chardonnay"? I'll take rrrum. +Now we gots 1 doubloons +arrr> quit +Quiterrr! + diff --git a/docs/pycon2010/ui/pycon/blank.gif b/docs/pycon2010/ui/pycon/blank.gif Binary files differnew file mode 100644 index 0000000..75b945d --- /dev/null +++ b/docs/pycon2010/ui/pycon/blank.gif diff --git a/docs/pycon2010/ui/pycon/framing.css b/docs/pycon2010/ui/pycon/framing.css new file mode 100644 index 0000000..c4727f3 --- /dev/null +++ b/docs/pycon2010/ui/pycon/framing.css @@ -0,0 +1,25 @@ +/* This file has been placed in the public domain. */ +/* The following styles size, place, and layer the slide components. + Edit these if you want to change the overall slide layout. + The commented lines can be uncommented (and modified, if necessary) + to help you with the rearrangement process. */ + +/* target = 1024x768 */ + +div#header, div#footer, .slide {width: 100%; top: 0; left: 0;} +div#header {position: fixed; top: 0; height: 3em; z-index: 1;} +div#footer {top: auto; bottom: 0; height: 2.5em; z-index: 5;} +.slide {top: 0; width: 92%; padding: 2.5em 4% 4%; z-index: 2;} +div#controls {left: 50%; bottom: 0; width: 50%; z-index: 100;} +div#controls form {position: absolute; bottom: 0; right: 0; width: 100%; + margin: 0;} +#currentSlide {position: absolute; width: 10%; left: 45%; bottom: 1em; + z-index: 10;} +html>body #currentSlide {position: fixed;} + +/* +div#header {background: #FCC;} +div#footer {background: #CCF;} +div#controls {background: #BBD;} +div#currentSlide {background: #FFC;} +*/ diff --git a/docs/pycon2010/ui/pycon/iepngfix.htc b/docs/pycon2010/ui/pycon/iepngfix.htc new file mode 100644 index 0000000..9f3d628 --- /dev/null +++ b/docs/pycon2010/ui/pycon/iepngfix.htc @@ -0,0 +1,42 @@ +<public:component> +<public:attach event="onpropertychange" onevent="doFix()" /> + +<script> + +// IE5.5+ PNG Alpha Fix v1.0 by Angus Turnbull http://www.twinhelix.com +// Free usage permitted as long as this notice remains intact. + +// This must be a path to a blank image. That's all the configuration you need here. +var blankImg = 'ui/default/blank.gif'; + +var f = 'DXImageTransform.Microsoft.AlphaImageLoader'; + +function filt(s, m) { + if (filters[f]) { + filters[f].enabled = s ? true : false; + if (s) with (filters[f]) { src = s; sizingMethod = m } + } else if (s) style.filter = 'progid:'+f+'(src="'+s+'",sizingMethod="'+m+'")'; +} + +function doFix() { + if ((parseFloat(navigator.userAgent.match(/MSIE (\S+)/)[1]) < 5.5) || + (event && !/(background|src)/.test(event.propertyName))) return; + + if (tagName == 'IMG') { + if ((/\.png$/i).test(src)) { + filt(src, 'image'); // was 'scale' + src = blankImg; + } else if (src.indexOf(blankImg) < 0) filt(); + } else if (style.backgroundImage) { + if (style.backgroundImage.match(/^url[("']+(.*\.png)[)"']+$/i)) { + var s = RegExp.$1; + style.backgroundImage = ''; + filt(s, 'crop'); + } else filt(); + } +} + +doFix(); + +</script> +</public:component>
\ No newline at end of file diff --git a/docs/pycon2010/ui/pycon/opera.css b/docs/pycon2010/ui/pycon/opera.css new file mode 100644 index 0000000..c9d1148 --- /dev/null +++ b/docs/pycon2010/ui/pycon/opera.css @@ -0,0 +1,8 @@ +/* This file has been placed in the public domain. */ +/* DO NOT CHANGE THESE unless you really want to break Opera Show */ +.slide { + visibility: visible !important; + position: static !important; + page-break-before: always; +} +#slide0 {page-break-before: avoid;} diff --git a/docs/pycon2010/ui/pycon/outline.css b/docs/pycon2010/ui/pycon/outline.css new file mode 100644 index 0000000..fa767e2 --- /dev/null +++ b/docs/pycon2010/ui/pycon/outline.css @@ -0,0 +1,16 @@ +/* This file has been placed in the public domain. */ +/* Don't change this unless you want the layout stuff to show up in the + outline view! */ + +.layout div, #footer *, #controlForm * {display: none;} +#footer, #controls, #controlForm, #navLinks, #toggle { + display: block; visibility: visible; margin: 0; padding: 0;} +#toggle {float: right; padding: 0.5em;} +html>body #toggle {position: fixed; top: 0; right: 0;} + +/* making the outline look pretty-ish */ + +#slide0 h1, #slide0 h2, #slide0 h3, #slide0 h4 {border: none; margin: 0;} +#toggle {border: 1px solid; border-width: 0 0 1px 1px; background: #FFF;} + +.outline {display: inline ! important;} diff --git a/docs/pycon2010/ui/pycon/pretty.css b/docs/pycon2010/ui/pycon/pretty.css new file mode 100644 index 0000000..1097903 --- /dev/null +++ b/docs/pycon2010/ui/pycon/pretty.css @@ -0,0 +1,120 @@ +/* This file has been placed in the public domain. */ +/* Following are the presentation styles -- edit away! */ + +html, body {margin: 0; padding: 0;} +body {background: white; color: black; font-family: sans-serif;} +/* Replace the background style above with the style below (and again for + div#header) for a graphic: */ +/* background: white url(bodybg.gif) -16px 0 no-repeat; */ +:link, :visited {text-decoration: none; color: #00C;} +#controls :active {color: #88A !important;} +#controls :focus {outline: 1px dotted #227;} +h1, h2, h3, h4 {font-size: 100%; margin: 0; padding: 0; font-weight: inherit;} + +blockquote {padding: 0 2em 0.5em; margin: 0 1.5em 0.5em;} +blockquote p {margin: 0;} + +kbd {font-weight: bold; font-size: 1em;} +sup {font-size: smaller; line-height: 1px;} + +.slide pre {padding: 0; margin-left: 0; margin-right: 0; font-size: 90%;} +.slide ul ul li {list-style: square;} +.slide img.leader {display: block; margin: 0 auto;} +.slide tt {font-size: 90%;} + +div#header, div#footer {background: green; color: #AAB; font-family: sans-serif;} +/* background: green url(bodybg.gif) -16px 0 no-repeat; */ +div#footer {font-size: 0.5em; font-weight: bold; padding: 1em 0;} +#footer h1 {display: block; padding: 0 1em;} +#footer h2 {display: block; padding: 0.8em 1em 0;} + +.slide {font-size: 1.2em;} +.slide h1 {position: absolute; top: 0.45em; z-index: 1; + margin: 0; padding-left: 0.7em; white-space: nowrap; + font: bold 150% sans-serif; color: #DDE; background: green;} +.slide h2 {font: bold 120%/1em sans-serif; padding-top: 0.5em;} +.slide h3 {font: bold 100% sans-serif; padding-top: 0.5em;} +h1 abbr {font-variant: small-caps;} + +div#controls {position: absolute; left: 50%; bottom: 0; + width: 50%; text-align: right; font: bold 0.9em sans-serif;} +html>body div#controls {position: fixed; padding: 0 0 1em 0; top: auto;} +div#controls form {position: absolute; bottom: 0; right: 0; width: 100%; + margin: 0; padding: 0;} +#controls #navLinks a {padding: 0; margin: 0 0.5em; + background: green; border: none; color: #779; cursor: pointer;} +#controls #navList {height: 1em;} +#controls #navList #jumplist {position: absolute; bottom: 0; right: 0; + background: #DDD; color: #227;} + +#currentSlide {text-align: center; font-size: 0.5em; color: #449; + font-family: sans-serif; font-weight: bold;} + +#slide0 {padding-top: 1.5em} +#slide0 h1 {position: static; margin: 1em 0 0; padding: 0; color: #000; + font: bold 2em sans-serif; white-space: normal; background: transparent;} +#slide0 h2 {font: bold italic 1em sans-serif; margin: 0.25em;} +#slide0 h3 {margin-top: 1.5em; font-size: 1.5em;} +#slide0 h4 {margin-top: 0; font-size: 1em;} + +ul.urls {list-style: none; display: inline; margin: 0;} +.urls li {display: inline; margin: 0;} +.external {border-bottom: 1px dotted gray;} +html>body .external {border-bottom: none;} +.external:after {content: " \274F"; font-size: smaller; color: #77B;} + +.incremental, .incremental *, .incremental *:after {visibility: visible; + color: white; border: 0;} +img.incremental {visibility: hidden;} +.slide .current {color: green;} + +.slide-display {display: inline ! important;} + +.huge {font-family: sans-serif; font-weight: bold; font-size: 150%;} +.big {font-family: sans-serif; font-weight: bold; font-size: 120%;} +.small {font-size: 75%;} +.tiny {font-size: 50%;} +.huge tt, .big tt, .small tt, .tiny tt {font-size: 115%;} +.huge pre, .big pre, .small pre, .tiny pre {font-size: 115%;} + +.maroon {color: maroon;} +.red {color: red;} +.magenta {color: magenta;} +.fuchsia {color: fuchsia;} +.pink {color: #FAA;} +.orange {color: orange;} +.yellow {color: yellow;} +.lime {color: lime;} +.green {color: green;} +.olive {color: olive;} +.teal {color: teal;} +.cyan {color: cyan;} +.aqua {color: aqua;} +.blue {color: blue;} +.navy {color: navy;} +.purple {color: purple;} +.black {color: black;} +.gray {color: gray;} +.silver {color: silver;} +.white {color: white;} + +.left {text-align: left ! important;} +.center {text-align: center ! important;} +.right {text-align: right ! important;} + +.animation {position: relative; margin: 1em 0; padding: 0;} +.animation img {position: absolute;} + +/* Docutils-specific overrides */ + +.slide table.docinfo {margin: 1em 0 0.5em 2em;} + +pre.literal-block, pre.doctest-block {background-color: white;} + +tt.docutils {background-color: white;} + +/* diagnostics */ +/* +li:after {content: " [" attr(class) "]"; color: #F88;} +div:before {content: "[" attr(class) "]"; color: #F88;} +*/ diff --git a/docs/pycon2010/ui/pycon/print.css b/docs/pycon2010/ui/pycon/print.css new file mode 100644 index 0000000..9d057cc --- /dev/null +++ b/docs/pycon2010/ui/pycon/print.css @@ -0,0 +1,24 @@ +/* This file has been placed in the public domain. */ +/* The following rule is necessary to have all slides appear in print! + DO NOT REMOVE IT! */ +.slide, ul {page-break-inside: avoid; visibility: visible !important;} +h1 {page-break-after: avoid;} + +body {font-size: 12pt; background: white;} +* {color: black;} + +#slide0 h1 {font-size: 200%; border: none; margin: 0.5em 0 0.25em;} +#slide0 h3 {margin: 0; padding: 0;} +#slide0 h4 {margin: 0 0 0.5em; padding: 0;} +#slide0 {margin-bottom: 3em;} + +#header {display: none;} +#footer h1 {margin: 0; border-bottom: 1px solid; color: gray; + font-style: italic;} +#footer h2, #controls {display: none;} + +.print {display: inline ! important;} + +/* The following rule keeps the layout stuff out of print. + Remove at your own risk! */ +.layout, .layout * {display: none !important;} diff --git a/docs/pycon2010/ui/pycon/s5-core.css b/docs/pycon2010/ui/pycon/s5-core.css new file mode 100644 index 0000000..6965f5e --- /dev/null +++ b/docs/pycon2010/ui/pycon/s5-core.css @@ -0,0 +1,11 @@ +/* This file has been placed in the public domain. */ +/* Do not edit or override these styles! + The system will likely break if you do. */ + +div#header, div#footer, div#controls, .slide {position: absolute;} +html>body div#header, html>body div#footer, + html>body div#controls, html>body .slide {position: fixed;} +.handout {display: none;} +.layout {display: block;} +.slide, .hideme, .incremental {visibility: hidden;} +#slide0 {visibility: visible;} diff --git a/docs/pycon2010/ui/pycon/slides.css b/docs/pycon2010/ui/pycon/slides.css new file mode 100644 index 0000000..82bdc0e --- /dev/null +++ b/docs/pycon2010/ui/pycon/slides.css @@ -0,0 +1,10 @@ +/* This file has been placed in the public domain. */ + +/* required to make the slide show run at all */ +@import url(s5-core.css); + +/* sets basic placement and size of slide components */ +@import url(framing.css); + +/* styles that make the slides look good */ +@import url(pretty.css); diff --git a/docs/pycon2010/ui/pycon/slides.js b/docs/pycon2010/ui/pycon/slides.js new file mode 100644 index 0000000..81e04e5 --- /dev/null +++ b/docs/pycon2010/ui/pycon/slides.js @@ -0,0 +1,558 @@ +// S5 v1.1 slides.js -- released into the Public Domain +// Modified for Docutils (http://docutils.sf.net) by David Goodger +// +// Please see http://www.meyerweb.com/eric/tools/s5/credits.html for +// information about all the wonderful and talented contributors to this code! + +var undef; +var slideCSS = ''; +var snum = 0; +var smax = 1; +var slideIDs = new Array(); +var incpos = 0; +var number = undef; +var s5mode = true; +var defaultView = 'slideshow'; +var controlVis = 'visible'; + +var isIE = navigator.appName == 'Microsoft Internet Explorer' ? 1 : 0; +var isOp = navigator.userAgent.indexOf('Opera') > -1 ? 1 : 0; +var isGe = navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('Safari') < 1 ? 1 : 0; + +function hasClass(object, className) { + if (!object.className) return false; + return (object.className.search('(^|\\s)' + className + '(\\s|$)') != -1); +} + +function hasValue(object, value) { + if (!object) return false; + return (object.search('(^|\\s)' + value + '(\\s|$)') != -1); +} + +function removeClass(object,className) { + if (!object) return; + object.className = object.className.replace(new RegExp('(^|\\s)'+className+'(\\s|$)'), RegExp.$1+RegExp.$2); +} + +function addClass(object,className) { + if (!object || hasClass(object, className)) return; + if (object.className) { + object.className += ' '+className; + } else { + object.className = className; + } +} + +function GetElementsWithClassName(elementName,className) { + var allElements = document.getElementsByTagName(elementName); + var elemColl = new Array(); + for (var i = 0; i< allElements.length; i++) { + if (hasClass(allElements[i], className)) { + elemColl[elemColl.length] = allElements[i]; + } + } + return elemColl; +} + +function isParentOrSelf(element, id) { + if (element == null || element.nodeName=='BODY') return false; + else if (element.id == id) return true; + else return isParentOrSelf(element.parentNode, id); +} + +function nodeValue(node) { + var result = ""; + if (node.nodeType == 1) { + var children = node.childNodes; + for (var i = 0; i < children.length; ++i) { + result += nodeValue(children[i]); + } + } + else if (node.nodeType == 3) { + result = node.nodeValue; + } + return(result); +} + +function slideLabel() { + var slideColl = GetElementsWithClassName('*','slide'); + var list = document.getElementById('jumplist'); + smax = slideColl.length; + for (var n = 0; n < smax; n++) { + var obj = slideColl[n]; + + var did = 'slide' + n.toString(); + if (obj.getAttribute('id')) { + slideIDs[n] = obj.getAttribute('id'); + } + else { + obj.setAttribute('id',did); + slideIDs[n] = did; + } + if (isOp) continue; + + var otext = ''; + var menu = obj.firstChild; + if (!menu) continue; // to cope with empty slides + while (menu && menu.nodeType == 3) { + menu = menu.nextSibling; + } + if (!menu) continue; // to cope with slides with only text nodes + + var menunodes = menu.childNodes; + for (var o = 0; o < menunodes.length; o++) { + otext += nodeValue(menunodes[o]); + } + list.options[list.length] = new Option(n + ' : ' + otext, n); + } +} + +function currentSlide() { + var cs; + var footer_nodes; + var vis = 'visible'; + if (document.getElementById) { + cs = document.getElementById('currentSlide'); + footer_nodes = document.getElementById('footer').childNodes; + } else { + cs = document.currentSlide; + footer = document.footer.childNodes; + } + cs.innerHTML = '<span id="csHere">' + snum + '<\/span> ' + + '<span id="csSep">\/<\/span> ' + + '<span id="csTotal">' + (smax-1) + '<\/span>'; + if (snum == 0) { + vis = 'hidden'; + } + cs.style.visibility = vis; + for (var i = 0; i < footer_nodes.length; i++) { + if (footer_nodes[i].nodeType == 1) { + footer_nodes[i].style.visibility = vis; + } + } +} + +function go(step) { + if (document.getElementById('slideProj').disabled || step == 0) return; + var jl = document.getElementById('jumplist'); + var cid = slideIDs[snum]; + var ce = document.getElementById(cid); + if (incrementals[snum].length > 0) { + for (var i = 0; i < incrementals[snum].length; i++) { + removeClass(incrementals[snum][i], 'current'); + removeClass(incrementals[snum][i], 'incremental'); + } + } + if (step != 'j') { + snum += step; + lmax = smax - 1; + if (snum > lmax) snum = lmax; + if (snum < 0) snum = 0; + } else + snum = parseInt(jl.value); + var nid = slideIDs[snum]; + var ne = document.getElementById(nid); + if (!ne) { + ne = document.getElementById(slideIDs[0]); + snum = 0; + } + if (step < 0) {incpos = incrementals[snum].length} else {incpos = 0;} + if (incrementals[snum].length > 0 && incpos == 0) { + for (var i = 0; i < incrementals[snum].length; i++) { + if (hasClass(incrementals[snum][i], 'current')) + incpos = i + 1; + else + addClass(incrementals[snum][i], 'incremental'); + } + } + if (incrementals[snum].length > 0 && incpos > 0) + addClass(incrementals[snum][incpos - 1], 'current'); + ce.style.visibility = 'hidden'; + ne.style.visibility = 'visible'; + jl.selectedIndex = snum; + currentSlide(); + number = 0; +} + +function goTo(target) { + if (target >= smax || target == snum) return; + go(target - snum); +} + +function subgo(step) { + if (step > 0) { + removeClass(incrementals[snum][incpos - 1],'current'); + removeClass(incrementals[snum][incpos], 'incremental'); + addClass(incrementals[snum][incpos],'current'); + incpos++; + } else { + incpos--; + removeClass(incrementals[snum][incpos],'current'); + addClass(incrementals[snum][incpos], 'incremental'); + addClass(incrementals[snum][incpos - 1],'current'); + } +} + +function toggle() { + var slideColl = GetElementsWithClassName('*','slide'); + var slides = document.getElementById('slideProj'); + var outline = document.getElementById('outlineStyle'); + if (!slides.disabled) { + slides.disabled = true; + outline.disabled = false; + s5mode = false; + fontSize('1em'); + for (var n = 0; n < smax; n++) { + var slide = slideColl[n]; + slide.style.visibility = 'visible'; + } + } else { + slides.disabled = false; + outline.disabled = true; + s5mode = true; + fontScale(); + for (var n = 0; n < smax; n++) { + var slide = slideColl[n]; + slide.style.visibility = 'hidden'; + } + slideColl[snum].style.visibility = 'visible'; + } +} + +function showHide(action) { + var obj = GetElementsWithClassName('*','hideme')[0]; + switch (action) { + case 's': obj.style.visibility = 'visible'; break; + case 'h': obj.style.visibility = 'hidden'; break; + case 'k': + if (obj.style.visibility != 'visible') { + obj.style.visibility = 'visible'; + } else { + obj.style.visibility = 'hidden'; + } + break; + } +} + +// 'keys' code adapted from MozPoint (http://mozpoint.mozdev.org/) +function keys(key) { + if (!key) { + key = event; + key.which = key.keyCode; + } + if (key.which == 84) { + toggle(); + return; + } + if (s5mode) { + switch (key.which) { + case 10: // return + case 13: // enter + if (window.event && isParentOrSelf(window.event.srcElement, 'controls')) return; + if (key.target && isParentOrSelf(key.target, 'controls')) return; + if(number != undef) { + goTo(number); + break; + } + case 32: // spacebar + case 34: // page down + case 39: // rightkey + case 40: // downkey + if(number != undef) { + go(number); + } else if (!incrementals[snum] || incpos >= incrementals[snum].length) { + go(1); + } else { + subgo(1); + } + break; + case 33: // page up + case 37: // leftkey + case 38: // upkey + if(number != undef) { + go(-1 * number); + } else if (!incrementals[snum] || incpos <= 0) { + go(-1); + } else { + subgo(-1); + } + break; + case 36: // home + goTo(0); + break; + case 35: // end + goTo(smax-1); + break; + case 67: // c + showHide('k'); + break; + } + if (key.which < 48 || key.which > 57) { + number = undef; + } else { + if (window.event && isParentOrSelf(window.event.srcElement, 'controls')) return; + if (key.target && isParentOrSelf(key.target, 'controls')) return; + number = (((number != undef) ? number : 0) * 10) + (key.which - 48); + } + } + return false; +} + +function clicker(e) { + number = undef; + var target; + if (window.event) { + target = window.event.srcElement; + e = window.event; + } else target = e.target; + if (target.href != null || hasValue(target.rel, 'external') || isParentOrSelf(target, 'controls') || isParentOrSelf(target,'embed') || isParentOrSelf(target, 'object')) return true; + if (!e.which || e.which == 1) { + if (!incrementals[snum] || incpos >= incrementals[snum].length) { + go(1); + } else { + subgo(1); + } + } +} + +function findSlide(hash) { + var target = document.getElementById(hash); + if (target) { + for (var i = 0; i < slideIDs.length; i++) { + if (target.id == slideIDs[i]) return i; + } + } + return null; +} + +function slideJump() { + if (window.location.hash == null || window.location.hash == '') { + currentSlide(); + return; + } + if (window.location.hash == null) return; + var dest = null; + dest = findSlide(window.location.hash.slice(1)); + if (dest == null) { + dest = 0; + } + go(dest - snum); +} + +function fixLinks() { + var thisUri = window.location.href; + thisUri = thisUri.slice(0, thisUri.length - window.location.hash.length); + var aelements = document.getElementsByTagName('A'); + for (var i = 0; i < aelements.length; i++) { + var a = aelements[i].href; + var slideID = a.match('\#.+'); + if ((slideID) && (slideID[0].slice(0,1) == '#')) { + var dest = findSlide(slideID[0].slice(1)); + if (dest != null) { + if (aelements[i].addEventListener) { + aelements[i].addEventListener("click", new Function("e", + "if (document.getElementById('slideProj').disabled) return;" + + "go("+dest+" - snum); " + + "if (e.preventDefault) e.preventDefault();"), true); + } else if (aelements[i].attachEvent) { + aelements[i].attachEvent("onclick", new Function("", + "if (document.getElementById('slideProj').disabled) return;" + + "go("+dest+" - snum); " + + "event.returnValue = false;")); + } + } + } + } +} + +function externalLinks() { + if (!document.getElementsByTagName) return; + var anchors = document.getElementsByTagName('a'); + for (var i=0; i<anchors.length; i++) { + var anchor = anchors[i]; + if (anchor.getAttribute('href') && hasValue(anchor.rel, 'external')) { + anchor.target = '_blank'; + addClass(anchor,'external'); + } + } +} + +function createControls() { + var controlsDiv = document.getElementById("controls"); + if (!controlsDiv) return; + var hider = ' onmouseover="showHide(\'s\');" onmouseout="showHide(\'h\');"'; + var hideDiv, hideList = ''; + if (controlVis == 'hidden') { + hideDiv = hider; + } else { + hideList = hider; + } + controlsDiv.innerHTML = '<form action="#" id="controlForm"' + hideDiv + '>' + + '<div id="navLinks">' + + '<a accesskey="t" id="toggle" href="javascript:toggle();">Ø<\/a>' + + '<a accesskey="z" id="prev" href="javascript:go(-1);">«<\/a>' + + '<a accesskey="x" id="next" href="javascript:go(1);">»<\/a>' + + '<div id="navList"' + hideList + '><select id="jumplist" onchange="go(\'j\');"><\/select><\/div>' + + '<\/div><\/form>'; + if (controlVis == 'hidden') { + var hidden = document.getElementById('navLinks'); + } else { + var hidden = document.getElementById('jumplist'); + } + addClass(hidden,'hideme'); +} + +function fontScale() { // causes layout problems in FireFox that get fixed if browser's Reload is used; same may be true of other Gecko-based browsers + if (!s5mode) return false; + var vScale = 22; // both yield 32 (after rounding) at 1024x768 + var hScale = 32; // perhaps should auto-calculate based on theme's declared value? + if (window.innerHeight) { + var vSize = window.innerHeight; + var hSize = window.innerWidth; + } else if (document.documentElement.clientHeight) { + var vSize = document.documentElement.clientHeight; + var hSize = document.documentElement.clientWidth; + } else if (document.body.clientHeight) { + var vSize = document.body.clientHeight; + var hSize = document.body.clientWidth; + } else { + var vSize = 700; // assuming 1024x768, minus chrome and such + var hSize = 1024; // these do not account for kiosk mode or Opera Show + } + var newSize = Math.min(Math.round(vSize/vScale),Math.round(hSize/hScale)); + fontSize(newSize + 'px'); + if (isGe) { // hack to counter incremental reflow bugs + var obj = document.getElementsByTagName('body')[0]; + obj.style.display = 'none'; + obj.style.display = 'block'; + } +} + +function fontSize(value) { + if (!(s5ss = document.getElementById('s5ss'))) { + if (!isIE) { + document.getElementsByTagName('head')[0].appendChild(s5ss = document.createElement('style')); + s5ss.setAttribute('media','screen, projection'); + s5ss.setAttribute('id','s5ss'); + } else { + document.createStyleSheet(); + document.s5ss = document.styleSheets[document.styleSheets.length - 1]; + } + } + if (!isIE) { + while (s5ss.lastChild) s5ss.removeChild(s5ss.lastChild); + s5ss.appendChild(document.createTextNode('body {font-size: ' + value + ' !important;}')); + } else { + document.s5ss.addRule('body','font-size: ' + value + ' !important;'); + } +} + +function notOperaFix() { + slideCSS = document.getElementById('slideProj').href; + var slides = document.getElementById('slideProj'); + var outline = document.getElementById('outlineStyle'); + slides.setAttribute('media','screen'); + outline.disabled = true; + if (isGe) { + slides.setAttribute('href','null'); // Gecko fix + slides.setAttribute('href',slideCSS); // Gecko fix + } + if (isIE && document.styleSheets && document.styleSheets[0]) { + document.styleSheets[0].addRule('img', 'behavior: url(ui/default/iepngfix.htc)'); + document.styleSheets[0].addRule('div', 'behavior: url(ui/default/iepngfix.htc)'); + document.styleSheets[0].addRule('.slide', 'behavior: url(ui/default/iepngfix.htc)'); + } +} + +function getIncrementals(obj) { + var incrementals = new Array(); + if (!obj) + return incrementals; + var children = obj.childNodes; + for (var i = 0; i < children.length; i++) { + var child = children[i]; + if (hasClass(child, 'incremental')) { + if (child.nodeName == 'OL' || child.nodeName == 'UL') { + removeClass(child, 'incremental'); + for (var j = 0; j < child.childNodes.length; j++) { + if (child.childNodes[j].nodeType == 1) { + addClass(child.childNodes[j], 'incremental'); + } + } + } else { + incrementals[incrementals.length] = child; + removeClass(child,'incremental'); + } + } + if (hasClass(child, 'show-first')) { + if (child.nodeName == 'OL' || child.nodeName == 'UL') { + removeClass(child, 'show-first'); + if (child.childNodes[isGe].nodeType == 1) { + removeClass(child.childNodes[isGe], 'incremental'); + } + } else { + incrementals[incrementals.length] = child; + } + } + incrementals = incrementals.concat(getIncrementals(child)); + } + return incrementals; +} + +function createIncrementals() { + var incrementals = new Array(); + for (var i = 0; i < smax; i++) { + incrementals[i] = getIncrementals(document.getElementById(slideIDs[i])); + } + return incrementals; +} + +function defaultCheck() { + var allMetas = document.getElementsByTagName('meta'); + for (var i = 0; i< allMetas.length; i++) { + if (allMetas[i].name == 'defaultView') { + defaultView = allMetas[i].content; + } + if (allMetas[i].name == 'controlVis') { + controlVis = allMetas[i].content; + } + } +} + +// Key trap fix, new function body for trap() +function trap(e) { + if (!e) { + e = event; + e.which = e.keyCode; + } + try { + modifierKey = e.ctrlKey || e.altKey || e.metaKey; + } + catch(e) { + modifierKey = false; + } + return modifierKey || e.which == 0; +} + +function startup() { + defaultCheck(); + if (!isOp) createControls(); + slideLabel(); + fixLinks(); + externalLinks(); + fontScale(); + if (!isOp) { + notOperaFix(); + incrementals = createIncrementals(); + slideJump(); + if (defaultView == 'outline') { + toggle(); + } + document.onkeyup = keys; + document.onkeypress = trap; + document.onclick = clicker; + } +} + +window.onload = startup; +window.onresize = function(){setTimeout('fontScale()', 50);} diff --git a/docs/pycon2010/urwid.png b/docs/pycon2010/urwid.png Binary files differnew file mode 100644 index 0000000..c2b5a9b --- /dev/null +++ b/docs/pycon2010/urwid.png diff --git a/docs/pycon2010/web-2-0-logos.gif b/docs/pycon2010/web-2-0-logos.gif Binary files differnew file mode 100644 index 0000000..9d48e37 --- /dev/null +++ b/docs/pycon2010/web-2-0-logos.gif diff --git a/docs/refresh.bash b/docs/refresh.bash new file mode 100755 index 0000000..d0b8651 --- /dev/null +++ b/docs/refresh.bash @@ -0,0 +1,8 @@ +make html +#scp -r build catherine@$tummy:/var/www/sqlpython +cd _build/html +zip -r cmd2_docs * +mv cmd2_docs.zip ../.. +cd .. +echo "Upload cmd2_docs.zip to http://pypi.python.org/pypi?%3Aaction=pkg_edit&name=cmd2" +scp -r _build/html www-data@$tummy:/var/www/cmd2 diff --git a/docs/settingchanges.rst b/docs/settingchanges.rst new file mode 100644 index 0000000..290e4e0 --- /dev/null +++ b/docs/settingchanges.rst @@ -0,0 +1,118 @@ +========================================= +Features requiring only parameter changes +========================================= + +Several aspects of a ``cmd2`` application's behavior +can be controlled simply by setting attributes of ``App``. +A parameter can also be changed at runtime by the user *if* +its name is included in the dictionary ``app.settable``. +(To define your own user-settable parameters, see :ref:`parameters`) + +Case-insensitivity +================== + +By default, all ``cmd2`` command names are case-insensitive; +``sing the blues`` and ``SiNg the blues`` are equivalent. To change this, +set ``App.case_insensitive`` to False. + +Whether or not you set ``case_insensitive``, *please do not* define +command method names with any uppercase letters. ``cmd2`` will probably +do something evil if you do. + +Shortcuts +========= + +Special-character shortcuts for common commands can make life more convenient for your +users. Shortcuts are used without a space separating them from their arguments, +like ``!ls``. By default, the following shortcuts are defined: + + ``?`` + help + + ``!`` + shell: run as OS-level command + + ``@`` + load script file + + ``@@`` + load script file; filename is relative to current script location + +To define more shortcuts, update the dict ``App.shortcuts`` with the +{'shortcut': 'command_name'} (omit ``do_``):: + + class App(Cmd2): + Cmd2.shortcuts.update({'*': 'sneeze', '~': 'squirm'}) + +Default to shell +================ + +Every ``cmd2`` application can execute operating-system +level (shell) commands with ``shell`` or a ``!`` +shortcut:: + + (Cmd) shell which python + /usr/bin/python + (Cmd) !which python + /usr/bin/python + +However, if the parameter ``default_to_shell`` is +``True``, then *every* command will be attempted on +the operating system. Only if that attempt fails +(i.e., produces a nonzero return value) will the +application's own ``default`` method be called. + +:: + + (Cmd) which python + /usr/bin/python + (Cmd) my dog has fleas + sh: my: not found + *** Unknown syntax: my dog has fleas + +Timing +====== + +Setting ``App.timing`` to ``True`` outputs timing data after +every application command is executed. |settable| + +Echo +==== + +If ``True``, each command the user issues will be repeated +to the screen before it is executed. This is particularly +useful when running scripts. + +Debug +===== + +Setting ``App.debug`` to ``True`` will produce detailed error stacks +whenever the application generates an error. |settable| + +.. |settable| replace:: The user can ``set`` this parameter + during application execution. + (See :ref:`parameters`) + + +Other user-settable parameters +============================== + +A list of all user-settable parameters, with brief +comments, is viewable from within a running application +with:: + + (Cmd) set --long + abbrev: True # Accept abbreviated commands + case_insensitive: True # upper- and lower-case both OK + colors: True # Colorized output (*nix only) + continuation_prompt: > # On 2nd+ line of input + debug: False # Show full error stack on error + default_file_name: command.txt # for ``save``, ``load``, etc. + echo: False # Echo command issued into output + editor: gedit # Program used by ``edit`` + feedback_to_output: False # include nonessentials in `|`, `>` results + prompt: (Cmd) # + quiet: False # Don't print nonessential feedback + timing: False # Report execution times + + diff --git a/docs/unfreefeatures.rst b/docs/unfreefeatures.rst new file mode 100644 index 0000000..1cd0081 --- /dev/null +++ b/docs/unfreefeatures.rst @@ -0,0 +1,251 @@ +====================================== +Features requiring application changes +====================================== + +Multiline commands +================== + +Command input may span multiple lines for the +commands whose names are listed in the +parameter ``app.multilineCommands``. These +commands will be executed only +after the user has entered a *terminator*. +By default, the command terminators is +``;``; replacing or appending to the list +``app.terminators`` allows different +terminators. A blank line +is *always* considered a command terminator +(cannot be overridden). + +Parsed statements +================= + +``cmd2`` passes ``arg`` to a ``do_`` method (or +``default`) as a ParsedString, a subclass of +string that includes an attribute ``parsed``. +``parsed`` is a ``pyparsing.ParseResults`` +object produced by applying a pyparsing_ +grammar applied to ``arg``. It may include: + +command + Name of the command called + +raw + Full input exactly as typed. + +terminator + Character used to end a multiline command + +suffix + Remnant of input after terminator + +:: + + def do_parsereport(self, arg): + self.stdout.write(arg.parsed.dump() + '\n') + +:: + + (Cmd) parsereport A B /* C */ D; E + ['parsereport', 'A B D', ';', 'E'] + - args: A B D + - command: parsereport + - raw: parsereport A B /* C */ D; E + - statement: ['parsereport', 'A B D', ';'] + - args: A B D + - command: parsereport + - terminator: ; + - suffix: E + - terminator: ; + +If ``parsed`` does not contain an attribute, +querying for it will return ``None``. (This +is a characteristic of ``pyparsing.ParseResults``.) + +ParsedString was developed to support sqlpython_ +and reflects its needs. The parsing grammar and +process are painfully complex and should not be +considered stable; future ``cmd2`` releases may +change it somewhat (hopefully reducing complexity). + +(Getting ``arg`` as a ``ParsedString`` is +technically "free", in that it requires no application +changes from the cmd_ standard, but there will +be no result unless you change your application +to *use* ``arg.parsed``.) + +.. _sqlpython: http://pypi.python.org/pypi/sqlpython/ + +.. _cmd: http://docs.python.org/library/cmd.html#module-cmd + +.. _pyparsing: http://pyparsing.wikispaces.com/ + +Environment parameters +====================== + +Your application can define user-settable parameters +which your code can reference. Create them as class attributes +with their default values, and add them (with optional +documentation) to ``settable``. + +:: + + from cmd2 import Cmd + class App(Cmd): + degrees_c = 22 + sunny = False + settable = Cmd.settable + '''degrees_c temperature in Celsius + sunny''' + def do_sunbathe(self, arg): + if self.degrees_c < 20: + result = "It's {temp} C - are you a penguin?".format(temp=self.degrees_c) + elif not self.sunny: + result = 'Too dim.' + else: + result = 'UV is bad for your skin.' + self.stdout.write(result + '\n') + app = App() + app.cmdloop() + +:: + + (Cmd) set --long + degrees_c: 22 # temperature in Celsius + sunny: False # + (Cmd) sunbathe + Too dim. + (Cmd) set sunny yes + sunny - was: False + now: True + (Cmd) sunbathe + UV is bad for your skin. + (Cmd) set degrees_c 13 + degrees_c - was: 22 + now: 13 + (Cmd) sunbathe + It's 13 C - are you a penguin? + + +Commands with flags +=================== + +All ``do_`` methods are responsible for interpreting +the arguments passed to them. However, ``cmd2`` lets +a ``do_`` methods accept Unix-style *flags*. It uses optparse_ +to parse the flags, and they work the same way as for +that module. + +Flags are defined with the ``options`` decorator, +which is passed a list of optparse_-style options, +each created with ``make_option``. The method +should accept a second argument, ``opts``, in +addition to ``args``; the flags will be stripped +from ``args``. + +:: + + @options([make_option('-p', '--piglatin', action="store_true", help="atinLay"), + make_option('-s', '--shout', action="store_true", help="N00B EMULATION MODE"), + make_option('-r', '--repeat', type="int", help="output [n] times") + ]) + def do_speak(self, arg, opts=None): + """Repeats what you tell me to.""" + arg = ''.join(arg) + if opts.piglatin: + arg = '%s%say' % (arg[1:].rstrip(), arg[0]) + if opts.shout: + arg = arg.upper() + repetitions = opts.repeat or 1 + for i in range(min(repetitions, self.maxrepeats)): + self.stdout.write(arg) + self.stdout.write('\n') + +:: + + (Cmd) say goodnight, gracie + goodnight, gracie + (Cmd) say -sp goodnight, gracie + OODNIGHT, GRACIEGAY + (Cmd) say -r 2 --shout goodnight, gracie + GOODNIGHT, GRACIE + GOODNIGHT, GRACIE + +``options`` takes an optional additional argument, ``arg_desc``. +If present, ``arg_desc`` will appear in place of ``arg`` in +the option's online help. + +:: + + @options([make_option('-t', '--train', action='store_true', help='by train')], + arg_desc='(from city) (to city)') + def do_travel(self, arg, opts=None): + 'Gets you from (from city) to (to city).' + + +:: + + (Cmd) help travel + Gets you from (from city) to (to city). + Usage: travel [options] (from-city) (to-city) + + Options: + -h, --help show this help message and exit + -t, --train by train + +.. _optparse: + +.. _outputters: + +poutput, pfeedback, perror +========================== + +Standard ``cmd`` applications produce their output with ``self.stdout.write('output')`` (or with ``print``, +but ``print`` decreases output flexibility). ``cmd2`` applications can use +``self.poutput('output')``, ``self.pfeedback('message')``, and ``self.perror('errmsg')`` +instead. These methods have these advantages: + +- More concise + - ``.pfeedback()`` destination is controlled by :ref:`quiet` parameter. + +color +===== + +Text output can be colored by wrapping it in the ``colorize`` method. + +.. automethod:: cmd2.Cmd.colorize + +.. _quiet: + +quiet +===== + +Controls whether ``self.pfeedback('message')`` output is suppressed; +useful for non-essential feedback that the user may not always want +to read. ``quiet`` is only relevant if +``app.pfeedback`` is sometimes used. + +``select`` +========== + +Presents numbered options to user, as bash ``select``. + +``app.select`` is called from within a method (not by the user directly; it is ``app.select``, not ``app.do_select``). + +.. automethod:: cmd2.Cmd.select + +:: + + def do_eat(self, arg): + sauce = self.select('sweet salty', 'Sauce? ') + result = '{food} with {sauce} sauce, yum!' + result = result.format(food=arg, sauce=sauce) + self.stdout.write(result + '\n') + +:: + + (Cmd) eat wheaties + 1. sweet + 2. salty + Sauce? 2 + wheaties with salty sauce, yum! +
\ No newline at end of file diff --git a/docs/upload_pycon.bash b/docs/upload_pycon.bash new file mode 100755 index 0000000..4f35188 --- /dev/null +++ b/docs/upload_pycon.bash @@ -0,0 +1,2 @@ +rst2s5.py --theme-url=pycon2010/ui/pycon pycon2010/pycon2010.rst pycon2010/pycon2010.html +scp -r pycon2010/ www-data@$tummy:/var/www/presentations/cmd_cmd2 |