From d7fb89fa339765b890a9f05a9f69c30cbf5c7df9 Mon Sep 17 00:00:00 2001 From: David Sansome Date: Wed, 16 Feb 2011 23:46:18 +0000 Subject: [PATCH] Add a Hello World Python script example to the docs --- doc/python/CMakeLists.txt | 10 +++ doc/python/doc-hello-world.epydoc | 102 +++++++++++++++++++++++++++++ doc/python/epydoc.css | 11 ++-- doc/python/generate_python_docs.py | 55 ++++++++++++++-- 4 files changed, 166 insertions(+), 12 deletions(-) create mode 100644 doc/python/doc-hello-world.epydoc diff --git a/doc/python/CMakeLists.txt b/doc/python/CMakeLists.txt index 26a0298ba..7416a4cb6 100644 --- a/doc/python/CMakeLists.txt +++ b/doc/python/CMakeLists.txt @@ -24,6 +24,16 @@ configure_file( COPYONLY ) +file(GLOB EPYDOC_PAGES ${CMAKE_CURRENT_SOURCE_DIR}/*.epydoc) +foreach(file ${EPYDOC_PAGES}) + get_filename_component(filename ${file} NAME) + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/${filename} + ${CMAKE_CURRENT_BINARY_DIR}/${filename} + COPYONLY + ) +endforeach(file) + add_custom_target(pythondocs generate_python_docs WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} diff --git a/doc/python/doc-hello-world.epydoc b/doc/python/doc-hello-world.epydoc new file mode 100644 index 000000000..0136905d6 --- /dev/null +++ b/doc/python/doc-hello-world.epydoc @@ -0,0 +1,102 @@ +Hello world! +============ + +Clementine allows users to load scripts written in Python. These scripts run +in a Python interpreter inside Clementine itself and have access to +Clementine's internals through a special L{clementine} module. Scripts can +create graphical user interfaces using the Python Qt bindings. + +Let's begin by creating a script that shows a dialog box when loaded. + +Creating a simple script +======================== + +Create a directory called C{helloworld}. All files for this script will live +in this directory. + +Inside the C{helloworld} directory create a file called C{main.py}. This will +contain all the Python source code for this script. + + >>> from PyQt4.QtGui import QMessageBox + ... + ... QMessageBox.information(None, "Hello world!", "My script was loaded!") + +B{Note:} It is possible (and recommended) to split large scripts up into multiple +classes stored in separate files, and C{import} them as in a normal Python +application. For now we will put all the code into a single file. + +This code imports the C{PyQt4.QtGui.QMessageBox} class from the Python Qt +bindings and displays a simple information message box when the script is +loaded. + +The script.ini +============== + +You now have some Python source code in a directory, but Clementine won't +recognise it as being a loadable script. You need to create a C{script.ini} +file with some information about your script: + + >>> [Script] + ... name=Hello world! + ... description=My first script + ... author=Fred + ... url=http://www.example.com + ... icon=:/icon.png + ... + ... language=python + ... script_file=main.py + +Let's look at what each of these fields is for: + + - B{name} - The short name of your script that is displayed to the user in + bold in the Script Manager dialog. + - B{description} - A longer description of your script. Try to explain + briefly what the script does and what the user should do to start using it. + - B{author} I{[optional]} - Your name and email address in the format + C{Name }. This is not currently used, but may be in the + future. + - B{url} I{[optional]} - A URL of this script's homepage. This is not + currently used, but may be in the future. + - B{icon} - The filename (relative to the script's directory) of an icon to + display next to the script in the Script Manager dialog. You can put an + image (.png or .jpg) into the C{helloworld} directory and refer to that + here. The image should be at least 64x64 pixels big. Notice in this + example we use a filename starting with C{:/}. This is a Qt resource path, + and refers to one of the icons embedded within Clementine. + - B{language} - The language the script is written in. Currently this must + be set to C{python}, but more languages may be supported in the future. + - B{script_file} - The Python source file to load for this script. If your + script consists of multiple files then the one specified here is the main + one that will be loaded first. + +Adding the script to Clementine +=============================== + +Clementine searches for its scripts in a couple of different places depending +on the operating system: + +B{On Windows:} + + - C{%UserProfile%\.config\Clementine\scripts} (where C{%UserProfile%} might be + C{C:\Users\YourUsername} on Windows Vista or Windows 7, or + C{C:\Documents and Settings\YourUsername} on XP). + - C{C:\Program Files\Clementine\scripts} + +B{On Linux:} + + - C{~/.config/Clementine/scripts} + - C{/usr/share/clementine/scripts} + - C{/usr/local/share/clementine/scripts} + - C{$PREFIX/share/clementine/scripts} (if Clementine was installed into a + different prefix). + +B{On Mac OS X:} + + - C{~/Library/Application Support/Clementine/scripts} + +For development you should copy your C{helloworld} directory (or create a +symbolic link) into one of these locations. Clementine should notice the new +script straight away and add it to the Script Manager dialog. + +Load your script by clicking on it in the Script Manager dialog and clicking +the C{Enable} button. diff --git a/doc/python/epydoc.css b/doc/python/epydoc.css index 5cd38a5ae..3ab756e5c 100644 --- a/doc/python/epydoc.css +++ b/doc/python/epydoc.css @@ -34,7 +34,7 @@ h2 { font-size: +125%; font-weight: bold; } h3 { font-size: +110%; font-style: italic; font-weight: normal; } -code { font-size: 100%; font-family: monospace; +code { font-family: monospace; color: #007000; } hr { height: 1px; background-color: #BBB; border: 0px; } /* N.B.: class, not pseudoclass */ @@ -76,8 +76,9 @@ div.sidebar { left: 0px; top: 0px; width: 350px; - margin-left: 6px; - margin-right: 6px; + padding-left: 6px; + padding-right: 6px; + border-right: 3px solid #E5ECF9; } div.maincontent { @@ -286,8 +287,8 @@ div.py-highlight-hdr { border-top: 2px solid #000000; background: #d8e8e8; } div.py-highlight { border-bottom: 2px solid #000000; background: #d0e0e0; } -.py-prompt { color: #005050; font-weight: bold;} -.py-more { color: #005050; font-weight: bold;} +.py-prompt { color: #005050; font-weight: bold; display: none; } +.py-more { color: #005050; font-weight: bold; display: none; } .py-string { color: #006030; } .py-comment { color: #003060; } .py-keyword { color: #600000; } diff --git a/doc/python/generate_python_docs.py b/doc/python/generate_python_docs.py index 70d858d83..4f262238b 100644 --- a/doc/python/generate_python_docs.py +++ b/doc/python/generate_python_docs.py @@ -1,12 +1,22 @@ +import epydoc import epydoc.apidoc import epydoc.cli +import epydoc.docbuilder import epydoc.docintrospecter import epydoc.docwriter.html +import epydoc.markup.epytext import inspect import PyQt4.QtCore import sys import types +DOC_PAGES = [ + ("Hello world!", "doc-hello-world"), +] + +OUTPUT_DIR = "output" + + # SIP does some strange stuff with the __dict__ of wrapped C++ classes: # someclass.__dict__["function"] != someclass.function # These little hacks make epydoc generate documentation for the actual functions @@ -43,21 +53,27 @@ def my_write_header(self, out, title): out('') out('
') @@ -82,7 +98,7 @@ epydoc.docwriter.html.HTMLWriter.write_toc_section = my_write_toc_section sys.argv = [ "epydoc", "--html", - "-o", "output", + "-o", OUTPUT_DIR, "-v", "--name", "clementine", "--url", "http://www.clementine-player.org", @@ -94,4 +110,29 @@ sys.argv = [ ] print "Running '%s'" % ' '.join(sys.argv) -epydoc.cli.cli() + +# Parse arguments +(options, names) = epydoc.cli.parse_arguments() + +# Write the main docs - this is copied from cli() +epydoc.docstringparser.DEFAULT_DOCFORMAT = options.docformat +docindex = epydoc.docbuilder.build_doc_index(names, + options.introspect, options.parse, + add_submodules=True) +html_writer = epydoc.docwriter.html.HTMLWriter(docindex, **options.__dict__) +html_writer.write(options.target) + +# Write extra pages +def write_extra_page(out, title, source): + handle = open(source, 'r') + parsed_docstring = epydoc.markup.epytext.parse_docstring(handle.read(), []) + html_writer.write_header(out, title) + out(html_writer.docstring_to_html(parsed_docstring)) + html_writer.write_footer(out) + +for (title, filename) in DOC_PAGES: + source = "%s.epydoc" % filename + html = "%s.html" % filename + print "Generating '%s' from '%s'..." % (html, source) + + html_writer._write(write_extra_page, OUTPUT_DIR, html, title, source)