diff --git a/.hgignore b/.hgignore
new file mode 100644
--- /dev/null
+++ b/.hgignore
@@ -0,0 +1,4 @@
+^\.newer$
+^\.snippets/
+^\.sync\.rc$
+^lib/\.htpasswd$
diff --git a/.htaccess.in b/.htaccess.in
new file mode 100644
--- /dev/null
+++ b/.htaccess.in
@@ -0,0 +1,28 @@
+
+order allow,deny
+Deny from all
+
+
+
+order allow,deny
+Deny from all
+
+
+
+order allow,deny
+Deny from all
+
+
+
+order allow,deny
+Deny from all
+
+
+AuthUserFile @base_dir@/lib/.htpasswd
+# AuthGroupFile .htgroup
+
+# User authorization
+AuthType Basic
+AuthName "Urlaubseinstellungen"
+require valid-user
+
diff --git a/Makefile b/Makefile
new file mode 100644
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,101 @@
+# -*- makefile -*-
+
+top_srcdir = .
+srcdir = .
+
+SUDOERS_D = /etc/sudoers.d
+
+base_dir=$(shell pwd)
+
+SUBDIRS = doc
+
+INPUTS =
+TXTS =
+HTML_TXTS =
+EXTRA_DIST =
+CLEANFILES =
+
+INPUTS += .htaccess.in
+INPUTS += lib/ws-vacation-sudo.in
+INPUTS += lib/ws-vacation.conf.in
+
+TARGETS = $(patsubst %.in,%,$(INPUTS))
+CLEANFILES += $(TARGETS)
+
+TXT_PDFS = $(patsubst %.txt,%.pdf,$(TXTS))
+TXT_HTMLS = $(patsubst %.txt,%.html,$(TXTS)) $(patsubst %.txt,%.html,$(HTML_TXTS))
+CLEANFILES += $(TXT_PDFS)
+CLEANFILES += $(TXT_HTMLS)
+
+SNIPPETS = ./lib/snippets.pl
+
+DISTFILES =
+DISTFILES += Makefile
+DISTFILES += $(INPUTS)
+DISTFILES += $(TARGETS)
+DISTFILES += $(TXTS)
+DISTFILES += $(TXT_PDFS)
+DISTFILES += $(TXT_HTMLS)
+DISTFILES += $(EXTRA_DIST)
+
+%: %.in
+ cat $< | $(SNIPPETS) --process --replace --mode text --key base_dir --value $(base_dir) --cat - >$@
+ test -s $@ || ( rm -f $@ && test 1 = 0 )
+
+%.pdf: %.txt
+ cd doc && $(MAKE) ../$@
+
+%.html: %.txt
+ cd doc && $(MAKE) ../$@
+
+default: all
+
+all: $(DISTFILES) all-local
+
+all-local: doc
+
+.PHONY: doc
+doc:
+ ( cd doc && $(MAKE) )
+
+clean: clean-local
+ test -z '$(CLEANFILES)' || rm -rf $(CLEANFILES)
+
+clean-local:
+ ( cd doc && $(MAKE) clean )
+
+
+install: all
+ mkdir -p $(SUDOERS_D)
+
+dist:
+
+tags-rc:
+ gen_tags.sh --template
+tags:
+ gen_tags.sh --force
+
+# |:here:|
+# :ide-menu: Emacs IDE Main Menu - Buffer @BUFFER@
+# . M-x `eIDE-menu' ()(eIDE-menu "z")
+
+# :ide: COMPILE: tags
+# . (let ((args "tags")) (compile (concat "make -k " args)))
+
+# :ide: COMPILE: dist
+# . (let ((args "dist")) (compile (concat "make -k " args)))
+
+# :ide: COMPILE: install
+# . (let ((args "install")) (compile (concat "make -k " args)))
+
+# :ide: COMPILE: clean
+# . (let ((args "clean")) (compile (concat "make -k " args)))
+
+# :ide: COMPILE: Standard
+# . (let ((args "")) (compile (concat "make -k " args)))
+#
+# Local Variables:
+# mode: makefile
+# snip-mode: makefile-gmake
+# truncate-lines: t
+# End:
diff --git a/README.txt b/README.txt
new file mode 100644
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,240 @@
+.. -*- coding: utf-8 -*-
+.. \||<-snip->|| start
+.. Copyright (C) 2012, Wolfgang Scherer,
+.. Sponsored by WIEDENMANN SEILE GMBH, http://www.wiedenmannseile.de
+..
+.. This file is part of Wiedenmann Vacation.
+..
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.3 or any later version published by the Free Software
+.. Foundation; with no Invariant Sections, no Front-Cover Texts, and
+.. no Back-Cover Texts. A copy of the license is included in the main
+.. documentation of Wiedenmann Vacation.
+
+.. (progn (forward-line 1)(snip-insert-mode "rst_t.inline-comments" t))
+.. inline comments (with ws_docutils)
+.. role:: rem(span)
+ :format: ''
+.. role:: html(span)
+ :format: html
+ :raw:
+
+.. role:: ihtml(span)
+ :format: html
+.. role:: nhtml(span)
+ :format: !html
+
+##################################################
+:rem:`|||:sec:|||`\ Wiedenmann Vacation
+##################################################
+Web Front-End to Manage vacation(1) Settings
+##################################################
+.. \||<-snap->|| skip
+
+:Author: `Wolfgang Scherer`_
+
+.. contents::
+.. \||<-snap->|| skip
+.. \||<-snap->|| include ^index-header.snip$
+
+==================================================
+:rem:`|||:sec:|||`\ Installation
+==================================================
+
+#. Copy the program anywhere on your harddrive.
+
+#. Change alias `/vacation` in `lib/ws-vacation.conf.in`, if desired.
+
+#. Execute the following commands (as user) to create the run-time files:
+
+ >>> make clean
+ >>> make
+
+ This substitutes the installation directory in the necessary places.
+
+#. Copy `lib/ws-vacation.conf` to `/etc/apache2/conf.d/`.
+
+#. Reload the Apache server:
+
+ >>> rcapache2 reload.
+
+#. The sudo(1) setup allows the apache server to execute vacation(1)
+ as any user (except root) without a password. This is activated by
+ copying the file `lib/ws-vacation-sudo` into the directory
+ `/etc/sudoers.d` (ubuntu):
+
+ >>> cp lib/ws-vacation-sudo /etc/sudoers.d/ws-vacation-sudo
+ >>> chmod 0440 /etc/sudoers.d/ws-vacation-sudo
+
+ or by appending it to the file `/etc/sudoers` (older SuSE):
+
+ >>> cat lib/ws-vacation-sudo >>/etc/sudoers
+
+==================================================
+:rem:`|||:sec:|||`\ User Management
+==================================================
+
+The file `lib/.htpasswd` can be created by the regular means.
+
+An automated script is available that creates the password database
+from the system shadow(8) database. Just change into directory `lib`
+and execute (as `root`):
+
+>>> php gen_htpasswd.php
+
+.. note:: If new users are created in the system, this step must be
+ repeated to update the `.htpasswd` file.
+
+:rem:`abstand`
+
+==================================================
+:rem:`|||:sec:|||`\ Configuration
+==================================================
+
+The file `lib/config.php` contains the basic configuration data.
+
+It is possible to fine-tune the standard user selection with:
+
+* $ALLOWED_USERS: users who are always accepted (if present in `/etc/passwd`).
+* $INVALID_USERS: invalid users, which are always ignored.
+* $ADMIN_USERS: administrators.
+
+The file `lib/language.php` contains language specific translation and
+also the default vacation(1) message text.
+
+The HTML header and footer can be modified in `lib/templates.php`.
+
+.. ==================================================
+.. :rem:`|||:sec:|||`\ Footnotes
+.. ==================================================
+
+:html:``
+
+.. \[#]
+
+.. ==================================================
+.. :rem:`|||:sec:|||`\ References
+.. ==================================================
+
+.. \||<-snap->|| include ^index-footer.snip$
+
+:rem:`|||:sec:|||`\ **Copyright**
+
+Copyright (C) 2012, Wolfgang Scherer, .
+Sponsored by `Wiedenmann-Seile GmbH`_.
+
+.. div::
+ :format: html
+
+ See section |GFDL| for license conditions for the documentation.
+
+ See section |GPL| for license conditions for the program.
+
+.. div::
+ :format: !html
+
+ See *GNU Free Documentation License* in file `GFDL.txt` for license
+ conditions for the documentation.
+
+ See *GNU General Public License* in file `COPYING` for license
+ conditions for the program.
+
+.. |GFDL| replace:: `GNU Free Documentation License`_
+.. |GPL| replace:: `GNU General Public License`_
+
+.. _`GNU Free Documentation License`: README-GFDL.html
+.. _`GNU General Public License`: README-COPYING.html
+.. _`Wiedenmann-Seile GmbH`: http://www.wiedenmannseile.de
+.. _`Wolfgang Scherer`: sw@wiedenmann-seile.de
+
+.. \||<-snip->|| stop
+
+.. ==================================================
+.. :rem:`|||:sec:|||`\ END
+.. ==================================================
+..
+.. :ide-menu: Emacs IDE Main Menu - Buffer @BUFFER@
+.. . M-x `eIDE-menu' ()(eIDE-menu "z")
+
+.. :ide: DELIM: SNIPPETS (ABOUT) |q|<- SYM ->||, ||<- SYM ->||, @| SYM @
+.. . (let nil (symbol-tag-normalize-delimiter (cons (cons nil "||<-") (cons "->||" nil)) t) (symbol-tag-switch-delimiter-sets) (symbol-tag-normalize-delimiter (cons (cons nil "||<-") (cons "->||" nil)) t) (setq symbol-tag-match-rx "sn[i]p") (setq symbol-tag-enclose-delimiter-set (symbol-tag-normalize-delimiter (cons (cons nil "@|") (cons "@" nil)))))
+
+.. :ide: DELIM: SNIPPETS (DOC) ||<- SYM ->||, |: SYM :|, ` SYM `
+.. . (let nil (symbol-tag-normalize-delimiter (cons (cons nil "|:") (cons ":|" nil)) t) (symbol-tag-switch-delimiter-sets) (symbol-tag-normalize-delimiter (cons (cons nil "||<-") (cons "->||" nil)) t) (setq symbol-tag-match-rx "sn[i]p") (setq symbol-tag-enclose-delimiter-set (symbol-tag-normalize-delimiter (cons (cons "\\(\\`\\|[^\\]\\)" "`") (cons "`" nil)))))
+
+.. :ide: DELIM: SNIPPETS (SNIP DOC) ||<- SYM ->||, |: SYM :|, @ SYM @
+.. . (let nil (symbol-tag-normalize-delimiter (cons (cons nil "|:") (cons ":|" nil)) t) (symbol-tag-switch-delimiter-sets) (symbol-tag-normalize-delimiter (cons (cons nil "||<-") (cons "->||" nil)) t) (setq symbol-tag-match-rx "sn[i]p") (setq symbol-tag-enclose-delimiter-set (symbol-tag-normalize-delimiter (cons (cons nil "@") (cons "@" nil)))))
+
+.. :ide: DELIM: SNIPPETS (FILLME) ||<- SYM ->||, :: SYM ::, @ SYM @
+.. . (let nil (symbol-tag-normalize-delimiter (cons (cons nil "::") (cons "::" nil)) t) (symbol-tag-switch-delimiter-sets) (symbol-tag-normalize-delimiter (cons (cons nil "||<-") (cons "->||" nil)) t) (setq symbol-tag-match-rx "sn[i]p") (setq symbol-tag-enclose-delimiter-set (symbol-tag-normalize-delimiter (cons (cons nil "@") (cons "@" nil)))))
+
+.. :ide: DELIM: SNIPPETS (SUBST) ||<- SYM ->||, @ SYM @, @ SYM @
+.. . (let nil (symbol-tag-normalize-delimiter (cons (cons nil "@") (cons "@" nil)) t) (symbol-tag-switch-delimiter-sets) (symbol-tag-normalize-delimiter (cons (cons nil "||<-") (cons "->||" nil)) t) (setq symbol-tag-match-rx "sn[i]p") (setq symbol-tag-enclose-delimiter-set (symbol-tag-normalize-delimiter (cons (cons "[^\\]" "`") (cons "`" nil)))))
+
+.. :ide: +#-
+.. . Snippet Delimiter Sets ()
+
+.. :ide: DELIM: ReST (links) ` SYM `_, .. _` SYM `, ` SYM `
+.. . (let nil (symbol-tag-normalize-delimiter (cons (cons "[^\\]" "`") (cons "`_" nil)) t) (symbol-tag-switch-delimiter-sets) (symbol-tag-normalize-delimiter (cons (cons nil ".. _`") (cons "`:" nil)) t) (setq symbol-tag-enclose-delimiter-set (symbol-tag-normalize-delimiter (cons (cons "\\(\\`\\|[^\\]\\)" "`") (cons "`" nil)))))
+
+.. :ide: DELIM: STANDARD (GNU quoting) |: SYM :|, :: SYM ::, ` SYM '
+.. . (let nil (symbol-tag-normalize-delimiter (cons (cons nil "::") (cons "::" nil)) t) (symbol-tag-switch-delimiter-sets) (symbol-tag-normalize-delimiter (cons (cons nil "|:") (cons ":|" nil)) t) (setq symbol-tag-enclose-delimiter-set (symbol-tag-normalize-delimiter (cons (cons nil "`") (cons "'" nil)))))
+
+.. :ide: DELIM: STANDARD (ReST quoting) |: SYM :|, :: SYM ::, ` SYM `
+.. . (let nil (symbol-tag-normalize-delimiter (cons (cons nil "::") (cons "::" nil)) t) (symbol-tag-switch-delimiter-sets) (symbol-tag-normalize-delimiter (cons (cons nil "|:") (cons ":|" nil)) t) (setq symbol-tag-enclose-delimiter-set (symbol-tag-normalize-delimiter (cons (cons "[^\\]" "`") (cons "`" nil)))))
+
+.. :ide: +#-
+.. . Delimiter Sets ()
+
+.. :ide: COMPILE: render reST as LaTeX
+.. . (let* ((fp (buffer-file-name)) (fn (file-name-nondirectory fp))) (save-match-data (if (string-match-t "[.][^.]*$" fn) (setq fn (replace-match "" nil t fn)))) (let ((args (concat " " fp " | ws_rst2latex.py --traceback | tee " fn ".tex"))) (save-buffer) (compile (concat "PATH=\".:$PATH\"; cat " args))))
+
+.. :ide: COMPILE: render reST as MAN
+.. . (let* ((fp (buffer-file-name)) (fn (file-name-nondirectory fp))) (save-match-data (if (string-match-t "[.][^.]*$" fn) (setq fn (replace-match "" nil t fn)))) (let ((args (concat " " fp " | ws_rst2man.py --traceback "))) (save-buffer) (compile (concat "PATH=\".:$PATH\"; cat " args))))
+
+.. :ide: COMPILE: render reST as TXT (via MAN)
+.. . (let* ((fp (buffer-file-name)) (fn (file-name-nondirectory fp))) (save-match-data (if (string-match-t "[.][^.]*$" fn) (setq fn (replace-match "" nil t fn)))) (let ((args (concat " " fp " | ws_rst2man.py --traceback | man -l -"))) (save-buffer) (compile (concat "PATH=\".:$PATH\"; cat " args))))
+
+.. :ide: COMPILE: render reST as ODT --strip-comments
+.. . (let* ((fp (buffer-file-name)) (fn (file-name-nondirectory fp))) (save-match-data (if (string-match-t "[.][^.]*$" fn) (setq fn (replace-match "" nil t fn)))) (let ((args (concat " " fp " | ws_rst2odt.py --traceback --strip-comments | cat >" fn ".odt "))) (save-buffer) (compile (concat "PATH=\".:$PATH\"; cat " args))))
+
+.. :ide: COMPILE: render reST as LaTeX, compile PDF and view with gv
+.. . (let* ((fp (buffer-file-name)) (fn (file-name-nondirectory fp))) (save-match-data (if (string-match-t "[.][^.]*$" fn) (setq fn (replace-match "" nil t fn)))) (let ((args (concat " " fp " | ws_rst2latex.py --traceback | tee " fn ".tex && pdflatex '\\nonstopmode\\input " fn ".tex' && gv " fn ".pdf"))) (save-buffer) (compile (concat "PATH=\".:$PATH\"; cat " args))))
+
+.. :ide: COMPILE: render reST as PDF
+.. . (let* ((fp (buffer-file-name)) (fn (file-name-nondirectory fp))) (save-match-data (if (string-match-t "[.][^.]*$" fn) (setq fn (replace-match "" nil t fn)))) (let ((args (concat " " fp " | ws_rst2pdf -e ws_docutils.raw_role >" fn ".pdf"))) (save-buffer) (compile (concat "PATH=\".:$PATH\"; cat " args))))
+
+.. :ide: COMPILE: render reST as HTML
+.. . (let* ((fp (buffer-file-name)) (fn (file-name-nondirectory fp))) (save-match-data (if (string-match-t "[.][^.]*$" fn) (setq fn (replace-match "" nil t fn)))) (let ((args (concat " " fp " | ws_rst2html.py --traceback --cloak-email-addresses | tee " fn ".html "))) (save-buffer) (compile (concat "PATH=\".:$PATH\"; cat " args))))
+
+.. :ide: COMPILE: render reST as pseudoXML
+.. . (let* ((fp (buffer-file-name)) (fn (file-name-nondirectory fp))) (save-match-data (if (string-match-t "[.][^.]*$" fn) (setq fn (replace-match "" nil t fn)))) (let ((args (concat " --traceback " fp " 2>&1 #| tee " fn ".pxml"))) (save-buffer) (compile (concat "PATH=\".:$PATH\"; ws_rst2pseudoxml.py " args))))
+
+.. :ide: +#-
+.. . Process ()
+
+.. :ide: QUO: ~~ Subsubsection ~~
+.. . (insert "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\:rem\:`|\:sec\:|`\\ ::fillme\::\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" )
+
+.. :ide: QUO: -- Subsection --
+.. . (insert "--------------------------------------------------\n\:rem\:`||\:sec\:||`\\ ::fillme\::\n--------------------------------------------------\n" )
+
+.. :ide: QUO: == Section ==
+.. . (insert "==================================================\n\:rem\:`|||\:sec\:|||`\\ ::fillme\::\n==================================================\n" )
+
+.. :ide: +#-
+.. . Sections ()
+
+.. :ide: MENU-OUTLINE: `|||:section:|||' (default)
+.. . (x-eIDE-menu-outline "sec" '("|:" ":|") (cons (cons "^" ".. ") (cons nil nil)) "\\(_`[^`\n]+`\\|\\[[^]\n]+\\]\\|[|][^|\n]+[|]\\|[^:\n]+::\\)")
+
+..
+.. Local Variables:
+.. mode: rst
+.. snip-mode: rst
+.. truncate-lines: t
+.. symbol-tag-symbol-regexp: "[-0-9A-Za-z_#]\\([-0-9A-Za-z_. ]*[-0-9A-Za-z_]\\|\\)"
+.. symbol-tag-auto-comment-mode: nil
+.. symbol-tag-srx-is-safe-with-nil-delimiters: nil
+.. End:
diff --git a/css/basic.css b/css/basic.css
new file mode 100644
--- /dev/null
+++ b/css/basic.css
@@ -0,0 +1,527 @@
+/*
+ * basic.css
+ * ~~~~~~~~~
+ *
+ * Sphinx stylesheet -- basic theme.
+ *
+ * :copyright: Copyright 2007-2010 by the Sphinx team, see AUTHORS.
+ * :license: BSD, see LICENSE for details.
+ *
+ */
+
+/* -- main layout ----------------------------------------------------------- */
+
+div.clearer {
+ clear: both;
+}
+
+/* -- relbar ---------------------------------------------------------------- */
+
+div.related {
+ width: 100%;
+ font-size: 90%;
+}
+
+div.related h3 {
+ display: none;
+}
+
+div.related ul {
+ margin: 0;
+ padding: 0 0 0 10px;
+ list-style: none;
+}
+
+div.related li {
+ display: inline;
+}
+
+div.related li.right {
+ float: right;
+ margin-right: 5px;
+}
+
+/* -- sidebar --------------------------------------------------------------- */
+
+div.sphinxsidebarwrapper {
+ padding: 10px 5px 0 10px;
+}
+
+div.sphinxsidebar {
+ float: left;
+ width: 230px;
+ margin-left: -100%;
+ font-size: 90%;
+}
+
+div.sphinxsidebar ul {
+ list-style: none;
+}
+
+div.sphinxsidebar ul ul,
+div.sphinxsidebar ul.want-points {
+ margin-left: 20px;
+ list-style: square;
+}
+
+div.sphinxsidebar ul ul {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+div.sphinxsidebar form {
+ margin-top: 10px;
+}
+
+div.sphinxsidebar input {
+ border: 1px solid #98dbcc;
+ font-family: sans-serif;
+ font-size: 1em;
+}
+
+img {
+ border: 0;
+}
+
+/* -- search page ----------------------------------------------------------- */
+
+ul.search {
+ margin: 10px 0 0 20px;
+ padding: 0;
+}
+
+ul.search li {
+ padding: 5px 0 5px 20px;
+ background-image: url(file.png);
+ background-repeat: no-repeat;
+ background-position: 0 7px;
+}
+
+ul.search li a {
+ font-weight: bold;
+}
+
+ul.search li div.context {
+ color: #888;
+ margin: 2px 0 0 30px;
+ text-align: left;
+}
+
+ul.keywordmatches li.goodmatch a {
+ font-weight: bold;
+}
+
+/* -- index page ------------------------------------------------------------ */
+
+table.contentstable {
+ width: 90%;
+}
+
+table.contentstable p.biglink {
+ line-height: 150%;
+}
+
+a.biglink {
+ font-size: 1.3em;
+}
+
+span.linkdescr {
+ font-style: italic;
+ padding-top: 5px;
+ font-size: 90%;
+}
+
+/* -- general index --------------------------------------------------------- */
+
+table.indextable {
+ width: 100%;
+}
+
+table.indextable td {
+ text-align: left;
+ vertical-align: top;
+}
+
+table.indextable dl, table.indextable dd {
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+table.indextable tr.pcap {
+ height: 10px;
+}
+
+table.indextable tr.cap {
+ margin-top: 10px;
+ background-color: #f2f2f2;
+}
+
+img.toggler {
+ margin-right: 3px;
+ margin-top: 3px;
+ cursor: pointer;
+}
+
+div.modindex-jumpbox {
+ border-top: 1px solid #ddd;
+ border-bottom: 1px solid #ddd;
+ margin: 1em 0 1em 0;
+ padding: 0.4em;
+}
+
+div.genindex-jumpbox {
+ border-top: 1px solid #ddd;
+ border-bottom: 1px solid #ddd;
+ margin: 1em 0 1em 0;
+ padding: 0.4em;
+}
+
+/* -- general body styles --------------------------------------------------- */
+
+a.headerlink {
+ visibility: hidden;
+}
+
+h1:hover > a.headerlink,
+h2:hover > a.headerlink,
+h3:hover > a.headerlink,
+h4:hover > a.headerlink,
+h5:hover > a.headerlink,
+h6:hover > a.headerlink,
+dt:hover > a.headerlink {
+ visibility: visible;
+}
+
+div.body p.caption {
+ text-align: inherit;
+}
+
+div.body td {
+ text-align: left;
+}
+
+.field-list ul {
+ padding-left: 1em;
+}
+
+.first {
+ margin-top: 0 !important;
+}
+
+p.rubric {
+ margin-top: 30px;
+ font-weight: bold;
+}
+
+img.align-left, .figure.align-left, object.align-left {
+ clear: left;
+ float: left;
+ margin-right: 1em;
+}
+
+img.align-right, .figure.align-right, object.align-right {
+ clear: right;
+ float: right;
+ margin-left: 1em;
+}
+
+img.align-center, .figure.align-center, object.align-center {
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+.align-left {
+ text-align: left;
+}
+
+.align-center {
+ clear: both;
+ text-align: center;
+}
+
+.align-right {
+ text-align: right;
+}
+
+/* -- sidebars -------------------------------------------------------------- */
+
+div.sidebar {
+ margin: 0 0 0.5em 1em;
+ border: 1px solid #ddb;
+ padding: 7px 7px 0 7px;
+ background-color: #ffe;
+ width: 40%;
+ float: right;
+}
+
+p.sidebar-title {
+ font-weight: bold;
+}
+
+/* -- topics ---------------------------------------------------------------- */
+
+div.topic {
+ border: 1px solid #ccc;
+ padding: 7px 7px 0 7px;
+ margin: 10px 0 10px 0;
+}
+
+p.topic-title {
+ font-size: 1.1em;
+ font-weight: bold;
+ margin-top: 10px;
+}
+
+/* -- admonitions ----------------------------------------------------------- */
+
+div.admonition {
+ margin-top: 10px;
+ margin-bottom: 10px;
+ padding: 7px;
+}
+
+div.admonition dt {
+ font-weight: bold;
+}
+
+div.admonition dl {
+ margin-bottom: 0;
+}
+
+p.admonition-title {
+ margin: 0px 10px 5px 0px;
+ font-weight: bold;
+}
+
+div.body p.centered {
+ text-align: center;
+ margin-top: 25px;
+}
+
+/* -- tables ---------------------------------------------------------------- */
+
+table.docutils {
+ border: 0;
+ border-collapse: collapse;
+}
+
+table.docutils td, table.docutils th {
+ padding: 1px 8px 1px 5px;
+ border-top: 0;
+ border-left: 0;
+ border-right: 0;
+ border-bottom: 1px solid #aaa;
+}
+
+table.field-list td, table.field-list th {
+ border: 0 !important;
+}
+
+table.footnote td, table.footnote th {
+ border: 0 !important;
+}
+
+th {
+ text-align: left;
+ padding-right: 5px;
+}
+
+table.citation {
+ border-left: solid 1px gray;
+ margin-left: 1px;
+}
+
+table.citation td {
+ border-bottom: none;
+}
+
+/* -- other body styles ----------------------------------------------------- */
+
+ol.arabic {
+ list-style: decimal;
+}
+
+ol.loweralpha {
+ list-style: lower-alpha;
+}
+
+ol.upperalpha {
+ list-style: upper-alpha;
+}
+
+ol.lowerroman {
+ list-style: lower-roman;
+}
+
+ol.upperroman {
+ list-style: upper-roman;
+}
+
+dl {
+ margin-bottom: 15px;
+}
+
+dd p {
+ margin-top: 0px;
+}
+
+dd ul, dd table {
+ margin-bottom: 10px;
+}
+
+dd {
+ margin-top: 3px;
+ margin-bottom: 10px;
+ margin-left: 30px;
+}
+
+dt:target, .highlighted {
+ background-color: #fbe54e;
+}
+
+dl.glossary dt {
+ font-weight: bold;
+ font-size: 1.1em;
+}
+
+.field-list ul {
+ margin: 0;
+ padding-left: 1em;
+}
+
+.field-list p {
+ margin: 0;
+}
+
+.refcount {
+ color: #060;
+}
+
+.optional {
+ font-size: 1.3em;
+}
+
+.versionmodified {
+ font-style: italic;
+}
+
+.system-message {
+ background-color: #fda;
+ padding: 5px;
+ border: 3px solid red;
+}
+
+.footnote:target {
+ background-color: #ffa
+}
+
+.line-block {
+ display: block;
+ margin-top: 1em;
+ margin-bottom: 1em;
+}
+
+.line-block .line-block {
+ margin-top: 0;
+ margin-bottom: 0;
+ margin-left: 1.5em;
+}
+
+.guilabel, .menuselection {
+ font-family: sans-serif;
+}
+
+.accelerator {
+ text-decoration: underline;
+}
+
+.classifier {
+ font-style: oblique;
+}
+
+/* -- code displays --------------------------------------------------------- */
+
+pre {
+ overflow: auto;
+}
+
+td.linenos pre {
+ padding: 5px 0px;
+ border: 0;
+ background-color: transparent;
+ color: #aaa;
+}
+
+table.highlighttable {
+ margin-left: 0.5em;
+}
+
+table.highlighttable td {
+ padding: 0 0.5em 0 0.5em;
+}
+
+tt.descname {
+ background-color: transparent;
+ font-weight: bold;
+ font-size: 1.2em;
+}
+
+tt.descclassname {
+ background-color: transparent;
+}
+
+tt.xref, a tt {
+ background-color: transparent;
+ font-weight: bold;
+}
+
+h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
+ background-color: transparent;
+}
+
+.viewcode-link {
+ float: right;
+}
+
+.viewcode-back {
+ float: right;
+ font-family: sans-serif;
+}
+
+div.viewcode-block:target {
+ margin: -1px -10px;
+ padding: 0 10px;
+}
+
+/* -- math display ---------------------------------------------------------- */
+
+img.math {
+ vertical-align: middle;
+}
+
+div.body div.math p {
+ text-align: center;
+}
+
+span.eqno {
+ float: right;
+}
+
+/* -- printout stylesheet --------------------------------------------------- */
+
+@media print {
+ div.document,
+ div.documentwrapper,
+ div.bodywrapper {
+ margin: 0 !important;
+ width: 100%;
+ }
+
+ div.sphinxsidebar,
+ div.related,
+ div.footer,
+ #top-link {
+ display: none;
+ }
+}
diff --git a/css/extlink.gif b/css/extlink.gif
new file mode 100644
index 0000000000000000000000000000000000000000..d47e14ca58d68e5b3f66f6a21b3ea7211636c289
GIT binary patch
literal 90
zc${sIv-Z;U{r{1G;!hSv1_l-e9R?r(sbyf6w-C~C
iW^qtb;}P&^T6
+order allow,deny
+Deny from all
+
+
+
+order allow,deny
+Deny from all
+
+
+
+order allow,deny
+Deny from all
+
+
+
+order allow,deny
+Deny from all
+
+
+
+order allow,deny
+Deny from all
+
diff --git a/doc/COPYING b/doc/COPYING
new file mode 100644
--- /dev/null
+++ b/doc/COPYING
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+
+ Copyright (C)
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ Copyright (C)
+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+.
+
+ The GNU General Public License does not permit incorporating your program
+into proprietary programs. If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License. But first, please read
+.
diff --git a/doc/GFDL.txt b/doc/GFDL.txt
new file mode 100644
--- /dev/null
+++ b/doc/GFDL.txt
@@ -0,0 +1,450 @@
+ GNU Free Documentation License
+ Version 1.3, 3 November 2008
+
+
+ Copyright (C) 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
+
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+0. PREAMBLE
+
+The purpose of this License is to make a manual, textbook, or other
+functional and useful document "free" in the sense of freedom: to
+assure everyone the effective freedom to copy and redistribute it,
+with or without modifying it, either commercially or noncommercially.
+Secondarily, this License preserves for the author and publisher a way
+to get credit for their work, while not being considered responsible
+for modifications made by others.
+
+This License is a kind of "copyleft", which means that derivative
+works of the document must themselves be free in the same sense. It
+complements the GNU General Public License, which is a copyleft
+license designed for free software.
+
+We have designed this License in order to use it for manuals for free
+software, because free software needs free documentation: a free
+program should come with manuals providing the same freedoms that the
+software does. But this License is not limited to software manuals;
+it can be used for any textual work, regardless of subject matter or
+whether it is published as a printed book. We recommend this License
+principally for works whose purpose is instruction or reference.
+
+
+1. APPLICABILITY AND DEFINITIONS
+
+This License applies to any manual or other work, in any medium, that
+contains a notice placed by the copyright holder saying it can be
+distributed under the terms of this License. Such a notice grants a
+world-wide, royalty-free license, unlimited in duration, to use that
+work under the conditions stated herein. The "Document", below,
+refers to any such manual or work. Any member of the public is a
+licensee, and is addressed as "you". You accept the license if you
+copy, modify or distribute the work in a way requiring permission
+under copyright law.
+
+A "Modified Version" of the Document means any work containing the
+Document or a portion of it, either copied verbatim, or with
+modifications and/or translated into another language.
+
+A "Secondary Section" is a named appendix or a front-matter section of
+the Document that deals exclusively with the relationship of the
+publishers or authors of the Document to the Document's overall
+subject (or to related matters) and contains nothing that could fall
+directly within that overall subject. (Thus, if the Document is in
+part a textbook of mathematics, a Secondary Section may not explain
+any mathematics.) The relationship could be a matter of historical
+connection with the subject or with related matters, or of legal,
+commercial, philosophical, ethical or political position regarding
+them.
+
+The "Invariant Sections" are certain Secondary Sections whose titles
+are designated, as being those of Invariant Sections, in the notice
+that says that the Document is released under this License. If a
+section does not fit the above definition of Secondary then it is not
+allowed to be designated as Invariant. The Document may contain zero
+Invariant Sections. If the Document does not identify any Invariant
+Sections then there are none.
+
+The "Cover Texts" are certain short passages of text that are listed,
+as Front-Cover Texts or Back-Cover Texts, in the notice that says that
+the Document is released under this License. A Front-Cover Text may
+be at most 5 words, and a Back-Cover Text may be at most 25 words.
+
+A "Transparent" copy of the Document means a machine-readable copy,
+represented in a format whose specification is available to the
+general public, that is suitable for revising the document
+straightforwardly with generic text editors or (for images composed of
+pixels) generic paint programs or (for drawings) some widely available
+drawing editor, and that is suitable for input to text formatters or
+for automatic translation to a variety of formats suitable for input
+to text formatters. A copy made in an otherwise Transparent file
+format whose markup, or absence of markup, has been arranged to thwart
+or discourage subsequent modification by readers is not Transparent.
+An image format is not Transparent if used for any substantial amount
+of text. A copy that is not "Transparent" is called "Opaque".
+
+Examples of suitable formats for Transparent copies include plain
+ASCII without markup, Texinfo input format, LaTeX input format, SGML
+or XML using a publicly available DTD, and standard-conforming simple
+HTML, PostScript or PDF designed for human modification. Examples of
+transparent image formats include PNG, XCF and JPG. Opaque formats
+include proprietary formats that can be read and edited only by
+proprietary word processors, SGML or XML for which the DTD and/or
+processing tools are not generally available, and the
+machine-generated HTML, PostScript or PDF produced by some word
+processors for output purposes only.
+
+The "Title Page" means, for a printed book, the title page itself,
+plus such following pages as are needed to hold, legibly, the material
+this License requires to appear in the title page. For works in
+formats which do not have any title page as such, "Title Page" means
+the text near the most prominent appearance of the work's title,
+preceding the beginning of the body of the text.
+
+The "publisher" means any person or entity that distributes copies of
+the Document to the public.
+
+A section "Entitled XYZ" means a named subunit of the Document whose
+title either is precisely XYZ or contains XYZ in parentheses following
+text that translates XYZ in another language. (Here XYZ stands for a
+specific section name mentioned below, such as "Acknowledgements",
+"Dedications", "Endorsements", or "History".) To "Preserve the Title"
+of such a section when you modify the Document means that it remains a
+section "Entitled XYZ" according to this definition.
+
+The Document may include Warranty Disclaimers next to the notice which
+states that this License applies to the Document. These Warranty
+Disclaimers are considered to be included by reference in this
+License, but only as regards disclaiming warranties: any other
+implication that these Warranty Disclaimers may have is void and has
+no effect on the meaning of this License.
+
+2. VERBATIM COPYING
+
+You may copy and distribute the Document in any medium, either
+commercially or noncommercially, provided that this License, the
+copyright notices, and the license notice saying this License applies
+to the Document are reproduced in all copies, and that you add no
+other conditions whatsoever to those of this License. You may not use
+technical measures to obstruct or control the reading or further
+copying of the copies you make or distribute. However, you may accept
+compensation in exchange for copies. If you distribute a large enough
+number of copies you must also follow the conditions in section 3.
+
+You may also lend copies, under the same conditions stated above, and
+you may publicly display copies.
+
+
+3. COPYING IN QUANTITY
+
+If you publish printed copies (or copies in media that commonly have
+printed covers) of the Document, numbering more than 100, and the
+Document's license notice requires Cover Texts, you must enclose the
+copies in covers that carry, clearly and legibly, all these Cover
+Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
+the back cover. Both covers must also clearly and legibly identify
+you as the publisher of these copies. The front cover must present
+the full title with all words of the title equally prominent and
+visible. You may add other material on the covers in addition.
+Copying with changes limited to the covers, as long as they preserve
+the title of the Document and satisfy these conditions, can be treated
+as verbatim copying in other respects.
+
+If the required texts for either cover are too voluminous to fit
+legibly, you should put the first ones listed (as many as fit
+reasonably) on the actual cover, and continue the rest onto adjacent
+pages.
+
+If you publish or distribute Opaque copies of the Document numbering
+more than 100, you must either include a machine-readable Transparent
+copy along with each Opaque copy, or state in or with each Opaque copy
+a computer-network location from which the general network-using
+public has access to download using public-standard network protocols
+a complete Transparent copy of the Document, free of added material.
+If you use the latter option, you must take reasonably prudent steps,
+when you begin distribution of Opaque copies in quantity, to ensure
+that this Transparent copy will remain thus accessible at the stated
+location until at least one year after the last time you distribute an
+Opaque copy (directly or through your agents or retailers) of that
+edition to the public.
+
+It is requested, but not required, that you contact the authors of the
+Document well before redistributing any large number of copies, to
+give them a chance to provide you with an updated version of the
+Document.
+
+
+4. MODIFICATIONS
+
+You may copy and distribute a Modified Version of the Document under
+the conditions of sections 2 and 3 above, provided that you release
+the Modified Version under precisely this License, with the Modified
+Version filling the role of the Document, thus licensing distribution
+and modification of the Modified Version to whoever possesses a copy
+of it. In addition, you must do these things in the Modified Version:
+
+A. Use in the Title Page (and on the covers, if any) a title distinct
+ from that of the Document, and from those of previous versions
+ (which should, if there were any, be listed in the History section
+ of the Document). You may use the same title as a previous version
+ if the original publisher of that version gives permission.
+B. List on the Title Page, as authors, one or more persons or entities
+ responsible for authorship of the modifications in the Modified
+ Version, together with at least five of the principal authors of the
+ Document (all of its principal authors, if it has fewer than five),
+ unless they release you from this requirement.
+C. State on the Title page the name of the publisher of the
+ Modified Version, as the publisher.
+D. Preserve all the copyright notices of the Document.
+E. Add an appropriate copyright notice for your modifications
+ adjacent to the other copyright notices.
+F. Include, immediately after the copyright notices, a license notice
+ giving the public permission to use the Modified Version under the
+ terms of this License, in the form shown in the Addendum below.
+G. Preserve in that license notice the full lists of Invariant Sections
+ and required Cover Texts given in the Document's license notice.
+H. Include an unaltered copy of this License.
+I. Preserve the section Entitled "History", Preserve its Title, and add
+ to it an item stating at least the title, year, new authors, and
+ publisher of the Modified Version as given on the Title Page. If
+ there is no section Entitled "History" in the Document, create one
+ stating the title, year, authors, and publisher of the Document as
+ given on its Title Page, then add an item describing the Modified
+ Version as stated in the previous sentence.
+J. Preserve the network location, if any, given in the Document for
+ public access to a Transparent copy of the Document, and likewise
+ the network locations given in the Document for previous versions
+ it was based on. These may be placed in the "History" section.
+ You may omit a network location for a work that was published at
+ least four years before the Document itself, or if the original
+ publisher of the version it refers to gives permission.
+K. For any section Entitled "Acknowledgements" or "Dedications",
+ Preserve the Title of the section, and preserve in the section all
+ the substance and tone of each of the contributor acknowledgements
+ and/or dedications given therein.
+L. Preserve all the Invariant Sections of the Document,
+ unaltered in their text and in their titles. Section numbers
+ or the equivalent are not considered part of the section titles.
+M. Delete any section Entitled "Endorsements". Such a section
+ may not be included in the Modified Version.
+N. Do not retitle any existing section to be Entitled "Endorsements"
+ or to conflict in title with any Invariant Section.
+O. Preserve any Warranty Disclaimers.
+
+If the Modified Version includes new front-matter sections or
+appendices that qualify as Secondary Sections and contain no material
+copied from the Document, you may at your option designate some or all
+of these sections as invariant. To do this, add their titles to the
+list of Invariant Sections in the Modified Version's license notice.
+These titles must be distinct from any other section titles.
+
+You may add a section Entitled "Endorsements", provided it contains
+nothing but endorsements of your Modified Version by various
+parties--for example, statements of peer review or that the text has
+been approved by an organization as the authoritative definition of a
+standard.
+
+You may add a passage of up to five words as a Front-Cover Text, and a
+passage of up to 25 words as a Back-Cover Text, to the end of the list
+of Cover Texts in the Modified Version. Only one passage of
+Front-Cover Text and one of Back-Cover Text may be added by (or
+through arrangements made by) any one entity. If the Document already
+includes a cover text for the same cover, previously added by you or
+by arrangement made by the same entity you are acting on behalf of,
+you may not add another; but you may replace the old one, on explicit
+permission from the previous publisher that added the old one.
+
+The author(s) and publisher(s) of the Document do not by this License
+give permission to use their names for publicity for or to assert or
+imply endorsement of any Modified Version.
+
+
+5. COMBINING DOCUMENTS
+
+You may combine the Document with other documents released under this
+License, under the terms defined in section 4 above for modified
+versions, provided that you include in the combination all of the
+Invariant Sections of all of the original documents, unmodified, and
+list them all as Invariant Sections of your combined work in its
+license notice, and that you preserve all their Warranty Disclaimers.
+
+The combined work need only contain one copy of this License, and
+multiple identical Invariant Sections may be replaced with a single
+copy. If there are multiple Invariant Sections with the same name but
+different contents, make the title of each such section unique by
+adding at the end of it, in parentheses, the name of the original
+author or publisher of that section if known, or else a unique number.
+Make the same adjustment to the section titles in the list of
+Invariant Sections in the license notice of the combined work.
+
+In the combination, you must combine any sections Entitled "History"
+in the various original documents, forming one section Entitled
+"History"; likewise combine any sections Entitled "Acknowledgements",
+and any sections Entitled "Dedications". You must delete all sections
+Entitled "Endorsements".
+
+
+6. COLLECTIONS OF DOCUMENTS
+
+You may make a collection consisting of the Document and other
+documents released under this License, and replace the individual
+copies of this License in the various documents with a single copy
+that is included in the collection, provided that you follow the rules
+of this License for verbatim copying of each of the documents in all
+other respects.
+
+You may extract a single document from such a collection, and
+distribute it individually under this License, provided you insert a
+copy of this License into the extracted document, and follow this
+License in all other respects regarding verbatim copying of that
+document.
+
+
+7. AGGREGATION WITH INDEPENDENT WORKS
+
+A compilation of the Document or its derivatives with other separate
+and independent documents or works, in or on a volume of a storage or
+distribution medium, is called an "aggregate" if the copyright
+resulting from the compilation is not used to limit the legal rights
+of the compilation's users beyond what the individual works permit.
+When the Document is included in an aggregate, this License does not
+apply to the other works in the aggregate which are not themselves
+derivative works of the Document.
+
+If the Cover Text requirement of section 3 is applicable to these
+copies of the Document, then if the Document is less than one half of
+the entire aggregate, the Document's Cover Texts may be placed on
+covers that bracket the Document within the aggregate, or the
+electronic equivalent of covers if the Document is in electronic form.
+Otherwise they must appear on printed covers that bracket the whole
+aggregate.
+
+
+8. TRANSLATION
+
+Translation is considered a kind of modification, so you may
+distribute translations of the Document under the terms of section 4.
+Replacing Invariant Sections with translations requires special
+permission from their copyright holders, but you may include
+translations of some or all Invariant Sections in addition to the
+original versions of these Invariant Sections. You may include a
+translation of this License, and all the license notices in the
+Document, and any Warranty Disclaimers, provided that you also include
+the original English version of this License and the original versions
+of those notices and disclaimers. In case of a disagreement between
+the translation and the original version of this License or a notice
+or disclaimer, the original version will prevail.
+
+If a section in the Document is Entitled "Acknowledgements",
+"Dedications", or "History", the requirement (section 4) to Preserve
+its Title (section 1) will typically require changing the actual
+title.
+
+
+9. TERMINATION
+
+You may not copy, modify, sublicense, or distribute the Document
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense, or distribute it is void, and
+will automatically terminate your rights under this License.
+
+However, if you cease all violation of this License, then your license
+from a particular copyright holder is reinstated (a) provisionally,
+unless and until the copyright holder explicitly and finally
+terminates your license, and (b) permanently, if the copyright holder
+fails to notify you of the violation by some reasonable means prior to
+60 days after the cessation.
+
+Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, receipt of a copy of some or all of the same material does
+not give you any rights to use it.
+
+
+10. FUTURE REVISIONS OF THIS LICENSE
+
+The Free Software Foundation may publish new, revised versions of the
+GNU Free Documentation License from time to time. Such new versions
+will be similar in spirit to the present version, but may differ in
+detail to address new problems or concerns. See
+http://www.gnu.org/copyleft/.
+
+Each version of the License is given a distinguishing version number.
+If the Document specifies that a particular numbered version of this
+License "or any later version" applies to it, you have the option of
+following the terms and conditions either of that specified version or
+of any later version that has been published (not as a draft) by the
+Free Software Foundation. If the Document does not specify a version
+number of this License, you may choose any version ever published (not
+as a draft) by the Free Software Foundation. If the Document
+specifies that a proxy can decide which future versions of this
+License can be used, that proxy's public statement of acceptance of a
+version permanently authorizes you to choose that version for the
+Document.
+
+11. RELICENSING
+
+"Massive Multiauthor Collaboration Site" (or "MMC Site") means any
+World Wide Web server that publishes copyrightable works and also
+provides prominent facilities for anybody to edit those works. A
+public wiki that anybody can edit is an example of such a server. A
+"Massive Multiauthor Collaboration" (or "MMC") contained in the site
+means any set of copyrightable works thus published on the MMC site.
+
+"CC-BY-SA" means the Creative Commons Attribution-Share Alike 3.0
+license published by Creative Commons Corporation, a not-for-profit
+corporation with a principal place of business in San Francisco,
+California, as well as future copyleft versions of that license
+published by that same organization.
+
+"Incorporate" means to publish or republish a Document, in whole or in
+part, as part of another Document.
+
+An MMC is "eligible for relicensing" if it is licensed under this
+License, and if all works that were first published under this License
+somewhere other than this MMC, and subsequently incorporated in whole or
+in part into the MMC, (1) had no cover texts or invariant sections, and
+(2) were thus incorporated prior to November 1, 2008.
+
+The operator of an MMC Site may republish an MMC contained in the site
+under CC-BY-SA on the same site at any time before August 1, 2009,
+provided the MMC is eligible for relicensing.
+
+
+ADDENDUM: How to use this License for your documents
+
+To use this License in a document you have written, include a copy of
+the License in the document and put the following copyright and
+license notices just after the title page:
+
+ Copyright (c) YEAR YOUR NAME.
+ Permission is granted to copy, distribute and/or modify this document
+ under the terms of the GNU Free Documentation License, Version 1.3
+ or any later version published by the Free Software Foundation;
+ with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
+ A copy of the license is included in the section entitled "GNU
+ Free Documentation License".
+
+If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
+replace the "with...Texts." line with this:
+
+ with the Invariant Sections being LIST THEIR TITLES, with the
+ Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
+
+If you have Invariant Sections without Cover Texts, or some other
+combination of the three, merge those two alternatives to suit the
+situation.
+
+If your document contains nontrivial examples of program code, we
+recommend releasing these examples in parallel under your choice of
+free software license, such as the GNU General Public License,
+to permit their use in free software.
diff --git a/doc/Makefile b/doc/Makefile
new file mode 100644
--- /dev/null
+++ b/doc/Makefile
@@ -0,0 +1,97 @@
+# -*- makefile -*-
+
+top_srcdir = ..
+srcdir = .
+
+base_dir=$(shell pwd)
+
+INPUTS =
+TXTS =
+HTML_TXTS =
+EXTRA_DIST =
+CLEANFILES =
+
+TXTS += README.txt
+TXTS += README-de.txt
+HTML_TXTS += README-GFDL.txt
+HTML_TXTS += README-COPYING.txt
+
+# use cp for Windows
+LN_S = cp
+LN_S = ln -s
+
+TXT_PDFS = $(patsubst %.txt,%.pdf,$(TXTS))
+TXT_HTMLS = $(patsubst %.txt,%.html,$(TXTS)) $(patsubst %.txt,%.html,$(HTML_TXTS))
+CLEANFILES += $(TXT_PDFS)
+CLEANFILES += $(TXT_HTMLS)
+
+SNIPPETS = ../lib/snippets.pl
+
+DISTFILES =
+DISTFILES += Makefile
+DISTFILES += $(TXTS)
+DISTFILES += $(TXT_PDFS)
+DISTFILES += $(TXT_HTMLS)
+DISTFILES += $(EXTRA_DIST)
+
+%: %.in
+ cat $< | $(SNIPPETS) --process --replace --mode text --key base_dir --value $(base_dir) --cat - >$@
+ test -s $@ || ( rm -f $@ && test 1 = 0 )
+
+%.html: %.txt
+ cat $< | PYTHONPATH="$$( pwd )" tools/ws_rst2html.py --traceback --cloak-email-addresses >$@
+ test -s $@ || (rm -f $@ && exit 1)
+
+%.pdf: %.txt
+ cat $< | PYTHONPATH="$$( pwd )" tools/ws_rst2pdf -e ws_docutils.raw_role >$@
+ test -s $@ || (rm -f $@ && exit 1)
+
+default: all
+
+all: $(DISTFILES) all-local
+
+all-local:
+
+clean: clean-local
+ test -z '$(CLEANFILES)' || rm -rf $(CLEANFILES)
+
+clean-local:
+ find . -name '*.pyc' | xargs -r rm
+
+install: all
+
+dist:
+
+tags-rc:
+ gen_tags.sh --template
+tags:
+ gen_tags.sh --force
+
+README.txt: ../README.txt
+ rm -f $@
+ $(LN_S) ../$@ $@
+
+# |:here:|
+# :ide-menu: Emacs IDE Main Menu - Buffer @BUFFER@
+# . M-x `eIDE-menu' ()(eIDE-menu "z")
+
+# :ide: COMPILE: tags
+# . (let ((args "tags")) (compile (concat "make -k " args)))
+
+# :ide: COMPILE: dist
+# . (let ((args "dist")) (compile (concat "make -k " args)))
+
+# :ide: COMPILE: install
+# . (let ((args "install")) (compile (concat "make -k " args)))
+
+# :ide: COMPILE: clean
+# . (let ((args "clean")) (compile (concat "make -k " args)))
+
+# :ide: COMPILE: Standard
+# . (let ((args "")) (compile (concat "make -k " args)))
+#
+# Local Variables:
+# mode: makefile
+# snip-mode: makefile-gmake
+# truncate-lines: t
+# End:
diff --git a/doc/README-COPYING.txt b/doc/README-COPYING.txt
new file mode 100644
--- /dev/null
+++ b/doc/README-COPYING.txt
@@ -0,0 +1,117 @@
+.. -*- coding: utf-8 -*-
+.. \||<-snip->|| start
+.. Copyright (C) 2012, Wolfgang Scherer,
+.. Sponsored by WIEDENMANN SEILE GMBH, http://www.wiedenmannseile.de
+..
+.. This file is part of Wiedenmann Vacation.
+..
+.. Permission is granted to copy, distribute and/or modify this document
+.. under the terms of the GNU Free Documentation License, Version 1.3
+.. or any later version published by the Free Software Foundation;
+.. with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
+.. A copy of the license is included in the main documentation of Wiedenmann Vacation.
+
+.. inline comments (with ws_docutils)
+.. role:: rem(span)
+ :format: ''
+.. role:: html(span)
+ :format: html
+ :raw:
+
+.. \||<-snap->|| include ^index-header.snip$
+
+.. Include the GNU General Public License verbatim
+.. include:: COPYING
+ :literal:
+
+.. \||<-snap->|| include ^index-footer.snip$
+.. \||<-snip->|| stop
+
+.. ==================================================
+.. :rem:`|||:sec:|||`\ END
+.. ==================================================
+..
+.. :ide-menu: Emacs IDE Main Menu - Buffer @BUFFER@
+.. . M-x `eIDE-menu' ()(eIDE-menu "z")
+
+.. :ide: DELIM: SNIPPETS (ABOUT) |q|<- SYM ->||, ||<- SYM ->||, @| SYM @
+.. . (let nil (symbol-tag-normalize-delimiter (cons (cons nil "||<-") (cons "->||" nil)) t) (symbol-tag-switch-delimiter-sets) (symbol-tag-normalize-delimiter (cons (cons nil "||<-") (cons "->||" nil)) t) (setq symbol-tag-match-rx "sn[i]p") (setq symbol-tag-enclose-delimiter-set (symbol-tag-normalize-delimiter (cons (cons nil "@|") (cons "@" nil)))))
+
+.. :ide: DELIM: SNIPPETS (DOC) ||<- SYM ->||, |: SYM :|, ` SYM `
+.. . (let nil (symbol-tag-normalize-delimiter (cons (cons nil "|:") (cons ":|" nil)) t) (symbol-tag-switch-delimiter-sets) (symbol-tag-normalize-delimiter (cons (cons nil "||<-") (cons "->||" nil)) t) (setq symbol-tag-match-rx "sn[i]p") (setq symbol-tag-enclose-delimiter-set (symbol-tag-normalize-delimiter (cons (cons "\\(\\`\\|[^\\]\\)" "`") (cons "`" nil)))))
+
+.. :ide: DELIM: SNIPPETS (SNIP DOC) ||<- SYM ->||, |: SYM :|, @ SYM @
+.. . (let nil (symbol-tag-normalize-delimiter (cons (cons nil "|:") (cons ":|" nil)) t) (symbol-tag-switch-delimiter-sets) (symbol-tag-normalize-delimiter (cons (cons nil "||<-") (cons "->||" nil)) t) (setq symbol-tag-match-rx "sn[i]p") (setq symbol-tag-enclose-delimiter-set (symbol-tag-normalize-delimiter (cons (cons nil "@") (cons "@" nil)))))
+
+.. :ide: DELIM: SNIPPETS (FILLME) ||<- SYM ->||, :: SYM ::, @ SYM @
+.. . (let nil (symbol-tag-normalize-delimiter (cons (cons nil "::") (cons "::" nil)) t) (symbol-tag-switch-delimiter-sets) (symbol-tag-normalize-delimiter (cons (cons nil "||<-") (cons "->||" nil)) t) (setq symbol-tag-match-rx "sn[i]p") (setq symbol-tag-enclose-delimiter-set (symbol-tag-normalize-delimiter (cons (cons nil "@") (cons "@" nil)))))
+
+.. :ide: DELIM: SNIPPETS (SUBST) ||<- SYM ->||, @ SYM @, @ SYM @
+.. . (let nil (symbol-tag-normalize-delimiter (cons (cons nil "@") (cons "@" nil)) t) (symbol-tag-switch-delimiter-sets) (symbol-tag-normalize-delimiter (cons (cons nil "||<-") (cons "->||" nil)) t) (setq symbol-tag-match-rx "sn[i]p") (setq symbol-tag-enclose-delimiter-set (symbol-tag-normalize-delimiter (cons (cons "[^\\]" "`") (cons "`" nil)))))
+
+.. :ide: +#-
+.. . Snippet Delimiter Sets ()
+
+.. :ide: DELIM: ReST (links) ` SYM `_, .. _` SYM `, ` SYM `
+.. . (let nil (symbol-tag-normalize-delimiter (cons (cons "[^\\]" "`") (cons "`_" nil)) t) (symbol-tag-switch-delimiter-sets) (symbol-tag-normalize-delimiter (cons (cons nil ".. _`") (cons "`:" nil)) t) (setq symbol-tag-enclose-delimiter-set (symbol-tag-normalize-delimiter (cons (cons "\\(\\`\\|[^\\]\\)" "`") (cons "`" nil)))))
+
+.. :ide: DELIM: STANDARD (GNU quoting) |: SYM :|, :: SYM ::, ` SYM '
+.. . (let nil (symbol-tag-normalize-delimiter (cons (cons nil "::") (cons "::" nil)) t) (symbol-tag-switch-delimiter-sets) (symbol-tag-normalize-delimiter (cons (cons nil "|:") (cons ":|" nil)) t) (setq symbol-tag-enclose-delimiter-set (symbol-tag-normalize-delimiter (cons (cons nil "`") (cons "'" nil)))))
+
+.. :ide: DELIM: STANDARD (ReST quoting) |: SYM :|, :: SYM ::, ` SYM `
+.. . (let nil (symbol-tag-normalize-delimiter (cons (cons nil "::") (cons "::" nil)) t) (symbol-tag-switch-delimiter-sets) (symbol-tag-normalize-delimiter (cons (cons nil "|:") (cons ":|" nil)) t) (setq symbol-tag-enclose-delimiter-set (symbol-tag-normalize-delimiter (cons (cons "[^\\]" "`") (cons "`" nil)))))
+
+.. :ide: +#-
+.. . Delimiter Sets ()
+
+.. :ide: COMPILE: render reST as LaTeX
+.. . (let* ((fp (buffer-file-name)) (fn (file-name-nondirectory fp))) (save-match-data (if (string-match-t "[.][^.]*$" fn) (setq fn (replace-match "" nil t fn)))) (let ((args (concat " " fp " | ws_rst2latex.py --traceback | tee " fn ".tex"))) (save-buffer) (compile (concat "PATH=\".:$PATH\"; cat " args))))
+
+.. :ide: COMPILE: render reST as MAN
+.. . (let* ((fp (buffer-file-name)) (fn (file-name-nondirectory fp))) (save-match-data (if (string-match-t "[.][^.]*$" fn) (setq fn (replace-match "" nil t fn)))) (let ((args (concat " " fp " | ws_rst2man.py --traceback "))) (save-buffer) (compile (concat "PATH=\".:$PATH\"; cat " args))))
+
+.. :ide: COMPILE: render reST as TXT (via MAN)
+.. . (let* ((fp (buffer-file-name)) (fn (file-name-nondirectory fp))) (save-match-data (if (string-match-t "[.][^.]*$" fn) (setq fn (replace-match "" nil t fn)))) (let ((args (concat " " fp " | ws_rst2man.py --traceback | man -l -"))) (save-buffer) (compile (concat "PATH=\".:$PATH\"; cat " args))))
+
+.. :ide: COMPILE: render reST as ODT --strip-comments
+.. . (let* ((fp (buffer-file-name)) (fn (file-name-nondirectory fp))) (save-match-data (if (string-match-t "[.][^.]*$" fn) (setq fn (replace-match "" nil t fn)))) (let ((args (concat " " fp " | ws_rst2odt.py --traceback --strip-comments | cat >" fn ".odt "))) (save-buffer) (compile (concat "PATH=\".:$PATH\"; cat " args))))
+
+.. :ide: COMPILE: render reST as LaTeX, compile PDF and view with gv
+.. . (let* ((fp (buffer-file-name)) (fn (file-name-nondirectory fp))) (save-match-data (if (string-match-t "[.][^.]*$" fn) (setq fn (replace-match "" nil t fn)))) (let ((args (concat " " fp " | ws_rst2latex.py --traceback | tee " fn ".tex && pdflatex '\\nonstopmode\\input " fn ".tex' && gv " fn ".pdf"))) (save-buffer) (compile (concat "PATH=\".:$PATH\"; cat " args))))
+
+.. :ide: COMPILE: render reST as PDF
+.. . (let* ((fp (buffer-file-name)) (fn (file-name-nondirectory fp))) (save-match-data (if (string-match-t "[.][^.]*$" fn) (setq fn (replace-match "" nil t fn)))) (let ((args (concat " " fp " | ws_rst2pdf -e ws_docutils.raw_role >" fn ".pdf"))) (save-buffer) (compile (concat "PATH=\".:$PATH\"; cat " args))))
+
+.. :ide: COMPILE: render reST as HTML
+.. . (let* ((fp (buffer-file-name)) (fn (file-name-nondirectory fp))) (save-match-data (if (string-match-t "[.][^.]*$" fn) (setq fn (replace-match "" nil t fn)))) (let ((args (concat " " fp " | ws_rst2html.py --traceback --cloak-email-addresses | tee " fn ".html "))) (save-buffer) (compile (concat "PATH=\".:$PATH\"; cat " args))))
+
+.. :ide: COMPILE: render reST as pseudoXML
+.. . (let* ((fp (buffer-file-name)) (fn (file-name-nondirectory fp))) (save-match-data (if (string-match-t "[.][^.]*$" fn) (setq fn (replace-match "" nil t fn)))) (let ((args (concat " --traceback " fp " 2>&1 #| tee " fn ".pxml"))) (save-buffer) (compile (concat "PATH=\".:$PATH\"; ws_rst2pseudoxml.py " args))))
+
+.. :ide: +#-
+.. . Process ()
+
+.. :ide: QUO: ~~ Subsubsection ~~
+.. . (insert "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\:rem\:`|\:sec\:|`\\ ::fillme\::\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" )
+
+.. :ide: QUO: -- Subsection --
+.. . (insert "--------------------------------------------------\n\:rem\:`||\:sec\:||`\\ ::fillme\::\n--------------------------------------------------\n" )
+
+.. :ide: QUO: == Section ==
+.. . (insert "==================================================\n\:rem\:`|||\:sec\:|||`\\ ::fillme\::\n==================================================\n" )
+
+.. :ide: +#-
+.. . Sections ()
+
+.. :ide: MENU-OUTLINE: `|||:section:|||' (default)
+.. . (x-eIDE-menu-outline "sec" '("|:" ":|") (cons (cons "^" ".. ") (cons nil nil)) "\\(_`[^`\n]+`\\|\\[[^]\n]+\\]\\|[|][^|\n]+[|]\\|[^:\n]+::\\)")
+
+..
+.. Local Variables:
+.. mode: rst
+.. snip-mode: rst
+.. truncate-lines: t
+.. symbol-tag-symbol-regexp: "[-0-9A-Za-z_#]\\([-0-9A-Za-z_. ]*[-0-9A-Za-z_]\\|\\)"
+.. symbol-tag-auto-comment-mode: nil
+.. symbol-tag-srx-is-safe-with-nil-delimiters: nil
+.. End:
diff --git a/doc/README-GFDL.txt b/doc/README-GFDL.txt
new file mode 100644
--- /dev/null
+++ b/doc/README-GFDL.txt
@@ -0,0 +1,117 @@
+.. -*- coding: utf-8 -*-
+.. \||<-snip->|| start
+.. Copyright (C) 2012, Wolfgang Scherer,
+.. Sponsored by WIEDENMANN SEILE GMBH, http://www.wiedenmannseile.de
+..
+.. This file is part of Wiedenmann Vacation.
+..
+.. Permission is granted to copy, distribute and/or modify this document
+.. under the terms of the GNU Free Documentation License, Version 1.3
+.. or any later version published by the Free Software Foundation;
+.. with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
+.. A copy of the license is included in the main documentation of Wiedenmann Vacation.
+
+.. inline comments (with ws_docutils)
+.. role:: rem(span)
+ :format: ''
+.. role:: html(span)
+ :format: html
+ :raw:
+
+.. \||<-snap->|| include ^index-header.snip$
+
+.. Include the GNU Free Documentation License verbatim
+.. include:: GFDL.txt
+ :literal:
+
+.. \||<-snap->|| include ^index-footer.snip$
+.. \||<-snip->|| stop
+
+.. ==================================================
+.. :rem:`|||:sec:|||`\ END
+.. ==================================================
+..
+.. :ide-menu: Emacs IDE Main Menu - Buffer @BUFFER@
+.. . M-x `eIDE-menu' ()(eIDE-menu "z")
+
+.. :ide: DELIM: SNIPPETS (ABOUT) |q|<- SYM ->||, ||<- SYM ->||, @| SYM @
+.. . (let nil (symbol-tag-normalize-delimiter (cons (cons nil "||<-") (cons "->||" nil)) t) (symbol-tag-switch-delimiter-sets) (symbol-tag-normalize-delimiter (cons (cons nil "||<-") (cons "->||" nil)) t) (setq symbol-tag-match-rx "sn[i]p") (setq symbol-tag-enclose-delimiter-set (symbol-tag-normalize-delimiter (cons (cons nil "@|") (cons "@" nil)))))
+
+.. :ide: DELIM: SNIPPETS (DOC) ||<- SYM ->||, |: SYM :|, ` SYM `
+.. . (let nil (symbol-tag-normalize-delimiter (cons (cons nil "|:") (cons ":|" nil)) t) (symbol-tag-switch-delimiter-sets) (symbol-tag-normalize-delimiter (cons (cons nil "||<-") (cons "->||" nil)) t) (setq symbol-tag-match-rx "sn[i]p") (setq symbol-tag-enclose-delimiter-set (symbol-tag-normalize-delimiter (cons (cons "\\(\\`\\|[^\\]\\)" "`") (cons "`" nil)))))
+
+.. :ide: DELIM: SNIPPETS (SNIP DOC) ||<- SYM ->||, |: SYM :|, @ SYM @
+.. . (let nil (symbol-tag-normalize-delimiter (cons (cons nil "|:") (cons ":|" nil)) t) (symbol-tag-switch-delimiter-sets) (symbol-tag-normalize-delimiter (cons (cons nil "||<-") (cons "->||" nil)) t) (setq symbol-tag-match-rx "sn[i]p") (setq symbol-tag-enclose-delimiter-set (symbol-tag-normalize-delimiter (cons (cons nil "@") (cons "@" nil)))))
+
+.. :ide: DELIM: SNIPPETS (FILLME) ||<- SYM ->||, :: SYM ::, @ SYM @
+.. . (let nil (symbol-tag-normalize-delimiter (cons (cons nil "::") (cons "::" nil)) t) (symbol-tag-switch-delimiter-sets) (symbol-tag-normalize-delimiter (cons (cons nil "||<-") (cons "->||" nil)) t) (setq symbol-tag-match-rx "sn[i]p") (setq symbol-tag-enclose-delimiter-set (symbol-tag-normalize-delimiter (cons (cons nil "@") (cons "@" nil)))))
+
+.. :ide: DELIM: SNIPPETS (SUBST) ||<- SYM ->||, @ SYM @, @ SYM @
+.. . (let nil (symbol-tag-normalize-delimiter (cons (cons nil "@") (cons "@" nil)) t) (symbol-tag-switch-delimiter-sets) (symbol-tag-normalize-delimiter (cons (cons nil "||<-") (cons "->||" nil)) t) (setq symbol-tag-match-rx "sn[i]p") (setq symbol-tag-enclose-delimiter-set (symbol-tag-normalize-delimiter (cons (cons "[^\\]" "`") (cons "`" nil)))))
+
+.. :ide: +#-
+.. . Snippet Delimiter Sets ()
+
+.. :ide: DELIM: ReST (links) ` SYM `_, .. _` SYM `, ` SYM `
+.. . (let nil (symbol-tag-normalize-delimiter (cons (cons "[^\\]" "`") (cons "`_" nil)) t) (symbol-tag-switch-delimiter-sets) (symbol-tag-normalize-delimiter (cons (cons nil ".. _`") (cons "`:" nil)) t) (setq symbol-tag-enclose-delimiter-set (symbol-tag-normalize-delimiter (cons (cons "\\(\\`\\|[^\\]\\)" "`") (cons "`" nil)))))
+
+.. :ide: DELIM: STANDARD (GNU quoting) |: SYM :|, :: SYM ::, ` SYM '
+.. . (let nil (symbol-tag-normalize-delimiter (cons (cons nil "::") (cons "::" nil)) t) (symbol-tag-switch-delimiter-sets) (symbol-tag-normalize-delimiter (cons (cons nil "|:") (cons ":|" nil)) t) (setq symbol-tag-enclose-delimiter-set (symbol-tag-normalize-delimiter (cons (cons nil "`") (cons "'" nil)))))
+
+.. :ide: DELIM: STANDARD (ReST quoting) |: SYM :|, :: SYM ::, ` SYM `
+.. . (let nil (symbol-tag-normalize-delimiter (cons (cons nil "::") (cons "::" nil)) t) (symbol-tag-switch-delimiter-sets) (symbol-tag-normalize-delimiter (cons (cons nil "|:") (cons ":|" nil)) t) (setq symbol-tag-enclose-delimiter-set (symbol-tag-normalize-delimiter (cons (cons "[^\\]" "`") (cons "`" nil)))))
+
+.. :ide: +#-
+.. . Delimiter Sets ()
+
+.. :ide: COMPILE: render reST as LaTeX
+.. . (let* ((fp (buffer-file-name)) (fn (file-name-nondirectory fp))) (save-match-data (if (string-match-t "[.][^.]*$" fn) (setq fn (replace-match "" nil t fn)))) (let ((args (concat " " fp " | ws_rst2latex.py --traceback | tee " fn ".tex"))) (save-buffer) (compile (concat "PATH=\".:$PATH\"; cat " args))))
+
+.. :ide: COMPILE: render reST as MAN
+.. . (let* ((fp (buffer-file-name)) (fn (file-name-nondirectory fp))) (save-match-data (if (string-match-t "[.][^.]*$" fn) (setq fn (replace-match "" nil t fn)))) (let ((args (concat " " fp " | ws_rst2man.py --traceback "))) (save-buffer) (compile (concat "PATH=\".:$PATH\"; cat " args))))
+
+.. :ide: COMPILE: render reST as TXT (via MAN)
+.. . (let* ((fp (buffer-file-name)) (fn (file-name-nondirectory fp))) (save-match-data (if (string-match-t "[.][^.]*$" fn) (setq fn (replace-match "" nil t fn)))) (let ((args (concat " " fp " | ws_rst2man.py --traceback | man -l -"))) (save-buffer) (compile (concat "PATH=\".:$PATH\"; cat " args))))
+
+.. :ide: COMPILE: render reST as ODT --strip-comments
+.. . (let* ((fp (buffer-file-name)) (fn (file-name-nondirectory fp))) (save-match-data (if (string-match-t "[.][^.]*$" fn) (setq fn (replace-match "" nil t fn)))) (let ((args (concat " " fp " | ws_rst2odt.py --traceback --strip-comments | cat >" fn ".odt "))) (save-buffer) (compile (concat "PATH=\".:$PATH\"; cat " args))))
+
+.. :ide: COMPILE: render reST as LaTeX, compile PDF and view with gv
+.. . (let* ((fp (buffer-file-name)) (fn (file-name-nondirectory fp))) (save-match-data (if (string-match-t "[.][^.]*$" fn) (setq fn (replace-match "" nil t fn)))) (let ((args (concat " " fp " | ws_rst2latex.py --traceback | tee " fn ".tex && pdflatex '\\nonstopmode\\input " fn ".tex' && gv " fn ".pdf"))) (save-buffer) (compile (concat "PATH=\".:$PATH\"; cat " args))))
+
+.. :ide: COMPILE: render reST as PDF
+.. . (let* ((fp (buffer-file-name)) (fn (file-name-nondirectory fp))) (save-match-data (if (string-match-t "[.][^.]*$" fn) (setq fn (replace-match "" nil t fn)))) (let ((args (concat " " fp " | ws_rst2pdf -e ws_docutils.raw_role >" fn ".pdf"))) (save-buffer) (compile (concat "PATH=\".:$PATH\"; cat " args))))
+
+.. :ide: COMPILE: render reST as HTML
+.. . (let* ((fp (buffer-file-name)) (fn (file-name-nondirectory fp))) (save-match-data (if (string-match-t "[.][^.]*$" fn) (setq fn (replace-match "" nil t fn)))) (let ((args (concat " " fp " | ws_rst2html.py --traceback --cloak-email-addresses | tee " fn ".html "))) (save-buffer) (compile (concat "PATH=\".:$PATH\"; cat " args))))
+
+.. :ide: COMPILE: render reST as pseudoXML
+.. . (let* ((fp (buffer-file-name)) (fn (file-name-nondirectory fp))) (save-match-data (if (string-match-t "[.][^.]*$" fn) (setq fn (replace-match "" nil t fn)))) (let ((args (concat " --traceback " fp " 2>&1 #| tee " fn ".pxml"))) (save-buffer) (compile (concat "PATH=\".:$PATH\"; ws_rst2pseudoxml.py " args))))
+
+.. :ide: +#-
+.. . Process ()
+
+.. :ide: QUO: ~~ Subsubsection ~~
+.. . (insert "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\:rem\:`|\:sec\:|`\\ ::fillme\::\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" )
+
+.. :ide: QUO: -- Subsection --
+.. . (insert "--------------------------------------------------\n\:rem\:`||\:sec\:||`\\ ::fillme\::\n--------------------------------------------------\n" )
+
+.. :ide: QUO: == Section ==
+.. . (insert "==================================================\n\:rem\:`|||\:sec\:|||`\\ ::fillme\::\n==================================================\n" )
+
+.. :ide: +#-
+.. . Sections ()
+
+.. :ide: MENU-OUTLINE: `|||:section:|||' (default)
+.. . (x-eIDE-menu-outline "sec" '("|:" ":|") (cons (cons "^" ".. ") (cons nil nil)) "\\(_`[^`\n]+`\\|\\[[^]\n]+\\]\\|[|][^|\n]+[|]\\|[^:\n]+::\\)")
+
+..
+.. Local Variables:
+.. mode: rst
+.. snip-mode: rst
+.. truncate-lines: t
+.. symbol-tag-symbol-regexp: "[-0-9A-Za-z_#]\\([-0-9A-Za-z_. ]*[-0-9A-Za-z_]\\|\\)"
+.. symbol-tag-auto-comment-mode: nil
+.. symbol-tag-srx-is-safe-with-nil-delimiters: nil
+.. End:
diff --git a/doc/README-de.txt b/doc/README-de.txt
new file mode 100644
--- /dev/null
+++ b/doc/README-de.txt
@@ -0,0 +1,236 @@
+.. -*- coding: utf-8 -*-
+.. \||<-snip->|| start
+.. Copyright (C) 2012, Wolfgang Scherer,
+.. Sponsored by WIEDENMANN SEILE GMBH, http://www.wiedenmannseile.de
+..
+.. This file is part of Wiedenmann Vacation.
+..
+.. Permission is granted to copy, distribute and/or modify this
+.. document under the terms of the GNU Free Documentation License,
+.. Version 1.3 or any later version published by the Free Software
+.. Foundation; with no Invariant Sections, no Front-Cover Texts, and
+.. no Back-Cover Texts. A copy of the license is included in the main
+.. documentation of Wiedenmann Vacation.
+
+.. (progn (forward-line 1)(snip-insert-mode "rst_t.inline-comments" t))
+.. inline comments (with ws_docutils)
+.. role:: rem(span)
+ :format: ''
+.. role:: html(span)
+ :format: html
+ :raw:
+
+.. role:: ihtml(span)
+ :format: html
+.. role:: nhtml(span)
+ :format: !html
+
+##################################################
+:rem:`|||:sec:|||`\ Wiedenmann Vacation
+##################################################
+Web Front-End zur Verwaltung von vacation(1)
+##################################################
+.. \||<-snap->|| skip
+
+:Author: `Wolfgang Scherer`_
+
+.. contents::
+.. \||<-snap->|| skip
+.. \||<-snap->|| include ^index-header.snip$
+
+==================================================
+:rem:`|||:sec:|||`\ Installation
+==================================================
+
+#. Alias `/vacation` in `lib/ws-vacation.conf.in` ändern, falls
+ gewĂźnscht.
+
+#. Folgende Kommandos ausfĂźhren, um die fertigen Dateien zu erzeugen:
+
+ >>> make clean
+ >>> make
+
+ Damit wird das Installationverzeichnis an den notwendigen Stellen
+ eingetragen.
+
+#. Datei `lib/ws-vacation.conf` nach `/etc/apache2/conf.d/` kopieren.
+
+#. Apache server neu laden:
+
+ >>> rcapache2 reload.
+
+#. Damit der WWW-Prozess das vacation(1)-Kommando als beliebiger
+ Benutzer (auĂer `root`) ausfĂźhren kann, muss die Datei
+ `lib/ws-vacation-sudo` in das Verzeichnis `/etc/sudoers.d` kopiert
+ werden (ubuntu):
+
+ >>> cp lib/ws-vacation-sudo /etc/sudoers.d/ws-vacation-sudo
+ >>> chmod 0440 /etc/sudoers.d/ws-vacation-sudo
+
+ oder an die Datei `/etc/sudoers` angehängt werden (SuSE):
+
+ >>> cat lib/ws-vacation-sudo >>/etc/sudoers
+
+==================================================
+:rem:`|||:sec:|||`\ Benutzerverwaltung
+==================================================
+
+FĂźr die Erstellung der Benutzer und PasswĂśrter, im Unterverzeichnis
+`lib` als `root` folgendes ausfĂźhren:
+
+>>> php gen_htpasswd.php
+
+.. note:: Wenn neue Benutzer auf dem System angelegt werden, muss das
+ entsprechend wiederholt werden.
+
+:rem:`abstand`
+
+==================================================
+:rem:`|||:sec:|||`\ Anpassung
+==================================================
+
+In der Datei `lib/config.php` befinden sich neben anderen
+Grundeinstellungen:
+
+* $ALLOWED_USERS: Immer erlaubte Benutzer.
+* $INVALID_USERS: UngĂźltige Benutzer.
+* $ADMIN_USERS: Administratoren.
+
+Die Vorlage fĂźr einen neuen Abwesenheitstext ist in der Datei
+`lib/language.php` zu finden.
+
+HTML Kopf- und FuĂabschnitt sind in der Datei `lib/templates.php`.
+
+.. ==================================================
+.. :rem:`|||:sec:|||`\ Footnotes
+.. ==================================================
+
+:html:``
+
+.. \[#]
+
+.. ==================================================
+.. :rem:`|||:sec:|||`\ References
+.. ==================================================
+
+.. \||<-snap->|| include ^index-footer.snip$
+
+:rem:`|||:sec:|||`\ **Copyright**
+
+Copyright (C) 2012, Wolfgang Scherer, .
+Sponsored by `Wiedenmann-Seile GmbH`_.
+
+.. div::
+ :format: html
+
+ Siehe Abschnitt |GFDL| fĂźr Nutzungsbedingungen der Dokumentation.
+
+ Siehe Abschnitt |GPL| fĂźr Nutzungsbedingungen des Programms.
+
+.. div::
+ :format: !html
+
+ Siehe Abschnitt *GNU Free Documentation License* in der Datei
+ `GFDL.txt` fĂźr Nutzungsbedingungen der Dokumentation.
+
+ Siehe Abschnitt *GNU General Public License* in der Datei `COPYING`
+ fĂźr Nutzungsbedingungen des Programms.
+
+.. |GFDL| replace:: `GNU Free Documentation License`_
+.. |GPL| replace:: `GNU General Public License`_
+
+.. _`GNU Free Documentation License`: README-GFDL.html
+.. _`GNU General Public License`: README-COPYING.html
+.. _`Wiedenmann-Seile GmbH`: http://www.wiedenmannseile.de
+.. _`Wolfgang Scherer`: sw@wiedenmann-seile.de
+
+.. \||<-snip->|| stop
+
+.. ==================================================
+.. :rem:`|||:sec:|||`\ END
+.. ==================================================
+..
+.. :ide-menu: Emacs IDE Main Menu - Buffer @BUFFER@
+.. . M-x `eIDE-menu' ()(eIDE-menu "z")
+
+.. :ide: DELIM: SNIPPETS (ABOUT) |q|<- SYM ->||, ||<- SYM ->||, @| SYM @
+.. . (let nil (symbol-tag-normalize-delimiter (cons (cons nil "||<-") (cons "->||" nil)) t) (symbol-tag-switch-delimiter-sets) (symbol-tag-normalize-delimiter (cons (cons nil "||<-") (cons "->||" nil)) t) (setq symbol-tag-match-rx "sn[i]p") (setq symbol-tag-enclose-delimiter-set (symbol-tag-normalize-delimiter (cons (cons nil "@|") (cons "@" nil)))))
+
+.. :ide: DELIM: SNIPPETS (DOC) ||<- SYM ->||, |: SYM :|, ` SYM `
+.. . (let nil (symbol-tag-normalize-delimiter (cons (cons nil "|:") (cons ":|" nil)) t) (symbol-tag-switch-delimiter-sets) (symbol-tag-normalize-delimiter (cons (cons nil "||<-") (cons "->||" nil)) t) (setq symbol-tag-match-rx "sn[i]p") (setq symbol-tag-enclose-delimiter-set (symbol-tag-normalize-delimiter (cons (cons "\\(\\`\\|[^\\]\\)" "`") (cons "`" nil)))))
+
+.. :ide: DELIM: SNIPPETS (SNIP DOC) ||<- SYM ->||, |: SYM :|, @ SYM @
+.. . (let nil (symbol-tag-normalize-delimiter (cons (cons nil "|:") (cons ":|" nil)) t) (symbol-tag-switch-delimiter-sets) (symbol-tag-normalize-delimiter (cons (cons nil "||<-") (cons "->||" nil)) t) (setq symbol-tag-match-rx "sn[i]p") (setq symbol-tag-enclose-delimiter-set (symbol-tag-normalize-delimiter (cons (cons nil "@") (cons "@" nil)))))
+
+.. :ide: DELIM: SNIPPETS (FILLME) ||<- SYM ->||, :: SYM ::, @ SYM @
+.. . (let nil (symbol-tag-normalize-delimiter (cons (cons nil "::") (cons "::" nil)) t) (symbol-tag-switch-delimiter-sets) (symbol-tag-normalize-delimiter (cons (cons nil "||<-") (cons "->||" nil)) t) (setq symbol-tag-match-rx "sn[i]p") (setq symbol-tag-enclose-delimiter-set (symbol-tag-normalize-delimiter (cons (cons nil "@") (cons "@" nil)))))
+
+.. :ide: DELIM: SNIPPETS (SUBST) ||<- SYM ->||, @ SYM @, @ SYM @
+.. . (let nil (symbol-tag-normalize-delimiter (cons (cons nil "@") (cons "@" nil)) t) (symbol-tag-switch-delimiter-sets) (symbol-tag-normalize-delimiter (cons (cons nil "||<-") (cons "->||" nil)) t) (setq symbol-tag-match-rx "sn[i]p") (setq symbol-tag-enclose-delimiter-set (symbol-tag-normalize-delimiter (cons (cons "[^\\]" "`") (cons "`" nil)))))
+
+.. :ide: +#-
+.. . Snippet Delimiter Sets ()
+
+.. :ide: DELIM: ReST (links) ` SYM `_, .. _` SYM `, ` SYM `
+.. . (let nil (symbol-tag-normalize-delimiter (cons (cons "[^\\]" "`") (cons "`_" nil)) t) (symbol-tag-switch-delimiter-sets) (symbol-tag-normalize-delimiter (cons (cons nil ".. _`") (cons "`:" nil)) t) (setq symbol-tag-enclose-delimiter-set (symbol-tag-normalize-delimiter (cons (cons "\\(\\`\\|[^\\]\\)" "`") (cons "`" nil)))))
+
+.. :ide: DELIM: STANDARD (GNU quoting) |: SYM :|, :: SYM ::, ` SYM '
+.. . (let nil (symbol-tag-normalize-delimiter (cons (cons nil "::") (cons "::" nil)) t) (symbol-tag-switch-delimiter-sets) (symbol-tag-normalize-delimiter (cons (cons nil "|:") (cons ":|" nil)) t) (setq symbol-tag-enclose-delimiter-set (symbol-tag-normalize-delimiter (cons (cons nil "`") (cons "'" nil)))))
+
+.. :ide: DELIM: STANDARD (ReST quoting) |: SYM :|, :: SYM ::, ` SYM `
+.. . (let nil (symbol-tag-normalize-delimiter (cons (cons nil "::") (cons "::" nil)) t) (symbol-tag-switch-delimiter-sets) (symbol-tag-normalize-delimiter (cons (cons nil "|:") (cons ":|" nil)) t) (setq symbol-tag-enclose-delimiter-set (symbol-tag-normalize-delimiter (cons (cons "[^\\]" "`") (cons "`" nil)))))
+
+.. :ide: +#-
+.. . Delimiter Sets ()
+
+.. :ide: COMPILE: render reST as LaTeX
+.. . (let* ((fp (buffer-file-name)) (fn (file-name-nondirectory fp))) (save-match-data (if (string-match-t "[.][^.]*$" fn) (setq fn (replace-match "" nil t fn)))) (let ((args (concat " " fp " | ws_rst2latex.py --traceback | tee " fn ".tex"))) (save-buffer) (compile (concat "PATH=\".:$PATH\"; cat " args))))
+
+.. :ide: COMPILE: render reST as MAN
+.. . (let* ((fp (buffer-file-name)) (fn (file-name-nondirectory fp))) (save-match-data (if (string-match-t "[.][^.]*$" fn) (setq fn (replace-match "" nil t fn)))) (let ((args (concat " " fp " | ws_rst2man.py --traceback "))) (save-buffer) (compile (concat "PATH=\".:$PATH\"; cat " args))))
+
+.. :ide: COMPILE: render reST as TXT (via MAN)
+.. . (let* ((fp (buffer-file-name)) (fn (file-name-nondirectory fp))) (save-match-data (if (string-match-t "[.][^.]*$" fn) (setq fn (replace-match "" nil t fn)))) (let ((args (concat " " fp " | ws_rst2man.py --traceback | man -l -"))) (save-buffer) (compile (concat "PATH=\".:$PATH\"; cat " args))))
+
+.. :ide: COMPILE: render reST as ODT --strip-comments
+.. . (let* ((fp (buffer-file-name)) (fn (file-name-nondirectory fp))) (save-match-data (if (string-match-t "[.][^.]*$" fn) (setq fn (replace-match "" nil t fn)))) (let ((args (concat " " fp " | ws_rst2odt.py --traceback --strip-comments | cat >" fn ".odt "))) (save-buffer) (compile (concat "PATH=\".:$PATH\"; cat " args))))
+
+.. :ide: COMPILE: render reST as LaTeX, compile PDF and view with gv
+.. . (let* ((fp (buffer-file-name)) (fn (file-name-nondirectory fp))) (save-match-data (if (string-match-t "[.][^.]*$" fn) (setq fn (replace-match "" nil t fn)))) (let ((args (concat " " fp " | ws_rst2latex.py --traceback | tee " fn ".tex && pdflatex '\\nonstopmode\\input " fn ".tex' && gv " fn ".pdf"))) (save-buffer) (compile (concat "PATH=\".:$PATH\"; cat " args))))
+
+.. :ide: COMPILE: render reST as PDF
+.. . (let* ((fp (buffer-file-name)) (fn (file-name-nondirectory fp))) (save-match-data (if (string-match-t "[.][^.]*$" fn) (setq fn (replace-match "" nil t fn)))) (let ((args (concat " " fp " | ws_rst2pdf -e ws_docutils.raw_role >" fn ".pdf"))) (save-buffer) (compile (concat "PATH=\".:$PATH\"; cat " args))))
+
+.. :ide: COMPILE: render reST as HTML
+.. . (let* ((fp (buffer-file-name)) (fn (file-name-nondirectory fp))) (save-match-data (if (string-match-t "[.][^.]*$" fn) (setq fn (replace-match "" nil t fn)))) (let ((args (concat " " fp " | ws_rst2html.py --traceback --cloak-email-addresses | tee " fn ".html "))) (save-buffer) (compile (concat "PATH=\".:$PATH\"; cat " args))))
+
+.. :ide: COMPILE: render reST as pseudoXML
+.. . (let* ((fp (buffer-file-name)) (fn (file-name-nondirectory fp))) (save-match-data (if (string-match-t "[.][^.]*$" fn) (setq fn (replace-match "" nil t fn)))) (let ((args (concat " --traceback " fp " 2>&1 #| tee " fn ".pxml"))) (save-buffer) (compile (concat "PATH=\".:$PATH\"; ws_rst2pseudoxml.py " args))))
+
+.. :ide: +#-
+.. . Process ()
+
+.. :ide: QUO: ~~ Subsubsection ~~
+.. . (insert "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\:rem\:`|\:sec\:|`\\ ::fillme\::\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" )
+
+.. :ide: QUO: -- Subsection --
+.. . (insert "--------------------------------------------------\n\:rem\:`||\:sec\:||`\\ ::fillme\::\n--------------------------------------------------\n" )
+
+.. :ide: QUO: == Section ==
+.. . (insert "==================================================\n\:rem\:`|||\:sec\:|||`\\ ::fillme\::\n==================================================\n" )
+
+.. :ide: +#-
+.. . Sections ()
+
+.. :ide: MENU-OUTLINE: `|||:section:|||' (default)
+.. . (x-eIDE-menu-outline "sec" '("|:" ":|") (cons (cons "^" ".. ") (cons nil nil)) "\\(_`[^`\n]+`\\|\\[[^]\n]+\\]\\|[|][^|\n]+[|]\\|[^:\n]+::\\)")
+
+..
+.. Local Variables:
+.. mode: rst
+.. snip-mode: rst
+.. truncate-lines: t
+.. symbol-tag-symbol-regexp: "[-0-9A-Za-z_#]\\([-0-9A-Za-z_. ]*[-0-9A-Za-z_]\\|\\)"
+.. symbol-tag-auto-comment-mode: nil
+.. symbol-tag-srx-is-safe-with-nil-delimiters: nil
+.. End:
diff --git a/doc/README.txt b/doc/README.txt
new file mode 120000
--- /dev/null
+++ b/doc/README.txt
@@ -0,0 +1,1 @@
+../README.txt
\ No newline at end of file
diff --git a/doc/docutils.conf b/doc/docutils.conf
new file mode 100644
--- /dev/null
+++ b/doc/docutils.conf
@@ -0,0 +1,11 @@
+[html4css1 writer]
+# Required for docutils-update, the website build system:
+stylesheet: ../css/basic.css,
+ ../css/pygments.css,
+ ../css/ws-project.css
+#stylesheet: ../doc/blue_box.css
+#stylesheet-path: ./html4css1.css
+embed-stylesheet: no
+#embed-stylesheet: yes
+#field-name-limit: 20
+language_code: de
diff --git a/doc/tools/ws_rst2html.py b/doc/tools/ws_rst2html.py
new file mode 100755
--- /dev/null
+++ b/doc/tools/ws_rst2html.py
@@ -0,0 +1,23 @@
+#!/usr/bin/python
+
+# $Id: rst2html.py 4564 2006-05-21 20:44:42Z wiemann $
+# Author: David Goodger
+# Copyright: This module has been placed in the public domain.
+
+"""
+A minimal front end to the Docutils Publisher, producing HTML.
+"""
+
+try:
+ import locale
+ locale.setlocale(locale.LC_ALL, '')
+except:
+ pass
+
+from docutils.core import publish_cmdline, default_description
+import ws_docutils.span
+
+description = ('Generates (X)HTML documents from standalone reStructuredText '
+ 'sources. ' + default_description)
+
+publish_cmdline(writer_name='html', description=description)
diff --git a/doc/tools/ws_rst2latex.py b/doc/tools/ws_rst2latex.py
new file mode 100755
--- /dev/null
+++ b/doc/tools/ws_rst2latex.py
@@ -0,0 +1,27 @@
+#!/usr/bin/python
+
+# $Id: rst2latex.py 5905 2009-04-16 12:04:49Z milde $
+# Author: David Goodger
+# Copyright: This module has been placed in the public domain.
+
+"""
+A minimal front end to the Docutils Publisher, producing LaTeX.
+"""
+
+try:
+ import locale
+ locale.setlocale(locale.LC_ALL, '')
+except:
+ pass
+
+from docutils.core import publish_cmdline
+import ws_docutils.span
+
+description = ('Generates LaTeX documents from standalone reStructuredText '
+ 'sources. '
+ 'Reads from (default is stdin) and writes to '
+ ' (default is stdout). See '
+ ' for '
+ 'the full reference.')
+
+publish_cmdline(writer_name='latex', description=description)
diff --git a/doc/tools/ws_rst2man.py b/doc/tools/ws_rst2man.py
new file mode 100755
--- /dev/null
+++ b/doc/tools/ws_rst2man.py
@@ -0,0 +1,27 @@
+#!/usr/bin/python
+
+# Author:
+# Contact: grubert@users.sf.net
+# Copyright: This module has been placed in the public domain.
+
+"""
+man.py
+======
+
+This module provides a simple command line interface that uses the
+man page writer to output from ReStructuredText source.
+"""
+
+import locale
+try:
+ locale.setlocale(locale.LC_ALL, '')
+except:
+ pass
+
+from docutils.core import publish_cmdline, default_description
+from docutils.writers import manpage
+import ws_docutils.span
+
+description = ("Generates plain unix manual documents. " + default_description)
+
+publish_cmdline(writer=manpage.Writer(), description=description)
diff --git a/doc/tools/ws_rst2odt.py b/doc/tools/ws_rst2odt.py
new file mode 100755
--- /dev/null
+++ b/doc/tools/ws_rst2odt.py
@@ -0,0 +1,31 @@
+#!/usr/bin/python
+
+# $Id: rst2odt.py 5839 2009-01-07 19:09:28Z dkuhlman $
+# Author: Dave Kuhlman
+# Copyright: This module has been placed in the public domain.
+
+"""
+A front end to the Docutils Publisher, producing OpenOffice documents.
+"""
+
+import sys
+try:
+ import locale
+ locale.setlocale(locale.LC_ALL, '')
+except:
+ pass
+
+from docutils.core import publish_cmdline_to_binary, default_description
+from docutils.writers.odf_odt import Writer, Reader
+import ws_docutils.span
+
+
+description = ('Generates OpenDocument/OpenOffice/ODF documents from '
+ 'standalone reStructuredText sources. ' + default_description)
+
+
+writer = Writer()
+reader = Reader()
+output = publish_cmdline_to_binary(reader=reader, writer=writer,
+ description=description)
+
diff --git a/doc/tools/ws_rst2pdf b/doc/tools/ws_rst2pdf
new file mode 100755
--- /dev/null
+++ b/doc/tools/ws_rst2pdf
@@ -0,0 +1,14 @@
+#!/usr/bin/python
+# EASY-INSTALL-ENTRY-SCRIPT: 'rst2pdf==0.16','console_scripts','rst2pdf'
+__requires__ = 'rst2pdf>=0.16'
+import sys
+from pkg_resources import load_entry_point
+
+import ws_docutils.span
+import docutils
+docutils.nodes.span.output_format = 'pdf'
+
+if __name__ == '__main__':
+ sys.exit(
+ load_entry_point('rst2pdf>=0.16', 'console_scripts', 'rst2pdf')()
+ )
diff --git a/doc/tools/ws_rst2pseudoxml.py b/doc/tools/ws_rst2pseudoxml.py
new file mode 100755
--- /dev/null
+++ b/doc/tools/ws_rst2pseudoxml.py
@@ -0,0 +1,23 @@
+#!/usr/bin/python
+
+# $Id: rst2pseudoxml.py 4564 2006-05-21 20:44:42Z wiemann $
+# Author: David Goodger
+# Copyright: This module has been placed in the public domain.
+
+"""
+A minimal front end to the Docutils Publisher, producing pseudo-XML.
+"""
+
+try:
+ import locale
+ locale.setlocale(locale.LC_ALL, '')
+except:
+ pass
+
+from docutils.core import publish_cmdline, default_description
+import ws_docutils.span
+
+description = ('Generates pseudo-XML from standalone reStructuredText '
+ 'sources (for testing purposes). ' + default_description)
+
+publish_cmdline(description=description)
diff --git a/doc/tools/ws_sh2rst.py b/doc/tools/ws_sh2rst.py
new file mode 100755
--- /dev/null
+++ b/doc/tools/ws_sh2rst.py
@@ -0,0 +1,325 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+# Copyright (C) 2011, Wolfgang Scherer,
+# Sponsored by WIEDENMANN SEILE GMBH, http://www.wiedenmannseile.de
+#
+# This file is part of Wiedenmann Applications.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see ,
+# or write to
+"""\
+sh2rst.py - sh(1) scripts to reStructuredText
+
+usage: sh2rst.py [OPTIONS] []
+
+OPTIONS
+ -t, --test run doctests
+ -v, --verbose verbose test output
+ -h, --help display this help message
+"""
+
+# --------------------------------------------------
+# |||:sec:||| CONFIGURATION
+# --------------------------------------------------
+
+import sys
+import os
+import re
+
+##
+# reStructuredText header.
+rst_header = """\
+.. -*- rst -*-
+.. role:: rem(span)
+ :format: ''
+"""
+
+rst_contents = """
+.. contents::
+"""
+
+rst_contents_before_header = False
+
+# --------------------------------------------------
+# |||:sec:||| CLASSES
+# --------------------------------------------------
+
+# --------------------------------------------------
+# |||:sec:||| FUNCTIONS
+# --------------------------------------------------
+
+def rem( str_, lead_ws = False ): # ||:fnc:||
+ if lead_ws:
+ return ''.join(("\\ :rem:`", str_, "`"))
+ return ''.join((":rem:`", str_, "`\\ "))
+
+def sec(str_ = "|||" ":sec:|||", plain = False): # ||:fnc:||
+ if plain:
+ return str_
+ return rem(str_)
+
+# state variables
+_in_body = False
+_pend_nl = False
+
+def header(title): # ||:fnc:||
+ global rst_header
+ global rst_contents
+ sline = "{0} {1}".format(sec(), title)
+ ouline = "#" * len(sline)
+ ousec = "-" * 50
+ if rst_contents_before_header:
+ first = ''.join((rst_header, rst_contents))
+ second = ""
+ else:
+ first = rst_header
+ second = rst_contents
+
+ hd = "\n".join((
+ first,
+ ouline, sline, ouline,
+ second,
+ ousec, 'SYNOPSIS', ousec,
+ ))
+ rst_header = ""
+ rst_contents = ""
+ return hd
+
+def outline(line=''): # ||:fnc:||
+ global _in_body
+ global _pend_nl
+ if not line:
+ if _in_body:
+ _pend_nl = True
+ return
+ elif not _in_body:
+ print(header(line))
+ _in_body = True
+ _pend_nl = True
+ return
+ if _pend_nl:
+ print('')
+ _pend_nl = False
+ print line
+
+def run(): # ||:fnc:||
+ global _in_body
+ global _pend_nl
+ files = sys.argv[1:]
+ if len(files) > 1:
+ global rst_contents_before_header
+ rst_contents_before_header = True
+ if not files:
+ files = ('-')
+ # handle all files
+ for file_ in files:
+ if file_ == '-':
+ fn = ''
+ fh = sys.stdin
+ do_close = False
+ else:
+ fn = os.path.basename( file_ )
+ fh = open(file_, "rb")
+ do_close = True
+ contents = fh.read()
+ if do_close:
+ fh.close()
+ lines = re.split('[ \t\r]*\n', contents)
+ _in_body = False
+ in_descr = True
+ lineno = 0
+ # handle all lines
+ for line in lines:
+ lineno += 1
+ # stop on \f
+ if line.find('\f') >= 0:
+ break
+ line = line.rstrip()
+ if not line:
+ outline()
+ continue
+ mo = re.match('^# ?(.*)', line)
+
+ # comment line
+ if mo:
+ if not in_descr:
+ outline()
+ in_descr = True
+ line = mo.groups()[ 0 ]
+ if not line:
+ outline()
+ continue
+ # she-bang
+ if line.startswith( '!/' ):
+ continue
+ # emacs definition/python coding
+ if line.startswith( '-*-' ):
+ continue
+ # double comment
+ if line.startswith( '#' ):
+ continue
+ # handle tags
+ first = True
+ pre = []
+ while True:
+ # 1 2 3 4 5
+ mo = re.match('''^([^|]*)(\|+)(:[^:]+:)(\|+)(.*)''',line)
+ if mo:
+ groups = mo.groups()
+ # translate section tags
+ pre_tag = groups[0]
+ post_tag = groups[4]
+ if first:
+ if not pre_tag and not post_tag:
+ line = ''
+ break
+ pre.append(pre_tag)
+ pre.append(sec(''.join((groups[1], groups[2], groups[3]))))
+ post_tag = post_tag.lstrip()
+ first = False
+ else:
+ pre.append(pre_tag)
+ pre.append(''.join(('\\', groups[1], groups[2], groups[3])))
+ line = post_tag
+ else:
+ break
+ pre.append(line)
+ line = ''.join(pre)
+ outline(line)
+
+ # skip special marker line
+ elif line.startswith(': # script help'):
+ continue
+
+ # print code lines as block quote
+ else:
+ if in_descr:
+ outline()
+ outline("::")
+ outline()
+ in_descr = False
+ outline(' {0:03d} {1}'.format(lineno, line))
+
+# --------------------------------------------------
+# |||:sec:||| MAIN
+# --------------------------------------------------
+
+##
+# Verbosity flag.
+_verbose = False
+
+##
+# Debug flag.
+_debug = False
+
+def main( argv ): # ||:fnc:||
+ """Generic main function.
+
+ :return: exit status
+ :param argv: command line arguments (defaults to sys.argv)
+ """
+ import getopt
+ optstr = ""; long_opts = []
+ optstr += "h"; long_opts.append( "help" )
+ global _verbose
+ optstr += "v"; long_opts.append( "verbose" )
+ global _debug
+ optstr += "d"; long_opts.append( "debug" )
+ _opt_test = False
+ optstr += "t"; long_opts.append( "test" )
+ # |:sec:| options
+ try:
+ opts, args = getopt.gnu_getopt( argv[ 1: ], optstr, long_opts )
+ except getopt.GetoptError as err:
+ sys.stderr.write( "".join(( str( err ), "\n" )))
+ sys.stderr.write( __doc__ )
+ sys.exit(1)
+ for opt, arg in opts:
+ if opt in ( "-h", "--help" ):
+ sys.stdout.write( __doc__ )
+ sys.exit()
+ # |:sec:| options
+ elif opt in ( "-v", "--verbose" ):
+ _verbose = True
+ elif opt in ( "-d", "--debug" ):
+ _verbose = True
+ _debug = True
+ elif opt in ( "-t", "--test" ):
+ _opt_test = True
+ else:
+ assert False, "unhandled option"
+ if _opt_test:
+ import doctest
+ doctest.testmod( verbose = _verbose )
+ sys.exit()
+ # |:here:|
+ if _debug:
+ cmd_line = sys.argv
+ sys.stderr.write( "# {1:<{0}s}: [{2!s}]\n".format(
+ dbg_fwid if 'dbg_fwid' in globals() else 15, 'cmd_line',
+ cmd_line ))
+ del( sys.argv[ 1: ])
+ sys.argv.extend( args )
+ run()
+
+if __name__ == "__main__":
+ sys.argv.insert( 1, '--debug' ) # |:debug:|
+ main( sys.argv )
+ sys.exit()
+
+# |:here:|
+#
+# :ide-menu: Emacs IDE Main Menu - Buffer @BUFFER@
+# . M-x `eIDE-menu' (eIDE-menu "z")
+
+# :ide: SNIP: insert PROG-PATH
+# . (snip-insert-mode "py_prog-path" nil t)
+
+# :ide: CSCOPE ON
+# . (cscope-minor-mode)
+
+# :ide: CSCOPE OFF
+# . (cscope-minor-mode (quote ( nil )))
+
+# :ide: COMPILE: Run with --help
+# . (progn (save-buffer) (compile (concat "python ./" (file-name-nondirectory (buffer-file-name)) " --help")))
+
+# :ide: COMPILE: Run with --test
+# . (progn (save-buffer) (compile (concat "python ./" (file-name-nondirectory (buffer-file-name)) " --test")))
+
+# :ide: COMPILE: Run with --test --verbose
+# . (progn (save-buffer) (compile (concat "python ./" (file-name-nondirectory (buffer-file-name)) " --test --verbose")))
+
+# :ide: INFO: Python Documentation
+# . (let ((ref-buffer "*w3m*")) (if (get-buffer ref-buffer) (display-buffer ref-buffer t)) (other-window 1) (w3m-goto-url "http://docs.python.org/index.html" nil nil))
+
+# :ide: INFO: Python Reference
+# . (let ((ref-buffer "*python-ref*")) (if (not (get-buffer ref-buffer)) (shell-command (concat "w3m -dump -cols " (number-to-string (1- (window-width))) " 'http://rgruet.free.fr/PQR26/PQR2.6.html'") ref-buffer) (display-buffer ref-buffer t)))
+
+# :ide: COMPILE: Run w/o args
+# . (progn (save-buffer) (compile (concat "python ./" (file-name-nondirectory (buffer-file-name)) " ")))
+
+# :ide: COMPILE: Run with /usr/local/bin/hg-status-all.sh
+# . (progn (save-buffer) (compile (concat "python ./" (file-name-nondirectory (buffer-file-name)) " /usr/local/bin/hg-status-all.sh | tee hg-status-all.txt; rst2html.py hg-status-all.txt >hg-status-all.html")))
+
+# :ide: COMPILE: Run with /usr/local/bin/hg-status-all.sh + /home/ws/develop/util/gen-tags/gen_etags.sh
+# . (let ((f0 (file-name-nondirectory (buffer-file-name))) (f1 "/usr/local/bin/hg-status-all.sh") (f2 "/home/ws/develop/util/gen-tags/gen_etags.sh") (ob "scripts")) (save-buffer) (compile (concat "python ./" f0 " " f1 " " f2 " | tee " ob ".txt; rst2html.py " ob ".txt >" ob ".html")))
+
+#
+# Local Variables:
+# mode: python
+# comment-start: "#"
+# comment-start-skip: "#+"
+# comment-column: 0
+# End:
diff --git a/doc/ws_docutils/__init__.py b/doc/ws_docutils/__init__.py
new file mode 100644
--- /dev/null
+++ b/doc/ws_docutils/__init__.py
@@ -0,0 +1,68 @@
+# -*- coding: utf-8 -*-
+# Copyright (C) 2011, Wolfgang Scherer,
+# Sponsored by WIEDENMANN SEILE GMBH, http://www.wiedenmannseile.de
+#
+# This file is part of WSRFID.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see ,
+# or write to Wolfgang Scherer, Neue Obernbreiter Str. 5, D-97340
+# Marktbreit or
+"""\
+ws_docutils - extension loader for docutils
+"""
+
+# span role and div directive
+#import ws_docutils.span
+
+# external link icons for trac
+#import ws_docutils.trachtml
+
+# |:here:|
+#
+# :ide-menu: Emacs IDE Main Menu - Buffer @BUFFER@
+# . M-x `eIDE-menu' (eIDE-menu "z")
+
+# :ide: SNIP: insert PROG-PATH
+# . (snip-insert-mode "py_prog-path" nil t)
+
+# :ide: CSCOPE ON
+# . (cscope-minor-mode)
+
+# :ide: CSCOPE OFF
+# . (cscope-minor-mode (quote ( nil )))
+
+# :ide: COMPILE: Run with --help
+# . (progn (save-buffer) (compile (concat "python ./" (file-name-nondirectory (buffer-file-name)) " --help")))
+
+# :ide: COMPILE: Run with --test
+# . (progn (save-buffer) (compile (concat "python ./" (file-name-nondirectory (buffer-file-name)) " --test")))
+
+# :ide: COMPILE: Run with --test --verbose
+# . (progn (save-buffer) (compile (concat "python ./" (file-name-nondirectory (buffer-file-name)) " --test --verbose")))
+
+# :ide: INFO: Python Documentation
+# . (let ((ref-buffer "*w3m*")) (if (get-buffer ref-buffer) (display-buffer ref-buffer t)) (other-window 1) (w3m-goto-url "http://docs.python.org/index.html" nil nil))
+
+# :ide: INFO: Python Reference
+# . (let ((ref-buffer "*python-ref*")) (if (not (get-buffer ref-buffer)) (shell-command (concat "w3m -dump -cols " (number-to-string (1- (window-width))) " 'http://rgruet.free.fr/PQR26/PQR2.6.html'") ref-buffer) (display-buffer ref-buffer t)))
+
+# :ide: COMPILE: Run w/o args
+# . (progn (save-buffer) (compile (concat "python ./" (file-name-nondirectory (buffer-file-name)) " ")))
+#
+# Local Variables:
+# mode: python
+# comment-start: "#"
+# comment-start-skip: "#+"
+# comment-column: 0
+# End:
diff --git a/doc/ws_docutils/raw_role_r2p.py b/doc/ws_docutils/raw_role_r2p.py
new file mode 100644
--- /dev/null
+++ b/doc/ws_docutils/raw_role_r2p.py
@@ -0,0 +1,29 @@
+# -*- coding: utf-8 -*-
+
+#$HeadURL: https://rst2pdf.googlecode.com/svn/tags/0.16/rst2pdf/genpdftext.py $
+#$LastChangedDate: 2010-10-06 17:17:48 -0300 (Wed, 06 Oct 2010) $
+#$LastChangedRevision: 2393 $
+
+# See LICENSE.txt for licensing terms
+
+import os
+from xml.sax.saxutils import escape
+from rst2pdf.log import log, nodeid
+from rst2pdf.basenodehandler import NodeHandler
+import docutils.nodes
+from urlparse import urljoin, urlparse
+from reportlab.lib.units import cm
+from rst2pdf.opt_imports import Paragraph
+
+from rst2pdf.image import MyImage, missing
+import ws_docutils.span
+
+class HandleRaw(NodeHandler, docutils.nodes.raw):
+ def get_text(self, client, node, replaceEnt):
+ text = ''
+ if 'pdf' in node.get('format', '').split():
+ docutils.nodes.raw.output_format = 'pdf'
+ text = node.astext()
+ if replaceEnt:
+ text = escape(text)
+ return text
diff --git a/doc/ws_docutils/span/__init__.py b/doc/ws_docutils/span/__init__.py
new file mode 100644
--- /dev/null
+++ b/doc/ws_docutils/span/__init__.py
@@ -0,0 +1,80 @@
+# $Id$
+# Authors: Wolfgang Scherer
+# Copyright: This module has been placed in the public domain.
+"""
+This module defines the span role and div directive.
+
+It sets up command line options and splices the various definitions
+into the docutils modules.
+"""
+
+# --------------------------------------------------
+# |||:sec:||| CONFIGURATION
+# --------------------------------------------------
+
+from docutils import frontend
+import docutils.parsers.rst
+
+span_settings = [
+ ('Disable the "span" role and "div" directive; " '
+ 'replaced with a "warning system message.',
+ ['--no-span'],
+ {'action': 'store_false', 'default': 1, 'dest': 'span_enabled',
+ 'validator': frontend.validate_boolean}),
+ ('Enable the "span" role and "div" directive. Enabled by default.',
+ ['--span-enabled'],
+ {'action': 'store_true'}),
+ ('Disable "span" role recursive parsing. '
+ 'Disbled by default.',
+ ['--no-span-recursive'],
+ {'action': 'store_false', 'default': 0, 'dest': 'span_recursive',
+ 'validator': frontend.validate_boolean}),
+ ('Enable "span" role recursive parsing.',
+ ['--span-recursive'],
+ {'action': 'store_true'}),
+ ]
+
+ss = list(docutils.parsers.rst.Parser.settings_spec)
+opts = list(ss[2])
+opts.extend(span_settings)
+ss[2] = tuple(opts)
+docutils.parsers.rst.Parser.settings_spec = tuple(ss)
+
+# --------------------------------------------------
+# |||:sec:||| SETUP
+# --------------------------------------------------
+
+# install `span` and `div` nodes
+import ws_docutils.span.nodes
+# install `span` role
+import ws_docutils.span.role
+# install `div` directive
+import ws_docutils.span.directive
+# install writer support
+import ws_docutils.span.writer
+
+# --------------------------------------------------
+# |||:sec:||| END
+# --------------------------------------------------
+#
+# :ide-menu: Emacs IDE Main Menu - Buffer @BUFFER@
+# . M-x `eIDE-menu' ()(eIDE-menu "z")
+
+# :ide: CLN: Clean file (remove excess blank lines and whitespace)
+# . (let () (save-excursion (goto-char (point-min)) (set-buffer-modified-p t) (replace-regexp "\n\n\n+" "\n\n" nil) (c-beautify-buffer) (save-buffer)))
+
+# :ide: CSCOPE ON
+# . (cscope-minor-mode)
+
+# :ide: CSCOPE OFF
+# . (cscope-minor-mode (quote ( nil )))
+
+# :ide: COMPILE: Run w/o args
+# . (progn (save-buffer) (compile (concat "python ./" (file-name-nondirectory (buffer-file-name)) " ")))
+#
+# Local Variables:
+# mode: python
+# comment-start: "#"
+# comment-start-skip: "#+"
+# comment-column: 0
+# End:
diff --git a/doc/ws_docutils/span/directive.py b/doc/ws_docutils/span/directive.py
new file mode 100644
--- /dev/null
+++ b/doc/ws_docutils/span/directive.py
@@ -0,0 +1,725 @@
+# $Id$
+# Authors: Wolfgang Scherer
+# Copyright: This module has been placed in the public domain.
+"""
+This module defines the div directive.
+"""
+
+__docformat__ = 'reStructuredText'
+
+import sys
+import os.path
+import re
+import time
+from docutils import io, nodes, statemachine, utils
+from docutils.parsers.rst import Directive, convert_directive_function
+from docutils.parsers.rst import directives, roles, states
+from docutils.transforms import misc
+
+# --------------------------------------------------
+# |||:sec:||| class Div
+# --------------------------------------------------
+
+class Div(Directive):
+ # ||:cls:||
+ """
+ Content is included or removed from output based on the format
+ argument.
+
+ Content may be parsed by the parser, included as a literal block
+ or in raw format.
+
+ Only a part of the text may be included by specifying start and
+ end line or text to match before and/or after the text to be used.
+
+ Content may be included inline (content section of directive) or
+ imported from a file or url. The tab-width and encoding of an
+ included file or url can be specified.
+ """
+
+ required_arguments = 0
+ optional_arguments = 1
+ final_argument_whitespace = True
+ option_spec = {
+ 'format': directives.unchanged,
+ 'literal': directives.flag,
+ 'raw': directives.flag,
+ 'start-line': directives.nonnegative_int,
+ 'end-line': directives.nonnegative_int,
+ 'start-after': directives.unchanged_required,
+ 'end-before': directives.unchanged_required,
+ 'file': directives.path,
+ 'url': directives.uri,
+ 'tab-width': directives.nonnegative_int,
+ 'encoding': directives.encoding,
+ 'inline': directives.flag,
+ 'debug': directives.flag,
+ }
+ has_content = True
+
+ def dbg_data(self, name, data, fmt ='s'): # |:mth:|
+ if self.debug_enabled:
+ import sys
+ fmt_str=''.join(["# {1:<{0}", fmt, "}: [{2!s}]\n"])
+ sys.stderr.write(
+ fmt_str.format(
+ dbg_fwid if 'dbg_fwid' in globals() else self.debug_fwid,
+ name, data))
+
+ def dbg_mark(self, mark, fmt ='s'): # |:mth:|
+ self.dbg_data( '||' ':div:||', mark, fmt)
+
+ def dbg_note(self, note, fmt ='s'): # |:mth:|
+ self.dbg_data( ' |' ':div:| ', note, fmt)
+
+ debug_fwid = 15
+ debug_enabled = False
+ #debug_enabled = True # |:debug:|
+
+ def run(self): # |:mth:|
+ if 'debug' in self.options:
+ self.debug_enabled = True
+
+ self.dbg_mark('start')
+
+ if (not self.state.document.settings.span_enabled
+ or (not self.state.document.settings.file_insertion_enabled
+ and ('file' in self.options
+ or 'url' in self.options))):
+ raise self.warning('"%s" directive disabled.' % self.name)
+
+ if not nodes.span.ext_initialized:
+ nodes.span.ext_init(self.state.inliner.document.settings)
+
+ have_fopt = 'format' in self.options
+ have_arg = len(self.arguments) > 0
+ if have_fopt and have_arg:
+ raise self.error(
+ '"{0!s}" directive may not both specify the format as argument '
+ 'and in the option list.'.format(self.name))
+
+ # check disposition
+ if 'literal' in self.options:
+ literal = 1
+ else:
+ literal = 0
+ if 'raw' in self.options:
+ raw = 1
+ else:
+ raw = 0
+ if literal and raw:
+ raise self.error(
+ '"{0!s}" directive may not both specify literal '
+ 'and raw as disposition in the option list.'.format(
+ self.name))
+ self.options['literal'] = literal
+ self.options['raw'] = raw
+
+ # determine format list
+ if have_arg:
+ format_ = self.arguments[0]
+ elif have_fopt:
+ format_ = self.options['format']
+ else:
+ format_ = '*'
+ format_ = ' '.join(format_.lower().split())
+ if format_.startswith('!'):
+ drop = 1
+ format_ = format_[1:].strip()
+ if format_ == '':
+ format_ = '*'
+ elif format_ == '*':
+ format_ = ''
+ else:
+ drop = 0
+ self.options['format'] = format_
+ self.options['drop'] = drop
+
+ # always remove
+ if format_ == '':
+ self.dbg_mark('end remove')
+ return []
+
+ tab_width = self.options.get(
+ 'tab-width', self.state.document.settings.tab_width)
+ encoding = self.options.get(
+ 'encoding', self.state.document.settings.input_encoding)
+
+ if 'inline' in self.options:
+ inline = 1
+ else:
+ inline = 0
+
+ # format == '*' == all formats allowed == never remove = keep
+ if format_ == "'*'":
+ inline = 1
+
+ attributes = self.options
+
+ # |:sec:| get contents
+ offset = -1
+ source_ = 'direct'
+ if self.content:
+ if 'file' in self.options or 'url' in self.options:
+ raise self.error(
+ '"%s" directive may not both specify an external file '
+ 'and have content.' % self.name)
+ text = '\n'.join(self.content)
+ offset = self.content_offset
+ elif 'file' in self.options:
+ if 'url' in self.options:
+ raise self.error(
+ 'The "file" and "url" options may not be simultaneously '
+ 'specified for the "%s" directive.' % self.name)
+ source_dir = os.path.dirname(
+ os.path.abspath(self.state.document.current_source))
+ path = os.path.normpath(os.path.join(source_dir,
+ self.options['file']))
+ path = utils.relative_path(None, path)
+ try:
+ self.state.document.settings.record_dependencies.add(path)
+ raw_file = io.FileInput(
+ source_path=path, encoding=encoding,
+ error_handler=(self.state.document.settings.\
+ input_encoding_error_handler),
+ handle_io_errors=None)
+ except IOError, error:
+ raise self.severe('Problems with "%s" directive path:\n%s.'
+ % (self.name, error))
+ try:
+ text = raw_file.read()
+ except UnicodeError, error:
+ raise self.severe(
+ 'Problem with "%s" directive:\n%s: %s'
+ % (self.name, error.__class__.__name__, error))
+ attributes['source'] = path
+ source_ = path
+ elif 'url' in self.options:
+ source = self.options['url']
+ # Do not import urllib2 at the top of the module because
+ # it may fail due to broken SSL dependencies, and it takes
+ # about 0.15 seconds to load.
+ import urllib2
+ try:
+ raw_text = urllib2.urlopen(source).read()
+ except (urllib2.URLError, IOError, OSError), error:
+ raise self.severe(
+ 'Problems with "%s" directive URL "%s":\n%s.'
+ % (self.name, self.options['url'], error))
+ raw_file = io.StringInput(
+ source=raw_text, source_path=source, encoding=encoding,
+ error_handler=(self.state.document.settings.\
+ input_encoding_error_handler))
+ try:
+ text = raw_file.read()
+ except UnicodeError, error:
+ raise self.severe(
+ 'Problem with "%s" directive:\n%s: %s'
+ % (self.name, error.__class__.__name__, error))
+ attributes['source'] = source
+ source_ = source
+ else:
+ # This will always fail because there is no content.
+ self.assert_has_content()
+
+ # |:sec:| extract lines
+ startline = self.options.get('start-line', None)
+ endline = self.options.get('end-line', None)
+ try:
+ if startline or (endline is not None):
+ lines = statemachine.string2lines(
+ text, tab_width, convert_whitespace=1)
+ text = '\n'.join(lines[startline:endline])
+ except UnicodeError, error:
+ raise self.severe(
+ 'Problem with "%s" directive:\n%s: %s'
+ % (self.name, error.__class__.__name__, error))
+ # start-after/end-before: no restrictions on newlines in match-text,
+ # and no restrictions on matching inside lines vs. line boundaries
+
+ after_text = self.options.get('start-after', None)
+ if after_text:
+ opttext_nodes, opttext_msgs = self.state.inline_text(after_text,offset)
+ if len(opttext_msgs) > 0:
+ self.dbg_mark('end error')
+ return opttext_nodes, opttext_msgs
+ opttext_txt = []
+ for otn in opttext_nodes:
+ opttext_txt.append( otn.astext())
+ after_text = ''.join(opttext_txt)
+ # skip content in rawtext before *and incl.* a matching text
+ after_index = text.find(after_text)
+ if after_index < 0:
+ raise self.severe(
+ 'Problem with "start-after" option of "{0!s}" '
+ 'directive:\nText `{1!s}` not found.'.format(
+ self.name,after_text))
+ text = text[after_index + len(after_text):]
+ before_text = self.options.get('end-before', None)
+ if before_text:
+ opttext_nodes, opttext_msgs = self.state.inline_text(before_text,offset)
+ if len(opttext_msgs) > 0:
+ self.dbg_mark('end error')
+ return opttext_nodes, opttext_msgs
+ opttext_txt = []
+ for otn in opttext_nodes:
+ opttext_txt.append( otn.astext())
+ before_text = ''.join(opttext_txt)
+ # skip content in rawtext after *and incl.* a matching text
+ before_index = text.find(before_text)
+ if before_index < 0:
+ raise self.severe(
+ 'Problem with "end-before" option of "{0!s}" '
+ 'directive:\nText `{1!s}` not found.'.format(
+ self.name,before_text))
+ text = text[:before_index]
+
+ # |:sec:| disposition
+ if literal:
+ # Literal Block
+ raw_text = text
+ if tab_width >= 0:
+ text = raw_text.expandtabs(tab_width)
+ literal_block = nodes.literal_block(raw_text, text)
+ literal_block.line = 1
+ div_node = nodes.div('', literal_block, **attributes)
+ elif raw:
+ # Raw Text
+ raw_node = nodes.raw('', text, **attributes)
+ div_node = nodes.div('', raw_node, **attributes)
+ else:
+ # Parse Text
+ if inline:
+ include_lines = statemachine.string2lines(
+ text, tab_width, convert_whitespace=1)
+ self.state_machine.insert_input(include_lines, source_)
+ self.dbg_mark('end inline parse')
+ return []
+
+ content = statemachine.StringList(
+ statemachine.string2lines(
+ text, tab_width, convert_whitespace=1),
+ source=source_)
+
+ div_node = nodes.div('', *[], **attributes)
+ self.state.nested_parse(content, offset, div_node)
+ if inline:
+ self.dbg_mark('end inline')
+ return div_node.children
+ self.dbg_mark('end')
+ return [div_node]
+
+# --------------------------------------------------
+# |||:sec:||| class DivX
+# --------------------------------------------------
+
+class DivX(Div):
+ # ||:cls:||
+ """
+ Debugging class for Div.
+ """
+
+ def run(self): # |:mth:|
+ self.options['debug'] = True
+ try:
+ del(self.options['inline'])
+ except KeyError:
+ pass
+ return Div.run(self)
+
+ import sys # |:debug:|
+ sys.stderr.write( "# {1:<{0}s}: [{2!s}]\n".format(
+ dbg_fwid if 'dbg_fwid' in globals() else 15,
+ '||:div:||', 'start' ))
+ if False:
+ sys.stderr.write( "# {1:<{0}s}: [{2!s}]\n".format(
+ dbg_fwid if 'dbg_fwid' in globals() else 15,
+ '---------------', '--------------------------------------------------' ))
+ sys.stderr.write( "# {1:<{0}s}: [{2!s}]\n".format(
+ dbg_fwid if 'dbg_fwid' in globals() else 15,
+ self.__class__.__name__ + '.dir', dir(self)))
+ sys.stderr.write( "# {1:<{0}s}: [{2!s}]\n".format(
+ dbg_fwid if 'dbg_fwid' in globals() else 15,
+ '---------------', '--------------------------------------------------' ))
+ sys.stderr.write( "# {1:<{0}s}: [{2!s}]\n".format(
+ dbg_fwid if 'dbg_fwid' in globals() else 15,
+ self.state.__class__.__name__ + '.dir', dir(self.state)))
+ sys.stderr.write( "# {1:<{0}s}: [{2!s}]\n".format(
+ dbg_fwid if 'dbg_fwid' in globals() else 15,
+ '---------------', '--------------------------------------------------' ))
+ sys.stderr.write( "# {1:<{0}s}: [{2!s}]\n".format(
+ dbg_fwid if 'dbg_fwid' in globals() else 15,
+ self.state.parent.__class__.__name__ + '.dir', dir(self.state.parent)))
+
+ if (not self.state.document.settings.span_enabled
+ or (not self.state.document.settings.file_insertion_enabled
+ and ('file' in self.options
+ or 'url' in self.options))):
+ sys.stderr.write( "# {1:<{0}s}: [{2!s}]\n".format(
+ dbg_fwid if 'dbg_fwid' in globals() else 15,
+ '||:div:||', 'error' ))
+ raise self.warning('"%s" directive disabled.' % self.name)
+
+ if not nodes.span.ext_initialized:
+ nodes.span.ext_init(self.state.inliner.document.settings)
+
+ # |:sec:| check format list
+ have_fopt = 'format' in self.options
+ have_arg = len(self.arguments) > 0
+ if have_fopt and have_arg:
+ sys.stderr.write( "# {1:<{0}s}: [{2!s}]\n".format(
+ dbg_fwid if 'dbg_fwid' in globals() else 15,
+ '||:div:||', 'error' ))
+ raise self.error(
+ '"{0!s}" directive may not both specify the format as argument '
+ 'and in the option list.'.format(self.name))
+
+ # check disposition
+ if 'literal' in self.options:
+ literal = 1
+ else:
+ literal = 0
+ if 'raw' in self.options:
+ raw = 1
+ else:
+ raw = 0
+ if literal and raw:
+ sys.stderr.write( "# {1:<{0}s}: [{2!s}]\n".format(
+ dbg_fwid if 'dbg_fwid' in globals() else 15,
+ '||:div:||', 'error' ))
+ raise self.error(
+ '"{0!s}" directive may not both specify literal '
+ 'and raw as disposition in the option list.'.format(
+ self.name))
+ self.options['literal'] = literal
+ self.options['raw'] = raw
+
+ # determine format list
+ if have_arg:
+ format_ = self.arguments[0]
+ elif have_fopt:
+ format_ = self.options['format']
+ else:
+ format_ = '*'
+ format_ = ' '.join(format_.lower().split())
+ if format_.startswith('!'):
+ drop = 1
+ format_ = format_[1:].strip()
+ if format_ == '':
+ format_ = '*'
+ elif format_ == '*':
+ format_ = ''
+ else:
+ drop = 0
+ self.options['format'] = format_
+ self.options['drop'] = drop
+
+ # always remove
+ if format_ == '':
+ sys.stderr.write( "# {1:<{0}s}: [{2!s}]\n".format(
+ dbg_fwid if 'dbg_fwid' in globals() else 15,
+ '||:div:||', 'end' ))
+ return []
+ # format == '*' == all formats allowed == never remove = keep
+ if format_ == "'*'":
+ wrap = True # |:check:| let's always wrap?
+ else:
+ wrap = True
+
+ tab_width = self.options.get(
+ 'tab-width', self.state.document.settings.tab_width)
+ encoding = self.options.get(
+ 'encoding', self.state.document.settings.input_encoding)
+
+ if 'inline' in self.options:
+ inline = 1
+ else:
+ inline = 0
+
+ attributes = self.options
+
+ # |:sec:| get contents
+ offset = -1
+ source_ = 'direct'
+ if self.content:
+ if 'file' in self.options or 'url' in self.options:
+ sys.stderr.write( "# {1:<{0}s}: [{2!s}]\n".format(
+ dbg_fwid if 'dbg_fwid' in globals() else 15,
+ '||:div:||', 'error' ))
+ raise self.error(
+ '"%s" directive may not both specify an external file '
+ 'and have content.' % self.name)
+ text = '\n'.join(self.content)
+ offset = self.content_offset
+ elif 'file' in self.options:
+ if 'url' in self.options:
+ sys.stderr.write( "# {1:<{0}s}: [{2!s}]\n".format(
+ dbg_fwid if 'dbg_fwid' in globals() else 15,
+ '||:div:||', 'error' ))
+ raise self.error(
+ 'The "file" and "url" options may not be simultaneously '
+ 'specified for the "%s" directive.' % self.name)
+ source_dir = os.path.dirname(
+ os.path.abspath(self.state.document.current_source))
+ path = os.path.normpath(os.path.join(source_dir,
+ self.options['file']))
+ path = utils.relative_path(None, path)
+ try:
+ self.state.document.settings.record_dependencies.add(path)
+ raw_file = io.FileInput(
+ source_path=path, encoding=encoding,
+ error_handler=(self.state.document.settings.\
+ input_encoding_error_handler),
+ handle_io_errors=None)
+ except IOError, error:
+ sys.stderr.write( "# {1:<{0}s}: [{2!s}]\n".format(
+ dbg_fwid if 'dbg_fwid' in globals() else 15,
+ '||:div:||', 'error' ))
+ raise self.severe('Problems with "%s" directive path:\n%s.'
+ % (self.name, error))
+ try:
+ text = raw_file.read()
+ except UnicodeError, error:
+ sys.stderr.write( "# {1:<{0}s}: [{2!s}]\n".format(
+ dbg_fwid if 'dbg_fwid' in globals() else 15,
+ '||:div:||', 'error' ))
+ raise self.severe(
+ 'Problem with "%s" directive:\n%s: %s'
+ % (self.name, error.__class__.__name__, error))
+ attributes['source'] = path
+ source_ = path
+ elif 'url' in self.options:
+ source = self.options['url']
+ # Do not import urllib2 at the top of the module because
+ # it may fail due to broken SSL dependencies, and it takes
+ # about 0.15 seconds to load.
+ import urllib2
+ try:
+ raw_text = urllib2.urlopen(source).read()
+ except (urllib2.URLError, IOError, OSError), error:
+ sys.stderr.write( "# {1:<{0}s}: [{2!s}]\n".format(
+ dbg_fwid if 'dbg_fwid' in globals() else 15,
+ '||:div:||', 'error' ))
+ raise self.severe(
+ 'Problems with "%s" directive URL "%s":\n%s.'
+ % (self.name, self.options['url'], error))
+ raw_file = io.StringInput(
+ source=raw_text, source_path=source, encoding=encoding,
+ error_handler=(self.state.document.settings.\
+ input_encoding_error_handler))
+ try:
+ text = raw_file.read()
+ except UnicodeError, error:
+ sys.stderr.write( "# {1:<{0}s}: [{2!s}]\n".format(
+ dbg_fwid if 'dbg_fwid' in globals() else 15,
+ '||:div:||', 'error' ))
+ raise self.severe(
+ 'Problem with "%s" directive:\n%s: %s'
+ % (self.name, error.__class__.__name__, error))
+ attributes['source'] = source
+ source_ = source
+ else:
+ # This will always fail because there is no content.
+ self.assert_has_content()
+
+ # |:sec:| extract lines
+ startline = self.options.get('start-line', None)
+ endline = self.options.get('end-line', None)
+ try:
+ if startline or (endline is not None):
+ lines = statemachine.string2lines(
+ text, tab_width, convert_whitespace=1)
+ text = '\n'.join(lines[startline:endline])
+ except UnicodeError, error:
+ sys.stderr.write( "# {1:<{0}s}: [{2!s}]\n".format(
+ dbg_fwid if 'dbg_fwid' in globals() else 15,
+ '||:div:||', 'error' ))
+ raise self.severe(
+ 'Problem with "%s" directive:\n%s: %s'
+ % (self.name, error.__class__.__name__, error))
+ # start-after/end-before: no restrictions on newlines in match-text,
+ # and no restrictions on matching inside lines vs. line boundaries
+
+ after_text = self.options.get('start-after', None)
+ if after_text:
+ opttext_nodes, opttext_msgs = self.state.inline_text(after_text,offset)
+ if len(opttext_msgs) > 0:
+ sys.stderr.write( "# {1:<{0}s}: [{2!s}]\n".format(
+ dbg_fwid if 'dbg_fwid' in globals() else 15,
+ '||:div:||', 'error' ))
+ return opttext_nodes, opttext_msgs
+ opttext_txt = []
+ for otn in opttext_nodes:
+ opttext_txt.append( otn.astext())
+ after_text = ''.join(opttext_txt)
+ # skip content in rawtext before *and incl.* a matching text
+ after_index = text.find(after_text)
+ if after_index < 0:
+ sys.stderr.write( "# {1:<{0}s}: [{2!s}]\n".format(
+ dbg_fwid if 'dbg_fwid' in globals() else 15,
+ '||:div:||', 'error' ))
+ raise self.severe(
+ 'Problem with "start-after" option of "{0!s}" '
+ 'directive:\nText `{1!s}` not found.'.format(
+ self.name,after_text))
+ text = text[after_index + len(after_text):]
+ before_text = self.options.get('end-before', None)
+ if before_text:
+ opttext_nodes, opttext_msgs = self.state.inline_text(before_text,offset)
+ if len(opttext_msgs) > 0:
+ sys.stderr.write( "# {1:<{0}s}: [{2!s}]\n".format(
+ dbg_fwid if 'dbg_fwid' in globals() else 15,
+ '||:div:||', 'error' ))
+ return opttext_nodes, opttext_msgs
+ opttext_txt = []
+ for otn in opttext_nodes:
+ opttext_txt.append( otn.astext())
+ before_text = ''.join(opttext_txt)
+ # skip content in rawtext after *and incl.* a matching text
+ before_index = text.find(before_text)
+ if before_index < 0:
+ sys.stderr.write( "# {1:<{0}s}: [{2!s}]\n".format(
+ dbg_fwid if 'dbg_fwid' in globals() else 15,
+ '||:div:||', 'error' ))
+ raise self.severe(
+ 'Problem with "end-before" option of "{0!s}" '
+ 'directive:\nText `{1!s}` not found.'.format(
+ self.name,before_text))
+ text = text[:before_index]
+
+ # |:sec:| disposition
+ if literal:
+ # Literal Block
+ raw_text = text
+ if tab_width >= 0:
+ text = raw_text.expandtabs(tab_width)
+ literal_block = nodes.literal_block(raw_text, text)
+ literal_block.line = 1
+ if not wrap:
+ div_node = literal_block
+ else:
+ div_node = nodes.div('', literal_block, **attributes)
+ elif raw:
+ # Raw Text
+ raw_node = nodes.raw('', text, **attributes)
+ div_node = nodes.div('', raw_node, **attributes)
+ else:
+ # Parse Text
+ parent = self.state.parent
+ pchild_ct = len(parent.children)
+ # |:debug:|
+ sys.stderr.write( "# {1:<{0}s}: [{2!s}]\n".format(
+ dbg_fwid if 'dbg_fwid' in globals() else 15,
+ 'pname', parent.__class__.__name__ ))
+ sys.stderr.write( "# {1:<{0}s}: [{2!s}]\n".format(
+ dbg_fwid if 'dbg_fwid' in globals() else 15,
+ 'pchild_ct', pchild_ct ))
+ sys.stderr.write( "# {1:<{0}s}: [{2!s}]\n".format(
+ dbg_fwid if 'dbg_fwid' in globals() else 15,
+ 'state', self.state.__class__.__name__ ))
+ sys.stderr.write( "# {1:<{0}s}: [{2!s}]\n".format(
+ dbg_fwid if 'dbg_fwid' in globals() else 15,
+ 'state.nested_sm', self.state.nested_sm.__name__ ))
+ # sys.stderr.write( "# {1:<{0}s}: [{2!s}]\n".format(
+ # dbg_fwid if 'dbg_fwid' in globals() else 15,
+ # 'state dir', dir(self.state)))
+
+ if inline and 0:
+ include_lines = statemachine.string2lines(
+ text, tab_width, convert_whitespace=1)
+ self.state_machine.insert_input(include_lines, source_)
+ sys.stderr.write( "# {1:<{0}s}: [{2!s}]\n".format(
+ dbg_fwid if 'dbg_fwid' in globals() else 15,
+ '||:div:||', 'end' ))
+ return []
+
+ content = statemachine.StringList(
+ statemachine.string2lines(
+ text, tab_width, convert_whitespace=1),
+ source=source_)
+
+ div_node = nodes.div('', *[], **attributes)
+ try:
+ self.state.nested_parse(content, offset, div_node, 1)
+ except Exception as e:
+ sys.stderr.write( "# {1:<{0}s}: [{2!r}]\n".format(
+ dbg_fwid if 'dbg_fwid' in globals() else 15,
+ e.__class__.__name__, dir(e)))
+ sys.stderr.write( "# {1:<{0}s}: [{2!s}]\n".format(
+ dbg_fwid if 'dbg_fwid' in globals() else 15,
+ '||:div:||', 'error below' ))
+ raise e
+ sys.stderr.write( "# {1:<{0}s}: [{2!s}]\n".format(
+ dbg_fwid if 'dbg_fwid' in globals() else 15,
+ 'children', div_node.children ))
+
+ if inline and 0:
+ return div_node.children
+ sys.stderr.write( "# {1:<{0}s}: [{2!s}]\n".format(
+ dbg_fwid if 'dbg_fwid' in globals() else 15,
+ '||:div:||', 'end' ))
+ return [div_node]
+
+# --------------------------------------------------
+# |||:sec:||| Register Div
+# --------------------------------------------------
+
+_register_div_class = Div
+#_register_div_class = DivX # |:debug:|
+
+# Register as if part of docutils.
+
+# add role name to language en
+from docutils.parsers.rst.languages import en
+en.directives['div'] = 'div'
+# install `div` directive
+import docutils.parsers.rst.directives
+import docutils.parsers.rst.directives.misc
+docutils.parsers.rst.directives.misc.Div = _register_div_class
+docutils.parsers.rst.directives._directive_registry[ 'div' ] = ('misc', _register_div_class.__name__)
+
+# --------------------------------------------------
+# |||:sec:||| Register DivX
+# --------------------------------------------------
+
+# Register as if part of docutils.
+
+# add role name to language en
+from docutils.parsers.rst.languages import en
+en.directives['divx'] = 'divx'
+# install `divx` directive
+import docutils.parsers.rst.directives
+import docutils.parsers.rst.directives.misc
+docutils.parsers.rst.directives.misc.DivX = DivX
+docutils.parsers.rst.directives._directive_registry[ 'divx' ] = ('misc', 'DivX')
+
+# Register application specific.
+
+#import docutils.parsers.rst.directives
+#docutils.parsers.rst.directives.register_directive('div', Div)
+
+# --------------------------------------------------
+# |||:sec:||| END
+# --------------------------------------------------
+#
+# :ide-menu: Emacs IDE Main Menu - Buffer @BUFFER@
+# . M-x `eIDE-menu' ()(eIDE-menu "z")
+
+# :ide: CLN: Clean file (remove excess blank lines and whitespace)
+# . (let () (save-excursion (goto-char (point-min)) (set-buffer-modified-p t) (replace-regexp "\n\n\n+" "\n\n" nil) (c-beautify-buffer) (save-buffer)))
+
+# :ide: CSCOPE ON
+# . (cscope-minor-mode)
+
+# :ide: CSCOPE OFF
+# . (cscope-minor-mode (quote ( nil )))
+
+# :ide: COMPILE: Run w/o args
+# . (progn (save-buffer) (compile (concat "python ./" (file-name-nondirectory (buffer-file-name)) " ")))
+#
+# Local Variables:
+# mode: python
+# comment-start: "#"
+# comment-start-skip: "#+"
+# comment-column: 0
+# End:
diff --git a/doc/ws_docutils/span/nodes.py b/doc/ws_docutils/span/nodes.py
new file mode 100644
--- /dev/null
+++ b/doc/ws_docutils/span/nodes.py
@@ -0,0 +1,162 @@
+# $Id$
+# Authors: Wolfgang Scherer
+# Copyright: This module has been placed in the public domain.
+"""
+This module defines the div and span nodes.
+
+It also adds default visit/depart handler to
+docutils.nodes.NodeVisitor.
+"""
+
+__docformat__ = 'reStructuredText'
+
+import sys
+# (progn (forward-line 1) (snip-insert-mode "py.b.printf" t) (insert "\n"))
+# (progn (forward-line 1) (snip-insert-mode "py.b.sformat" t) (insert "\n"))
+# (progn (forward-line 1) (snip-insert-mode "py.f.printe" t) (insert "\n"))
+
+# --------------------------------------------------
+# |||:sec:||| NODES
+# --------------------------------------------------
+
+import docutils.nodes
+from docutils.nodes import Special, PreBibliographic, Structural, Element, Inline, TextElement
+
+class span(Inline, TextElement):
+ # ||:cls:||
+ """
+ Data that is to be removed by the Parser or Writer for specific
+ output formats.
+
+ This is the inline version with text data.
+
+ It also contains the static variables for both span and diversion
+ nodes.
+ """
+
+ ext_initialized = False
+ "Flag for remove directive/role, writer to perform setup."
+
+ output_format = "*"
+ """Output format that the text is to be removed for.
+ If it is `*', the text is always removed.
+ If it is None, the text is never removed (`keep` semantics).
+ """
+
+ @staticmethod
+ def ext_init(settings):
+ """Perform initialization."""
+ if settings.span_enabled:
+ # |:info:| do not change output format, so it can be overridden for 'rst2pdf'
+ # docutils.nodes.span.output_format = '*'
+ pass
+ else:
+ docutils.nodes.span.output_format = None
+ import sys # |:debug:|
+ span.ext_initialized = True;
+
+ def astext(self):
+ format_ = self.output_format
+ # format = None => keep
+ # format = '*' => Remove
+ format_opt = self.get('format', '').split()
+ if not (format_
+ and (format_ == '*'
+ or format_ in self.get('format', '').split())):
+
+ return TextElement.astext(self)
+ return ''
+
+class div(Special, PreBibliographic, Structural, Element):
+ # ||:cls:||
+ """
+ Data that is to be removed by the Parser or Writer for specific
+ output formats.
+
+ This is the container version without data.
+
+ The static variables for both span and diversion nodes are located
+ in the span class.
+ """
+
+# install the `span` and `div` nodes.
+docutils.nodes.span = span
+docutils.nodes.div = div
+
+# --------------------------------------------------
+# |||:sec:||| FUNCTIONS
+# --------------------------------------------------
+
+import docutils.nodes
+
+def visit_span(self, node): # ||:fnc:||
+ """
+ Called when entering a `span` node.
+
+ Raise exception `SkipNode` if the nodes' format matches
+ static class attribute `nodes.span.output_format`.
+ """
+ format_ = docutils.nodes.span.output_format
+ import sys # |:debug:|
+ nformat = node.get('format', '*')
+ allowed = (format_
+ and (format_ == '*'
+ or nformat == '*'
+ or format_ in nformat.split()))
+ if node.get('drop',0):
+ allowed = not allowed
+ if allowed and True: # |:debug:|
+ return ''
+ if format_ and format_ == 'pdf':
+ # |:info:| rst2pdf does not use a proper writer, so cut off children right here
+ node.children = []
+ raise docutils.nodes.SkipNode
+
+def depart_span(self, node): # ||:fnc:||
+ """
+ Called when leaving a `span` node.
+ """
+ pass
+
+# install the NodeVisitor default handlers
+docutils.nodes.NodeVisitor.visit_span = visit_span
+docutils.nodes.NodeVisitor.depart_span = depart_span
+docutils.nodes.NodeVisitor.visit_div = visit_span
+docutils.nodes.NodeVisitor.depart_div = depart_span
+
+# patch nodes.raw
+def nodes_raw_astext(self):
+ format_ = self.output_format
+ if format_ and (format_ == '*'
+ or format_ in self.get('format', '').split()):
+ return docutils.nodes.FixedTextElement.astext(self)
+ return ''
+
+docutils.nodes.raw.output_format = None
+docutils.nodes.raw.astext = nodes_raw_astext
+
+# --------------------------------------------------
+# |||:sec:||| END
+# --------------------------------------------------
+#
+# :ide-menu: Emacs IDE Main Menu - Buffer @BUFFER@
+# . M-x `eIDE-menu' ()(eIDE-menu "z")
+
+# :ide: CLN: Clean file (remove excess blank lines and whitespace)
+# . (let () (save-excursion (goto-char (point-min)) (set-buffer-modified-p t) (replace-regexp "\n\n\n+" "\n\n" nil) (c-beautify-buffer) (save-buffer)))
+
+# :ide: CSCOPE ON
+# . (cscope-minor-mode)
+
+# :ide: CSCOPE OFF
+# . (cscope-minor-mode (quote ( nil )))
+
+# :ide: COMPILE: Run w/o args
+# . (progn (save-buffer) (compile (concat "python ./" (file-name-nondirectory (buffer-file-name)) " ")))
+#
+# Local Variables:
+# mode: python
+# comment-start: "#"
+# comment-start-skip: "#+"
+# comment-column: 0
+# End:
diff --git a/doc/ws_docutils/span/role.py b/doc/ws_docutils/span/role.py
new file mode 100644
--- /dev/null
+++ b/doc/ws_docutils/span/role.py
@@ -0,0 +1,193 @@
+# $Id$
+# Copyright: This module has been placed in the public domain.
+"""
+This module defines the interpreted text role functions for span
+nodes.
+"""
+
+__docformat__ = 'reStructuredText'
+
+# import sys
+# (progn (forward-line 1) (snip-insert-mode "py.b.printf" t) (insert "\n"))
+# (progn (forward-line 1) (snip-insert-mode "py.b.sformat" t) (insert "\n"))
+# (progn (forward-line 1) (snip-insert-mode "py.f.printe" t) (insert "\n"))
+
+from docutils import nodes, utils
+from docutils.parsers.rst import directives
+from docutils.parsers.rst.languages import en
+from docutils.parsers.rst.roles import register_canonical_role, set_classes
+
+import sys
+def show_step(indx):
+ return indx + 1
+
+def span_role(role, rawtext, text, lineno, inliner, options={}, content=[]):
+ import sys # |:debug:|
+
+ def recursive_inliner_parse(text,lineno,inliner):
+ # EXPERIMENTAL recursive parse
+ import docutils.parsers.rst.states
+ my_inliner = docutils.parsers.rst.states.Inliner()
+ my_inliner.init_customizations(inliner.document.settings)
+ my_memo = docutils.parsers.rst.states.Struct(
+ document=inliner.document,
+ reporter=inliner.document.reporter,
+ language=inliner.language,
+ title_styles=[],
+ section_level=0,
+ section_bubble_up_kludge=0,
+ inliner=my_inliner)
+ nodes_, msgs = my_inliner.parse(text, lineno, my_memo, inliner.parent)
+ if len(msgs) > 0:
+ msg = inliner.reporter.warning('span: internal parse error')
+ prb = inliner.problematic(rawtext, rawtext, msg)
+ return [prb], [msg].extend(msgs)
+ return nodes_, []
+
+ #indx=show_step(0) # 0
+ if not inliner.document.settings.span_enabled:
+ msg = inliner.reporter.warning('span role disabled')
+ prb = inliner.problematic(rawtext, rawtext, msg)
+ return [prb], [msg]
+ #indx=show_step(indx) # 1
+ if not nodes.span.ext_initialized:
+ nodes.span.ext_init(inliner.document.settings)
+
+ if 'format' in options:
+ format_ = ' '.join(options['format'].lower().split())
+ if (len(format_) >= 2
+ and format_[0] == "'"
+ and format_[-1] == "'"):
+ format_ = format_[1:-1]
+ else:
+ format_ = '*'
+ format_ = ' '.join(format_.lower().split())
+ if format_.startswith('!'):
+ drop = 1
+ format_ = format_[1:].strip()
+ if format_ == '':
+ format_ = '*'
+ elif format_ == '*':
+ format_ = ''
+ else:
+ drop = 0
+ options['format'] = format_
+ options['drop'] = drop
+
+ # not allowed for any output => remove
+ if format_ == '':
+ return [], []
+
+ if 'literal' not in options:
+ literal = 0
+ else:
+ literal = options['literal']
+ options['literal'] = literal
+
+ if 'raw' not in options:
+ raw = 0
+ else:
+ raw = 1
+ options['raw'] = raw
+
+ if literal and raw:
+ msg = inliner.reporter.error(
+ '"Cannot both specify raw and'
+ ' literal options.', line=lineno)
+ prb = inliner.problematic(rawtext, rawtext, msg)
+ return [prb], [msg]
+
+ if 'pfx' in options:
+ pfx = options['pfx']
+ if (len(pfx) >= 2 and pfx[0] == "'" and pfx[-1] == "'"):
+ pfx = pfx[1:-1]
+ else:
+ pfx = ''
+ # del options['pfx'] # |:debug:|
+
+ if 'sfx' in options:
+ sfx = options['sfx']
+ if (len(sfx) >= 2 and sfx[0] == "'" and sfx[-1] == "'"):
+ sfx = sfx[1:-1]
+ else:
+ sfx = ''
+ # del options['sfx'] # |:debug:|
+
+ set_classes(options)
+
+ if raw:
+ text_nodes = [nodes.raw( rawtext, rawtext, **{})]
+ else:
+ if not inliner.document.settings.span_recursive:
+ text = ''.join([ pfx, text, sfx ])
+ text_nodes = [nodes.Text(utils.unescape(text), rawsource=utils.unescape(text, 1))]
+ else:
+ text_nodes = []
+ if pfx:
+ text_nodes.append( nodes.Text(utils.unescape(pfx), rawsource=utils.unescape(pfx, 1)))
+ nodes_, msgs_ = recursive_inliner_parse(text,lineno,inliner)
+ if len( msgs_ ):
+ return nodes_, msgs_
+ text_nodes.extend(nodes_)
+ if sfx:
+ text_nodes.append( nodes.Text(utils.unescape(sfx), rawsource=utils.unescape(sfx, 1)))
+
+ node = nodes.span( '', '', *text_nodes, **options)
+ return [node], []
+
+span_role.options = {
+ 'format': directives.unchanged,
+ 'literal': directives.flag,
+ 'raw': directives.flag,
+ 'pfx': directives.unchanged_required,
+ 'sfx': directives.unchanged_required,
+ 'ref': directives.flag,
+ }
+
+# add role name to language en
+en.roles['span'] = 'span'
+
+# install `span` role
+register_canonical_role('span', span_role)
+
+# |:here:|
+#
+# :ide-menu: Emacs IDE Main Menu - Buffer @BUFFER@
+# . M-x `eIDE-menu' (eIDE-menu "z")
+
+# :ide: CLN: Clean file (remove excess blank lines and whitespace)
+# . (let () (save-excursion (goto-char (point-min)) (set-buffer-modified-p t) (replace-regexp "\n\n\n+" "\n\n" nil) (c-beautify-buffer) (save-buffer)))
+
+# :ide: SNIP: insert PROG-PATH
+# . (snip-insert-mode "py_prog-path" nil t)
+
+# :ide: CSCOPE ON
+# . (cscope-minor-mode)
+
+# :ide: CSCOPE OFF
+# . (cscope-minor-mode (quote ( nil )))
+
+# :ide: COMPILE: Run with --help
+# . (progn (save-buffer) (compile (concat "python ./" (file-name-nondirectory (buffer-file-name)) " --help")))
+
+# :ide: COMPILE: Run with --test
+# . (progn (save-buffer) (compile (concat "python ./" (file-name-nondirectory (buffer-file-name)) " --test")))
+
+# :ide: COMPILE: Run with --test --verbose
+# . (progn (save-buffer) (compile (concat "python ./" (file-name-nondirectory (buffer-file-name)) " --test --verbose")))
+
+# :ide: INFO: Python Documentation
+# . (let ((ref-buffer "*w3m*")) (if (get-buffer ref-buffer) (display-buffer ref-buffer t)) (other-window 1) (w3m-goto-url "http://docs.python.org/index.html" nil nil))
+
+# :ide: INFO: Python Reference
+# . (let ((ref-buffer "*python-ref*")) (if (not (get-buffer ref-buffer)) (shell-command (concat "w3m -dump -cols " (number-to-string (1- (window-width))) " 'http://rgruet.free.fr/PQR26/PQR2.6.html'") ref-buffer) (display-buffer ref-buffer t)))
+
+# :ide: COMPILE: Run w/o args
+# . (progn (save-buffer) (compile (concat "python ./" (file-name-nondirectory (buffer-file-name)) " ")))
+#
+# Local Variables:
+# mode: python
+# comment-start: "#"
+# comment-start-skip: "#+"
+# comment-column: 0
+# End:
diff --git a/doc/ws_docutils/span/writer.py b/doc/ws_docutils/span/writer.py
new file mode 100644
--- /dev/null
+++ b/doc/ws_docutils/span/writer.py
@@ -0,0 +1,88 @@
+# $Id$
+# Authors: Wolfgang Scherer
+# Copyright: This module has been placed in the public domain.
+"""
+This module defines the writer support for span role and div
+directive.
+"""
+
+# import sys
+# (progn (forward-line 1) (snip-insert-mode "py.b.printf" t) (insert "\n"))
+# (progn (forward-line 1) (snip-insert-mode "py.b.sformat" t) (insert "\n"))
+# (progn (forward-line 1) (snip-insert-mode "py.f.printe" t) (insert "\n"))
+
+import docutils.nodes
+import docutils.writers
+import docutils.writers.manpage
+import docutils.writers.html4css1
+import docutils.writers.latex2e
+import docutils.writers.odf_odt
+
+docutils.writers.manpage.Writer.output_format = 'manpage'
+docutils.writers.html4css1.Writer.output_format = 'html'
+docutils.writers.latex2e.Writer.output_format = 'latex'
+docutils.writers.odf_odt.Writer.output_format = 'odt'
+
+def write(self, document, destination):
+ """
+ Process a document into its final form.
+
+ This is a wrapper around docutils.writers.Writer.write to
+ implement the correct output_format setting for span/div/raw
+ extensions. The original method is moved to
+ docutils.writers.Writer.span_write.
+ """
+ import sys # |:debug:|
+ try:
+ raw_output_format = span_output_format = self.output_format
+ except AttributeError:
+ raw_output_format = '*'
+ span_output_format = None
+ try:
+ raw_output_format_sv = docutils.nodes.raw.output_format
+ have_raw_patch = True
+ except AttributeError:
+ have_raw_patch = False
+ span_output_format_sv = docutils.nodes.span.output_format
+ docutils.nodes.raw.output_format = raw_output_format
+ # |:todo:| |:check:| sphinx does not have this setting. why?
+ try:
+ if document.settings.span_enabled:
+ docutils.nodes.span.output_format = span_output_format
+ except AttributeError:
+ document.settings.span_enabled = True
+ docutils.nodes.span.output_format = span_output_format
+ output = self.span_write(document,destination)
+ if have_raw_patch:
+ docutils.nodes.raw.output_format = raw_output_format_sv
+ docutils.nodes.span.output_format = span_output_format_sv
+ return output
+
+docutils.writers.Writer.span_write = docutils.writers.Writer.write
+docutils.writers.Writer.write = write
+
+# --------------------------------------------------
+# |||:sec:||| END
+# --------------------------------------------------
+#
+# :ide-menu: Emacs IDE Main Menu - Buffer @BUFFER@
+# . M-x `eIDE-menu' ()(eIDE-menu "z")
+
+# :ide: CLN: Clean file (remove excess blank lines and whitespace)
+# . (let () (save-excursion (goto-char (point-min)) (set-buffer-modified-p t) (replace-regexp "\n\n\n+" "\n\n" nil) (c-beautify-buffer) (save-buffer)))
+
+# :ide: CSCOPE ON
+# . (cscope-minor-mode)
+
+# :ide: CSCOPE OFF
+# . (cscope-minor-mode (quote ( nil )))
+
+# :ide: COMPILE: Run w/o args
+# . (progn (save-buffer) (compile (concat "python ./" (file-name-nondirectory (buffer-file-name)) " ")))
+#
+# Local Variables:
+# mode: python
+# comment-start: "#"
+# comment-start-skip: "#+"
+# comment-column: 0
+# End:
diff --git a/doc/ws_docutils/trachtml.py b/doc/ws_docutils/trachtml.py
new file mode 100644
--- /dev/null
+++ b/doc/ws_docutils/trachtml.py
@@ -0,0 +1,102 @@
+# -*- coding: utf-8 -*-
+# Copyright (C) 2011, Wolfgang Scherer,
+# Sponsored by WIEDENMANN SEILE GMBH, http://www.wiedenmannseile.de
+#
+# This file is part of WSRFID.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see ,
+# or write to Wolfgang Scherer, Neue Obernbreiter Str. 5, D-97340
+# Marktbreit or
+"""\
+trachtml.py - docutils monkey patch to get icon for external links in trac.
+
+usage: import ws_docutils.trachtml
+"""
+
+# --------------------------------------------------
+# |||:sec:||| CLASSES
+# --------------------------------------------------
+
+# --------------------------------------------------
+# |||:sec:||| FUNCTIONS
+# --------------------------------------------------
+
+from docutils import nodes
+
+def visit_reference(self, node):
+ atts = {'class': 'reference'}
+ if 'refuri' in node:
+ atts['href'] = node['refuri']
+ if ( self.settings.cloak_email_addresses
+ and atts['href'].startswith('mailto:')):
+ atts['href'] = self.cloak_mailto(atts['href'])
+ self.in_mailto = 1
+ atts['class'] += ' external'
+ atts['class'] += ' ext-uri'
+ else:
+ assert 'refid' in node, \
+ 'References must have "refuri" or "refid" attribute.'
+ atts['href'] = '#' + node['refid']
+ atts['class'] += ' internal'
+ if not isinstance(node.parent, nodes.TextElement):
+ assert len(node) == 1 and isinstance(node[0], nodes.image)
+ atts['class'] += ' image-reference'
+ self.body.append(self.starttag(node, 'a', '', **atts))
+ self.body.append('')
+
+import docutils.writers.html4css1
+docutils.writers.html4css1.HTMLTranslator.visit_reference = visit_reference
+
+# --------------------------------------------------
+# |||:sec:||| MAIN
+# --------------------------------------------------
+
+# |:here:|
+#
+# :ide-menu: Emacs IDE Main Menu - Buffer @BUFFER@
+# . M-x `eIDE-menu' (eIDE-menu "z")
+
+# :ide: SNIP: insert PROG-PATH
+# . (snip-insert-mode "py_prog-path" nil t)
+
+# :ide: CSCOPE ON
+# . (cscope-minor-mode)
+
+# :ide: CSCOPE OFF
+# . (cscope-minor-mode (quote ( nil )))
+
+# :ide: COMPILE: Run with --help
+# . (progn (save-buffer) (compile (concat "python ./" (file-name-nondirectory (buffer-file-name)) " --help")))
+
+# :ide: COMPILE: Run with --test
+# . (progn (save-buffer) (compile (concat "python ./" (file-name-nondirectory (buffer-file-name)) " --test")))
+
+# :ide: COMPILE: Run with --test --verbose
+# . (progn (save-buffer) (compile (concat "python ./" (file-name-nondirectory (buffer-file-name)) " --test --verbose")))
+
+# :ide: INFO: Python Documentation
+# . (let ((ref-buffer "*w3m*")) (if (get-buffer ref-buffer) (display-buffer ref-buffer t)) (other-window 1) (w3m-goto-url "http://docs.python.org/index.html" nil nil))
+
+# :ide: INFO: Python Reference
+# . (let ((ref-buffer "*python-ref*")) (if (not (get-buffer ref-buffer)) (shell-command (concat "w3m -dump -cols " (number-to-string (1- (window-width))) " 'http://rgruet.free.fr/PQR26/PQR2.6.html'") ref-buffer) (display-buffer ref-buffer t)))
+
+# :ide: COMPILE: Run w/o args
+# . (progn (save-buffer) (compile (concat "python ./" (file-name-nondirectory (buffer-file-name)) " ")))
+#
+# Local Variables:
+# mode: python
+# comment-start: "#"
+# comment-start-skip: "#+"
+# comment-column: 0
+# End:
diff --git a/index.php b/index.php
new file mode 100644
--- /dev/null
+++ b/index.php
@@ -0,0 +1,439 @@
+
+// Sponsored by WIEDENMANN SEILE GMBH, http://www.wiedenmannseile.de
+//
+// This file is part of Wiedenmann Vacation.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published
+// by the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see ,
+// or write to Wolfgang Scherer,
+
+// $_REQUEST['_DEBUG_'] = 1;
+
+// --------------------------------------------------
+// |||:sec:||| Configuration
+// --------------------------------------------------
+require_once(dirname(__FILE__) . '/lib/util.php');
+require_once(dirname(__FILE__) . '/lib/template.php');
+
+// _DEBUG_ = 1 normal debugging
+// _DEBUG_ = 2 turn off administrator rights
+// _DEBUG_ = 3 provoke error #1
+// _DEBUG_ = 4 provoke error #2
+if (isset($_REQUEST['_DEBUG_'])) {
+ $_debug = $_REQUEST['_DEBUG_'];
+ if (empty($_debug)) {
+ $_debug = 1;
+ }
+} else {
+ $_debug = 0;
+}
+
+file_put_contents('/tmp/xxxxxxx', 'check');
+system('touch /tmp/xxxxxx1');
+
+// --------------------------------------------------
+// |||:sec:||| Setup
+// --------------------------------------------------
+
+if (isset($_SERVER["REMOTE_USER"])) {
+ $remote_user = $_SERVER["REMOTE_USER"];
+} else {
+ $remote_user = '';
+}
+if (isset($_REQUEST["user"])) {
+ $request_user = $_REQUEST["user"];
+} else {
+ $request_user = '';
+}
+
+$is_admin = in_array($remote_user, $ADMIN_USERS);
+if ($_debug > 1) {
+ $is_admin = False;
+}
+
+$users = get_users();
+$user_names = array_keys($users);
+
+if (!$is_admin) {
+ $user = $remote_user;
+} else {
+ $user = $request_user;
+ if (empty($user)) {
+ $user = $remote_user;
+ }
+}
+
+// --------------------------------------------------
+// |||:sec:||| HTML Header
+// --------------------------------------------------
+
+$title = get_text('title');
+$css = '
+span.label {
+ width: 100px;
+ display: inline-block;
+}
+hr.sep {
+ width: 550px;
+ text-align: left;
+ margin-left: 0;
+}
+';
+
+echo substitute_elements(
+ $HEAD, Array(
+ 'title' => $title,
+ 'css' => $css,
+ ));
+hl($title);
+
+// --------------------------------------------------
+// |||:sec:||| Error handling (User)
+// --------------------------------------------------
+
+if ($_debug > 2) {
+ $user = ''; // error #1
+}
+if ($_debug > 3) {
+ $user = 'unknown'; // error #2
+}
+
+if (empty($user)) {
+ error_msg(get_text('error_no_user'));
+ echo $FOOT;
+ exit(0);
+}
+
+if (!$is_admin && !in_array($user, $user_names)) {
+ error_msg(sprintf('%s (%s)!', get_text('error_no_user'), $user));
+ echo $FOOT;
+ exit(0);
+}
+
+// --------------------------------------------------
+// |||:sec:||| Setup HOME/vacation(1)
+// --------------------------------------------------
+
+$home = $users[$user][1];
+
+if ($_debug) {
+ echo ('
\n";
+}
+
+echo $FOOT;
+
+//
+// :ide-menu: Emacs IDE Menu - Buffer @BUFFER@
+// . M-x `eIDE-menu' ()(eIDE-menu "z")
+// :ide: COMPILE: PHP _DEBUG_=2 _DEBUG_TEST_=2
+// . (compile (concat "php " (file-name-nondirectory (buffer-file-name)) " _DEBUG_=2 _DEBUG_TEST_=2"))
+
+// :ide: QUO: $this->
+// . (insert "$this->" )
+
+// :ide: COMPILE: PHP w/o args
+// . (compile (concat "php " (file-name-nondirectory (buffer-file-name)) ""))
+
+// :ide: COMPILE: PHP _DEBUG_=1 _DEBUG_TEST_=1
+// . (compile (concat "php " (file-name-nondirectory (buffer-file-name)) " _DEBUG_=1 _DEBUG_TEST_=1"))
+
+//
+// Local Variables:
+// mode: php
+// End:
+?>
diff --git a/lib/.htaccess b/lib/.htaccess
new file mode 100644
--- /dev/null
+++ b/lib/.htaccess
@@ -0,0 +1,3 @@
+order allow,deny
+Deny from all
+
diff --git a/lib/config.php b/lib/config.php
new file mode 100644
--- /dev/null
+++ b/lib/config.php
@@ -0,0 +1,101 @@
+
+// Sponsored by WIEDENMANN SEILE GMBH, http://www.wiedenmannseile.de
+//
+// This file is part of Wiedenmann Vacation.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published
+// by the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see ,
+// or write to
+
+// $_REQUEST['_DEBUG_'] = 1;
+
+// --------------------------------------------------
+// |||:sec:||| CONFIGURATION
+// --------------------------------------------------
+
+// All users in $PASSWD_FILE, whose user ID >= $USER_ID_MIN and <=
+// $USER_ID_MAX are considered:
+// 1. If the user appears in $ALLOWED_USERS, he is always included
+// 2. If the HOME directory does not start with $HOME_PFX, the user is ignored
+// 3. If the user appears in $INVALID_USERS, he is ignored
+// 4. The user is authorized.
+
+// Alle Benutzer in $PASSWD_FILE, deren User ID >= $USER_ID_MIN und <=
+// $USER_ID_MAX werden in Betracht gezogen:
+// 1. Falls der Benutzer in $ALLOWED_USERS angegeben ist, wird er immer zugelassen.
+// 2. Wenn das HOME-Verzeichnis nicht mit $HOME_PFX beginnnt, wird der Benutzer nicht zugelasssen.
+// 3. Wenn der Benutzer in $INVALID_USERS angegeben ist, wird er nicht zugelasssen.
+// 4. Der Benutzer wird zugelassen.
+
+// User which are always allowed.
+// If the user appears in $PASSWD_FILE, he is always enabled.
+$ALLOWED_USERS = Array(
+ );
+
+// Invalid users.
+// These users are always ignored.
+$INVALID_USERS = Array(
+ 'clamav',
+ 'elektriker',
+ 'info',
+ 'postman',
+ 'vmail',
+ );
+
+// Administrators can modify the settings of all users.
+$ADMIN_USERS = Array(
+ 'js',
+ 'sw',
+ 'ws',
+ );
+
+$LANGUAGE = 'en';
+$LANGUAGE = 'de';
+
+$PASSWD_FILE = '/etc/passwd';
+$SHADOW_FILE = '/etc/shadow';
+$HTPASSWD_FILE = '.htpasswd';
+$HOME_PFX = '/home/';
+$USER_ID_MIN = 1000;
+$USER_ID_MAX = 60000;
+$SUDO_CMD = '/usr/bin/sudo';
+$SUDO_OPT_H = ' -H';
+$WRITE_TO_CMD = dirname(__FILE__) . '/write_to.sh';
+
+$VACATION_CMD = '/usr/bin/vacation';
+$VACATION_MSG_FILE = '.vacation.msg';
+$VACATION_DB_FILE = '.vacation.db';
+$VACATION_FORWARD_ENTRY = '"|/usr/bin/vacation %s"'; // use sprintf($VFE, $user);
+$FORWARD_FILE = '.forward';
+
+//
+// :ide-menu: Emacs IDE Menu - Buffer @BUFFER@
+// . M-x `eIDE-menu' ()(eIDE-menu "z")
+// :ide: COMPILE: PHP _DEBUG_=2 _DEBUG_TEST_=2
+// . (compile (concat "php " (file-name-nondirectory (buffer-file-name)) " _DEBUG_=2 _DEBUG_TEST_=2"))
+
+// :ide: QUO: $this->
+// . (insert "$this->" )
+
+// :ide: COMPILE: PHP w/o args
+// . (compile (concat "php " (file-name-nondirectory (buffer-file-name)) ""))
+
+// :ide: COMPILE: PHP _DEBUG_=1 _DEBUG_TEST_=1
+// . (compile (concat "php " (file-name-nondirectory (buffer-file-name)) " _DEBUG_=1 _DEBUG_TEST_=1"))
+
+//
+// Local Variables:
+// mode: php
+// End:
+?>
diff --git a/lib/gen_htpasswd.php b/lib/gen_htpasswd.php
new file mode 100644
--- /dev/null
+++ b/lib/gen_htpasswd.php
@@ -0,0 +1,46 @@
+
+// Sponsored by WIEDENMANN SEILE GMBH, http://www.wiedenmannseile.de
+//
+// This file is part of @Package@.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published
+// by the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see ,
+// or write to Wolfgang Scherer,
+
+// $_REQUEST['_DEBUG_'] = 1;
+require_once(dirname(__FILE__) . '/util.php');
+
+make_htpasswd();
+
+//
+// :ide-menu: Emacs IDE Menu - Buffer @BUFFER@
+// . M-x `eIDE-menu' ()(eIDE-menu "z")
+// :ide: COMPILE: PHP _DEBUG_=2 _DEBUG_TEST_=2
+// . (compile (concat "php " (file-name-nondirectory (buffer-file-name)) " _DEBUG_=2 _DEBUG_TEST_=2"))
+
+// :ide: QUO: $this->
+// . (insert "$this->" )
+
+// :ide: COMPILE: PHP w/o args
+// . (compile (concat "php " (file-name-nondirectory (buffer-file-name)) ""))
+
+// :ide: COMPILE: PHP _DEBUG_=1 _DEBUG_TEST_=1
+// . (compile (concat "php " (file-name-nondirectory (buffer-file-name)) " _DEBUG_=1 _DEBUG_TEST_=1"))
+
+//
+// Local Variables:
+// mode: php
+// End:
+?>
diff --git a/lib/language.php b/lib/language.php
new file mode 100644
--- /dev/null
+++ b/lib/language.php
@@ -0,0 +1,111 @@
+
+// Sponsored by WIEDENMANN SEILE GMBH, http://www.wiedenmannseile.de
+//
+// This file is part of Wiedenmann Vacation.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published
+// by the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see ,
+// or write to Wolfgang Scherer,
+
+// $_REQUEST['_DEBUG_'] = 1;
+
+$LC_LANGUAGES = Array(
+ 'en' => Array(
+ 'vacation' => 'Subject: Re: $SUBJECT
+
+I am currently not able to read mail.
+
+Your message has been forwarded to a co-worker for processing.
+',
+ 'error_no_subject' => 'error: subject is empty!',
+ 'error_no_user' => 'error: no user specified!',
+ 'error_unknown_user' => 'error: unkown user',
+
+ 'title' => 'Email Vacation Settings',
+ 'user' => 'User',
+ 'forward_to' => 'Forward To',
+ 'active' => 'Active',
+ 'none' => 'none',
+ 'subject' => 'Subject',
+ 'message' => 'Message',
+ 'explain_subject' =>
+ ' The expression'
+ .' $SUBJECT is replaced with the subject of the incoming message.',
+ 'refresh' => 'Refresh',
+ 'save' => 'Save',
+
+ 'reply_history_empty' => 'Autoreply History Is Empty',
+ 'reply_history' => 'Autoreply History',
+ 'delete' => 'Delete',
+
+ 'manual' => 'Manual',
+ 'manual_link' => 'doc/README.html',
+ // |:here:|
+ ),
+ 'de' => Array(
+ 'vacation' => 'Subject: Re: $SUBJECT
+
+Ich bin leider vorĂźbergehend nicht per Email erreichbar.
+
+Ihre Mail wird zur Bearbeitung an meine Vertretung weitergeleitet.
+',
+ 'error_no_subject' => 'Fehler: Betreff ist leer!',
+ 'error_no_user' => 'Fehler: Benutzer kann nicht ermittelt werden!',
+ 'error_unknown_user' => 'Fehler: unbekannter Benutzer',
+
+ 'title' => 'Email Urlaubseinstellungen',
+
+ 'user' => 'Benutzer',
+ 'forward_to' => 'Vertretung',
+ 'active' => 'Aktiv',
+ 'none' => 'niemand',
+ 'subject' => 'Betreff',
+ 'message' => 'Nachricht',
+ 'explain_subject' =>
+ ' Der Ausdruck'
+ .' $SUBJECT wird durch den Betreff der eingehenden Email'
+ .' ersetzt.',
+ 'refresh' => 'Neu einlesen',
+ 'save' => 'Speichern',
+
+ 'reply_history_empty' => 'Keine automatisch beantworteten Emails',
+ 'reply_history' => 'Automatisch Beantwortete Emails',
+ 'delete' => 'LĂśschen',
+
+ 'manual' => 'Anleitung',
+ 'manual_link' => 'doc/README-de.html',
+ // |:here:|
+ ),
+ );
+
+//
+// :ide-menu: Emacs IDE Menu - Buffer @BUFFER@
+// . M-x `eIDE-menu' ()(eIDE-menu "z")
+// :ide: COMPILE: PHP _DEBUG_=2 _DEBUG_TEST_=2
+// . (compile (concat "php " (file-name-nondirectory (buffer-file-name)) " _DEBUG_=2 _DEBUG_TEST_=2"))
+
+// :ide: QUO: $this->
+// . (insert "$this->" )
+
+// :ide: COMPILE: PHP w/o args
+// . (compile (concat "php " (file-name-nondirectory (buffer-file-name)) ""))
+
+// :ide: COMPILE: PHP _DEBUG_=1 _DEBUG_TEST_=1
+// . (compile (concat "php " (file-name-nondirectory (buffer-file-name)) " _DEBUG_=1 _DEBUG_TEST_=1"))
+
+//
+// Local Variables:
+// mode: php
+// End:
+?>
diff --git a/lib/snippets.pl b/lib/snippets.pl
new file mode 100755
--- /dev/null
+++ b/lib/snippets.pl
@@ -0,0 +1,8839 @@
+:
+#!/usr/bin/perl -w
+# ||<-snip->|| start
+# @hs@snippets - snippets administration tool@he@
+#
+# usage: snippets [OPTIONS] [COMMAND]@rb@
+# snh => snippets --help
+# snl => snippets --list [name-rx]
+# sni => snippets --as-includes
+# --list [name-rx]
+# sng => --grep [grep-opts]
+#
+# snc => snippets --cat [name-rx] | - [temp-snippet]
+# snr => snippets --replace --process
+# --cat [name-rx]
+# snn => snippets --new [filename [name]]
+#
+# sns => snippets --store [name] [text|file|url]
+# sna => snippets --append [name] [text|file|url]
+#
+# snw => snippets --work [work(1) args]
+# @contents@
+# @s@COMMON OPTIONS FOR ALL COMMANDS@eb@
+# --debug show debug messages
+# -q, --quiet suppress status messages.
+# -d, --dir directory set SNIPS_DIR to DIRETORY and prepend
+# it to SNIPS_PATH.
+# --accept-cat ACCEPT-RX accept categories matching RX.
+# -i, --ignore-cat IGNORE-RX ignore categories matching RX.
+# -m, --mode MODE setup parameters according to MODE.
+# -t, --title [TITLE] set @|title@ to `title`.
+# -u, --uuid [UUID] set @|uuid@ to `uuid`.
+# --main-only only use main mode category.
+
+# @s@COMMAND LIST@eb@
+# -l, --list [name-rx]@n@
+# list snippets matching NAME-RX@n@
+# OPTIONS@rb@
+# --as-includes list as snippets includes
+# --fn-sep [SEP] file name separator (default '#').
+#
+# @s@COMMAND GREP@eb@
+# -g, --grep [grep-opts]@n@
+# grep snippets with GREP-OPTS@n@
+# OPTIONS@rb@
+# --as-includes list as snippets includes
+
+# @s@COMMAND CAT@eb@
+# -c, --cat [name-rx] | - [temp-snippet]@n@
+# retrieve snippet matching NAME-RX or process temporary snippet
+# from command-line or standard input.@n@
+# OPTIONS@rb@
+# --all retrieve all snippets, not just the first match.
+# -r, --replace do standard replacements @|date@ ...
+# --no-replace do no standard replacements @|date@ ... (default)
+# -p, --process process commands
+# --no-process do not process commands (default)
+#
+# @s@COMMAND NEW@eb@
+# -n, --new [filename [name]]@n@
+# Retrieve snippet based on filename.
+# Implies --replace and --process.@n@
+# The filename extension determines the mode and the name.
+# the default name is _.@n@
+# OPTIONS@rb@
+# -f, --force overwrite existing output file.
+# -r, --replace do standard replacements @|date@ ... (default)
+# --no-replace do no standard replacements @|date@ ...
+# -p, --process process commands (default)
+# --no-process do not process commands
+#
+# @s@COMMON OPTIONS FOR CAT/NEW@eb@
+# --no-skip do not skip any sections, if not processing.
+# --no-indent do not add indent to lines. (Useful for --mark).
+# --no-final without final replacement (for further processing as snippet)
+# --mark[=NUM] mark snippet and included snippets.
+# (see section MARK FLAGS)
+# -k, --key [KEY] add/clear a replacement key. (deprecated) (implies --replace)
+# -v, --value [VALUE] set replacement value for last added key.
+# --verbose show full snippets.
+
+# @s@COMMAND STORE@eb@
+# -s, --store [name] [text|file|url]@n@
+# store text/file/url as snippet.@n@
+# OPTIONS@rb@
+# -f, --force overwrite existing snippet for --store.
+#
+# @s@COMMAND APPEND@eb@
+# -a, --append [name] [text|file|url]@n@
+# append or store text/file/url as snippet.
+#
+# @s@COMMON OPTIONS FOR STORE/APPEND@eb@
+# --literal do not quote snippet tags
+# --use-both use both header and footer from snippet text
+# --use-header use header from snippet text
+# --use-footer use footer from snippet text
+
+# @s@COMMAND WORK@eb@
+# -w, --work [work(1) arguments]@n@
+# change working directory to $SNIPS_DIR and run work(1) with
+# arguments.
+
+# @s@COMMAND INSTALL@eb@
+# --install [bin_dir] # default: /usr/local/bin
+#
+# @s@COMMAND DIST@eb@
+# --dist [dist_dir] # default: /srv/ftp/pub
+
+# @s@MARK FLAGS@eb@
+# 0 000 => no marking, unless processing
+# 1 001 => mark tagged, if processing
+# 2 010 => mark untagged, if processing
+# 3 011 => mark both, if processing
+# 4 100 => forced marking
+# 5 101 => always mark tagged
+# 6 110 => always mark untagged
+# 7 111 => always mark both
+
+# @s@SNIPPET FILE NAMES@e@
+# The snippet category is determined as the substring before the
+# first underscore.
+#
+# If no mode is specified for a snippet, the prefix category is used
+# as such.
+#
+# If a supplied snippet name for storage does not have a category,
+# the current mode is automatically prepended.
+#
+# In order to allow for an optional sub-category / name scheme, the
+# first dot is used separate categories and name. This allows for
+# underscores to appear in a name part after the dot, without
+# implying a category::
+#
+# `_` [ `.` ]
+#
+# The sub-category is just a suggestion and has no special meaning
+# for snippets(1).
+#
+# The dot-separator is only used to determine the end of substring,
+# where snippets(1) looks for an underscore. It is entirely optional
+# and has no other special meaning.
+
+# @s@|@fempty@|<-snap->|| HANDLERS@eb@
+# - capture on | off | clear | get | drop
+# drop == clear + off
+#
+# - debug NUM
+# set debug level to NUM
+#
+# - show [ [[[!]final] replacement] ... ]
+# show current value of replacement
+#
+# - alias alias_name command_handler
+# define alias_name to behave as command_handler.@rb@
+
+# - start comment
+# start snippet
+#
+# - stop comment
+# stop snippet
+#
+# - title title
+# Not processed
+#
+# - uuid uuid
+# Not processed@rb@
+
+# - mark [text]
+# without `text`, a timestamp is used for the mark
+#
+# - beg
+# see option --mark
+#
+# - end
+# see option --mark@rb@
+
+# - indent [+-]NUM
+# set indent to NUM. If `+` or `-` is given, increase or decrease indent respectively.
+# Option --no-indent suppresses indents.@rb@
+
+# - rem [text]
+# text is ignored, the tag is removed
+#
+# - trim left|right|all
+# accumulated text is trimmed. `all` is the default.
+#
+# - drop
+# accumulated text is dropped.
+#
+# - quote text
+# `text` is inserted verbatim without replacement or processing
+#
+# - todo comment
+# add TODO entry@rb@
+
+# - undef key
+# undefine @|key@
+#
+# - define key [['!']'default'] [['!']'final']
+# [['!']'unquote'] [['!']'replace'] [['!']'process']
+# start/stop defining replacement for @|key@.
+#
+# - If `default` is specified, only set replacement, if it not yet
+# defined.
+# - If `final` is specified, set a replacement for final
+# replacement pass.
+# - If `unquote` is specified, remove one level of quoting from
+# replacements. before replacing.
+# - If `replace` is specified, substitute current replacements
+# before definition.
+# - If `process` is specified, the collected replacement text is
+# processed (default is the global processing status).
+#
+# - default key value
+# If replacing is enabled, set @|key@ replacement to `value`, if
+# it is not yet defined. One level of quoting is removed from
+# `value`.
+#
+# - subst key value
+# If replacing is enabled, set @|key@ replacement to `value`. One
+# level of quoting is removed from `value`.
+#
+# - final key value
+# If replacing is enabled, set @|key@ replacement to `value` for
+# final replacement after comment cleanup. One level of quoting is
+# removed from `value`.@rb@
+
+# - verbatim
+# begin/end verbatim block
+#
+# - snip
+# begin/end block
+#
+# - snap
+# begin/end block
+#
+# - read
+#
+# - include file-rx [accept cat-accept-rx] [ignore cat-ignore-rx] \
+# [[!]process] [[!]skip] \
+# [[!]replace] [[!]export] [[!]import] \
+# [key=value ...] [-key]
+#
+# include file matching FILE-RX.
+#
+# See section 'INCLUDE FILE RX REPLACEMENTS' below for FILE-RX
+# quoting.
+#
+# - if PROCESS is given, turn processing on/off as
+# specified. default: global processing flag.
+# - if SKIP is given, set skipping, if not processing, to
+# always/never as specified. default: global no_skip flag.
+# - if REPLACE is given, turn replacing on/off as
+# specified. default: global replace flag.
+# - if IMPORT is given, keep/restore replacements defined in
+# include file as specified. default: on.
+# - ACCEPT. default: global --accept-cat option. !ACCEPT == IGNORE
+# - INGORE. default: global --ignore-cat option. !IGNORE == ACCEPT@rb@
+
+# - exec [[!]dump] [[!]process] [[!]skip] [[!]autostart] \
+# [[!]replace] [[!]export] [[!]import] \
+# [sprocess] [sreplace] [sunquote] \
+# [key=value ...] [-key]
+# sh(1)-cmd
+# ...
+# exec
+#
+# get text from output of sh(1)-cmd. The result is processed as
+# snippets text.
+#
+# - if DUMP is given, the shell command output is not processed in
+# any way. This avoids end-of-line trimming, which would messs
+# up binary data.
+#
+# - if SUNQUOTE is given, the shell script is unquoted after
+# processing and replacing, but before execution.
+#
+# - shellq sh(1)-cmd
+# get text from output of sh(1)-cmd. The result is not further
+# processed.
+#
+# - shell sh(1)-cmd
+# get text from output of sh(1)-cmd. The result is processed as
+# snippet.@rb@
+
+# - skip [`keep`]
+# start/stop skipping. If keep is specified, only drop section
+# when processing@rb@
+
+# - if [[!]final] [!]defined key
+# include section up to next `elif/else/fi`, only if condition is true.
+#
+# - if [[!]final] [!]eq key value
+# include section up to next `elif/else/fi`, only if condition is true.
+#
+# - elif [[!]final] { [!]defined key | [!]eq key value }
+# include section up to next `elif/else/fi`, only if no if/elif
+# was included before and if condition is true.
+#
+# - else
+# include section up to next `fi`, if no if/elif was included before.
+#
+# - fi
+# terminate if/elif/else/fi block.
+
+# @s@SPECIAL SKIP HANDLERS@e@
+
+# If a snippet is retrieved for snippets internal use::
+#
+# for_snips => [quote]
+# not_for_snips => [skip]
+
+# If a snippet is retrieved for external use::
+#
+# for_snips => [skip]
+# not_for_snips => [quote]
+
+# @s@DEPRECATED HANDLERS@eb@
+# - evalq text
+# deprecated for portability.
+# perl(1) eval of `text`. The result is not further processed.
+#
+# - eval text
+# deprecated for portability.
+# perl(1) eval of `text`. The result is processed as snippets
+# text.
+
+# @s@SNIPPET TAG QUOTING@e@
+# Snippet tags are only recognized at the beginning of a line,
+# optionally proceeded by a comment start skip. Therefore, snippet
+# tags within a line do not need to be quoted. Other snippet tags
+# can be quoted through the final replacement mechanism. E.g.::
+#
+# ;; |@|fempty@|<-snap->||
+#
+# results in::
+#
+# ;; ||<-snap->||
+#
+# and still allows symbol tag navigation with the reduced delimiter
+# set `("|<-" . "->|")`.
+
+# @s@REPLACEMENT QUOTING@eb@
+# The first `|` after an `@` is removed in the final pass:
+#
+# @||quoted@ => @|quoted@
+# @|||quoted@ => @||quoted@
+# @||||quoted@ => @|||quoted@
+#
+# This also allows for quoting of the generic comment syntax::
+#
+# @||:comm@ => @|:comm@
+
+# @s@STANDARD REPLACEMENTS@eb@
+# @|mode@ => [text]
+
+# @|empty@ => []
+# @|space@ => [ ]
+# @|nl@ =>
+
+# @|filename@ => if output filename is applicable
+# @|filebase@ => if output filename is applicable
+
+# @|dts@ => [2011-11-29 22:57:08]
+# @|sts@ => [1322603828]
+
+# @|date@ => [2011-11-29]
+# @|time@ => [22:57:08]
+
+# @|year@ => [2011]
+# @|month@ => [11]
+# @|day@ => [29]
+# @|hours@ => [22]
+# @|minutes@ => [57]
+# @|seconds@ => [08]
+
+# @|:_comm@ => sep + comment-end
+# @|:comm@ => comment-start
+# @|:comm_@ => comment-start + sep
+# @|:comm_line@ => [@|:comm@@|_comm@]
+# @|:comme@ => comment-end
+
+# @|:bcomm@ => block-comment-start
+# @|:bcomme@ => block-comment-end
+# @|:bcomm_@ => block-comment-start + sep
+# @|:_bcomm@ => sep + block-comment-end
+
+# @|:lcomm@ => line comment within block-comment
+# @|:lcomm_@ => line comment within block-comment + sep
+
+# @s@FINAL REPLACEMENTS@eb@
+# @|fempty@ => []
+# @|fspace@ => [ ]
+# @|fnl@ =>
+
+# @s@SPECIAL REPLACEMENTS@eb@
+# @|snip_mode@ => the current snippet mode, which is not necessarily the same as the emacs mode.
+# @|snip_self@ => the current snippet file
+# @|snip_selfi@ => the current snippet file, quoted for `include` command.
+# @|snip_selfq@ => the current snippet file, quoted for shell
+# @|snip_self_dir@ => the current snippet file
+# @|snip_self_diri@ => the current snippet file, quoted for `include` command.
+# @|snip_self_dirq@ => the current snippet file, quoted for shell
+# @|snip_self_base@ => the current snippet file
+# @|snip_self_basei@ => the current snippet file, quoted for `include` command.
+# @|snip_self_baseq@ => the current snippet file, quoted for shell
+
+# @s@COMMAND LINE SUBSTITUTION HANDLING@e@
+# 1. `snips_process_line__` replaces entire command line::@n@
+# |@fempty@|<-snap->|| @|command@ opt=@||val@ opt2=@|||val2@
+# =>
+# |@fempty@|<-snap->|| replaced opt=@||val@ opt2=@|||val2@
+#
+# 2. `subst` command removes one level of quoting::@n@
+# |@fempty@|<-snap->|| replaced opt=@||val@ opt2=@|||val2@
+# =>
+# |@fempty@|<-snap->|| replaced opt=@|val@ opt2=@||val2@
+#
+# 3. `subst` command splits option arguments into key/value pairs::@n@
+# |@fempty@|<-snap->|| replaced opt=@|val@ opt2=@||val2@
+# =>
+# [[ opt, @|val@ ], [ opt2, @||val2@ ]]
+#
+# 4. `subst` command replaces values::@n@
+# [[ opt, @|val@ ] [ opt2, @||val2@ ]]
+# =>
+# [[ opt, replaced ], [ opt2, @||val2@ ]]
+#
+# 5. `subst` command removes another level of quotes::@n@
+# [[ opt, replaced ], [ opt2, @||val2@ ]]
+# =>
+# [[ opt, replaced ], [ opt2, @|val2@ ]]
+
+# @s@INCLUDE FILE RX REPLACEMENTS@e@
+# The first level of quotes is removed on FILE-RX and the
+# appropriate replacements are filled in. Then, another level of
+# quotes is removed. This works exactly like the `subst` command.
+#
+# If you wish to match a filename with a valid replacement in it,
+# you must double-quote it (e.g. `@|||space@`), or use other means
+# like @\|match@ or `@[m]atch@`.
+#
+# The following replacements are defined as defaults (i.e., if they
+# are not yet defined) when replacing the first quote level of an
+# `include` file regexp::
+#
+# @|snip_fn_space@ => ` `
+# @|snip_fn_tab@ => `\t`
+# @|snip_fn_cr@ => `\r`
+# @|snip_fn_nl@ => `\n`
+
+# @s@CONFIGURATION@e@
+# SNIPS_PATH is taken from the environment variable `SNIPS_PATH`. If
+# the variable is not set, `${HOME}/snippets` is used.
+#
+# SNIPS_DIR is then taken from the environment variable
+# `SNIPS_DIR`. If the variable is not set, the first element of
+# SNIPS_PATH is used.
+#
+# All directories named `.snippets` going up from the current
+# directory to the root level are prepended to SNIPS_PATH in reverse
+# order. I.e., the `.snippets` directory in the current working
+# directory takes highest precedence.
+#
+# SNIPS_PATH is searched for `snip_setup`. The first occurence
+# found is processed. Any resulting text is discarded.
+#
+# SNIPS_PATH is then searched in reverse order for all files named
+# `.snips.rc`, which are all processed. Any resulting text is
+# discarded.
+#
+# It is really intended to process `snip_setup` and `.snips.rc`
+# before option processing. However, this still remains ``|:todo:|``.
+#
+# The configuration processing is mainly useful to define
+# replacements. But can also be used with the `exec` mechanism to
+# create directories, files and the like.
+
+# @s@ENVIRONMENT@eb@
+# SNIPS_PATH is searched for snippets
+# SNIPS_PATH="${SNIPS_PATH-${HOME}/snippets}"
+#
+# SNIPS_DIR is used to store snippets
+# SNIPS_DIR="${SNIPS_DIR-first element of SNIPS_PATH}"
+#
+# SNIPS_MODE is the default mode to be used.
+#
+# SNIPS_CAT is the default category (rx) to be used.
+#
+# SNIPS_COMMENT_START
+#
+# SNIPS_COMMENT_START_SKIP
+#
+# SNIPS_COMMENT_END
+#
+# SNIPS_COMMENT_END_SKIP
+#
+# SNIPS_COMMENT_START_SEP
+#
+# SNIPS_COMMENT_END_SEP
+#
+# ||<-snap->|| if !defined min_mode
+# Copyright (C) 2010, 2011, 2012 Wolfgang Scherer, Sudetenstr. 48,
+# D-97340 Marktbreit,
+# ||<-snap->|| fi
+# ||<-snap->|| skip
+eval 'exec perl -w -S $0 ${1+"$@"}'
+if 0;
+#
+# This file is part of Snippets.
+#
+# Snippets is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or (at
+# your option) any later version.
+#
+# Snippets is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public
+# License along with Snippets; see the file COPYING. If not,
+# write to Wolfgang Scherer, Sudetenstr. 48, D-97340
+# Marktbreit, or the Free Software Foundation, Inc., 59 Temple
+# Place, Suite 330, Boston, MA 02111-1307, USA.
+# ||<-snap->|| skip
+# ||<-snip->|| stop
+
+# Handle -?, -h, --help
+sub usage {
+ local ( *HANDLE ) = shift;
+ my $rst_format = shift || 0;
+ my $min_format = shift || 0;
+ my $opts = shift || '';
+ my $programq = sqe($0);
+ $programq = snip_quote_file($0);
+
+ my $define = 'undef';
+ if ($rst_format) {
+ $define = 'subst';
+ }
+
+ my $mindef = 'undef';
+ if ($min_format) {
+ $mindef = 'subst';
+ }
+
+ my $script = "
+|"."|<-snip->|| start
+||<-snap->|| define n
+\@nl@#
+||<-snap->|| define
+||<-snap->|| ${define} rst_mode
+||<-snap->|| ${mindef} min_mode
+||<-snip->|| if !defined rst_mode
+||<-snap->|| define rb
+
+\@empty@
+||<-snap->|| define
+||<-snap->|| define s
+||<-snap->|| define
+||<-snap->|| define e
+\@rb@
+||<-snap->|| define
+||<-snap->|| define eb
+\@rb@
+||<-snap->|| define
+||<-snap->|| define hs
+||<-snap->|| define
+||<-snap->|| define he
+||<-snap->|| define
+||<-snap->|| subst contents
+||<-snap->|| fi
+||<-snip->|| if defined rst_mode
+||<-snap->|| define rb
+
+#
+# ::
+#
+\@empty\@
+||<-snap->|| define
+||<-snap->|| define s
+--------------------------------------------------
+# \@empty@
+||<-snap->|| define
+||<-snap->|| define e
+
+# --------------------------------------------------
+||<-snap->|| define
+||<-snap->|| define eb
+\@e@\@rb@
+||<-snap->|| define
+||<-snap->|| define contents
+
+# .. contents::
+#
+||<-snap->|| define
+||<-snap->|| define hs
+==================================================
+# \@empty@
+||<-snap->|| define
+||<-snap->|| define he
+
+# ==================================================
+||<-snap->|| define
+||<-snip->|| drop
+||<-snap->|| fi
+||<-snap->|| if defined min_mode
+||<-snap->|| subst contents
+||<-snap->|| fi
+||<-snap->|| include $programq
+|"."|<-snip->|| stop
+";
+
+ my $cmd = "printf '%s\\n' ".sqe($script)." | $0 --process --replace --mode pl ".$opts." --cat - |";
+ open ( SELF, $cmd );
+ while ( ) {
+ if ( m/^#!|^:/so ) {
+ next;
+ }
+ if ( ! m/^#|^[ \t]*$/so ) {
+ last;
+ }
+ s,^# ?,,so;
+ printf HANDLE ( "%s", $_ );
+ }
+}
+
+use vars qw( $prog_name $bin_dir $inst_dir );
+use vars qw($msg_output);
+
+BEGIN {
+ $msg_output = *STDERR;
+ $bin_dir = '.';
+ $0 =~ m,^(.*)/(.*)$,so;
+ $bin_dir = $1 if $1;
+ $prog_name = 'snippets';
+ $prog_name = $2 if $2;
+ unshift ( @INC, $bin_dir );
+ $inst_dir = $bin_dir;
+ my $l = readlink ( $0 );
+ if ( $l ) {
+ if ( $l !~ m,/,so) {
+ # $prog_name = $l;
+ } elsif ( $l =~ m,^(.*)/(.*)$,so && $1 ) {
+ $inst_dir = $1;
+ $prog_name = $2;
+ $l =~ m,^(/),so;
+ $inst_dir = $bin_dir.'/'.$inst_dir if !$1;
+ unshift ( @INC, $inst_dir );
+ }
+ }
+}
+
+# make UUID::Tiny compatible with `use strict`
+use vars qw(
+ *UUID::Tiny::equal_UUIDs
+ *UUID::Tiny::clk_seq_of_UUID
+ *UUID::Tiny::clk_seq_of_UUID
+ *UUID::Tiny::create_UUID_as_string
+ *UUID::Tiny::create_UUID
+ *UUID::Tiny::string_to_UUID
+ *UUID::Tiny::version_of_UUID
+ *UUID::Tiny::time_of_UUID
+ *UUID::Tiny::UUID_to_string
+ *UUID::Tiny::is_UUID_string
+ );
+
+# THE FOLLOWING MODULE IS COPIED FROM ITS ORIGINAL SOURCE AS IS AND
+# THEREFORE IS NOT COVERED BY THE COPYRIGHT NOTICE AT THE BEGINNING OF
+# THE FILE.
+# vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
+package UUID::Tiny;
+
+use 5.008;
+use warnings;
+use strict;
+use Carp;
+use Digest::MD5;
+use MIME::Base64;
+use Time::HiRes;
+use POSIX;
+
+our $SHA1_CALCULATOR = undef;
+
+{
+ # Check for availability of SHA-1 ...
+ local $@; # don't leak an error condition
+ eval { require Digest::SHA; $SHA1_CALCULATOR = Digest::SHA->new(1) } ||
+ eval { require Digest::SHA1; $SHA1_CALCULATOR = Digest::SHA1->new() } ||
+ eval {
+ require Digest::SHA::PurePerl;
+ $SHA1_CALCULATOR = Digest::SHA::PurePerl->new(1)
+ };
+};
+
+our $MD5_CALCULATOR = Digest::MD5->new();
+
+# ToDo:
+# - Check and report for undefined UUIDs with all UUID manipulating functions!
+# - Better error propagation for better debugging.
+
+=head1 NAME
+
+UUID::Tiny - Pure Perl UUID Support With Functional Interface
+
+=head1 VERSION
+
+Version 1.03
+
+=cut
+
+our $VERSION = '1.03';
+
+=head1 SYNOPSIS
+
+Create version 1, 3, 4 and 5 UUIDs:
+
+ use UUID::Tiny;
+
+ my $v1_mc_UUID = create_UUID();
+ my $v3_md5_UUID = create_UUID(UUID_V3, $str);
+ my $v3_md5_UUID = create_UUID(UUID_V3, UUID_NS_DNS, 'caugustin.de');
+ my $v4_rand_UUID = create_UUID(UUID_V4);
+ my $v5_sha1_UUID = create_UUID(UUID_V5, $str);
+ my $v5_with_NS_UUID = create_UUID(UUID_V5, UUID_NS_DNS, 'caugustin.de');
+
+ my $v1_mc_UUID_string = create_UUID_as_string(UUID_V1);
+ my $v3_md5_UUID_string = UUID_to_string($v3_md5_UUID);
+
+ if ( version_of_UUID($v1_mc_UUID) == 1 ) { ... };
+ if ( version_of_UUID($v5_sha1_UUID) == 5 ) { ... };
+ if ( is_UUID_string($v1_mc_UUID_string) ) { ... };
+ if ( equal_UUIDs($uuid1, $uuid2) ) { ... };
+
+ my $uuid_time = time_of_UUID($v1_mc_UUID);
+ my $uuid_clk_seq = clk_seq_of_UUID($v1_mc_UUID);
+
+=cut
+
+=head1 DESCRIPTION
+
+UUID::Tiny is a lightweight, low dependency Pure Perl module for UUID
+creation and testing. This module provides the creation of version 1 time
+based UUIDs (using random multicast MAC addresses), version 3 MD5 based UUIDs,
+version 4 random UUIDs, and version 5 SHA-1 based UUIDs.
+
+ATTENTION! UUID::Tiny uses Perl's C to create the basic random
+numbers, so the created v4 UUIDs are B cryptographically strong!
+
+No fancy OO interface, no plethora of different UUID representation formats
+and transformations - just string and binary. Conversion, test and time
+functions equally accept UUIDs and UUID strings, so don't bother to convert
+UUIDs for them!
+
+All constants and public functions are exported by default, because if you
+didn't need/want them, you wouldn't use this module ...
+
+UUID::Tiny deliberately uses a minimal functional interface for UUID creation
+(and conversion/testing), because in this case OO looks like overkill to me
+and makes the creation and use of UUIDs unnecessarily complicated.
+
+If you need raw performance for UUID creation, or the real MAC address in
+version 1 UUIDs, or an OO interface, and if you can afford module compilation
+and installation on the target system, then better look at other CPAN UUID
+modules like L.
+
+This module is "fork safe", especially for random UUIDs (it works around
+Perl's rand() problem when forking processes).
+
+This module should be "thread safe," because its global variables
+are locked in the functions that access them. (Not tested - if you can provide
+some tests, please tell me!)
+
+=cut
+
+=head1 DEPENDENCIES
+
+This module should run from Perl 5.8 up and uses mostly standard (5.8 core)
+modules for its job. No compilation or installation required. These are the
+modules UUID::Tiny depends on:
+
+ Carp
+ Digest::MD5 Perl 5.8 core
+ Digest::SHA Perl 5.10 core (or Digest::SHA1, or Digest::SHA::PurePerl)
+ MIME::Base64 Perl 5.8 core
+ Time::HiRes Perl 5.8 core
+ POSIX Perl 5.8 core
+
+If you are using this module on a Perl prior to 5.10 and you don't have
+Digest::SHA1 installed, you can use Digest::SHA::PurePerl instead.
+
+=cut
+
+=head1 ATTENTION! NEW STANDARD INTERFACE (IN PREPARATION FOR V2.00)
+
+After some debate I'm convinced that it is more Perlish (and far easier to
+write) to use all-lowercase function names - without exceptions. And that it
+is more polite to export symbols only on demand.
+
+While the 1.0x versions will continue to export the old, "legacy" interface on
+default, the future standard interface is available using the C<:std> tag on
+import from version 1.02 on:
+
+ use UUID::Tiny ':std';
+ my $md5_uuid = create_uuid(UUID_MD5, $str);
+
+In preparation for the upcoming version 2.00 of UUID::Tiny you should use the
+C<:legacy> tag if you want to stay with the version 1.0x interface:
+
+ use UUID::Tiny ':legacy';
+ my $md5_uuid = create_UUID(UUID_V3, $str);
+
+=cut
+
+use Exporter;
+our @ISA = qw(Exporter);
+our @EXPORT;
+our @EXPORT_OK;
+our %EXPORT_TAGS = (
+ std => [qw(
+ UUID_NIL
+ UUID_NS_DNS UUID_NS_URL UUID_NS_OID UUID_NS_X500
+ UUID_V1 UUID_TIME
+ UUID_V3 UUID_MD5
+ UUID_V4 UUID_RANDOM
+ UUID_V5 UUID_SHA1
+ UUID_SHA1_AVAIL
+ create_uuid create_uuid_as_string
+ is_uuid_string
+ uuid_to_string string_to_uuid
+ version_of_uuid time_of_uuid clk_seq_of_uuid
+ equal_uuids
+ )],
+ legacy => [qw(
+ UUID_NIL
+ UUID_NS_DNS UUID_NS_URL UUID_NS_OID UUID_NS_X500
+ UUID_V1
+ UUID_V3
+ UUID_V4
+ UUID_V5
+ UUID_SHA1_AVAIL
+ create_UUID create_UUID_as_string
+ is_UUID_string
+ UUID_to_string string_to_UUID
+ version_of_UUID time_of_UUID clk_seq_of_UUID
+ equal_UUIDs
+ )],
+);
+
+Exporter::export_tags('legacy');
+Exporter::export_ok_tags('std');
+
+=head1 CONSTANTS
+
+=cut
+
+=over 4
+
+=item B
+
+This module provides the NIL UUID (shown with its string representation):
+
+ UUID_NIL: '00000000-0000-0000-0000-000000000000'
+
+=cut
+
+use constant UUID_NIL => "\x00" x 16;
+
+=item B
+
+This module provides the common pre-defined namespace UUIDs (shown with their
+string representation):
+
+ UUID_NS_DNS: '6ba7b810-9dad-11d1-80b4-00c04fd430c8'
+ UUID_NS_URL: '6ba7b811-9dad-11d1-80b4-00c04fd430c8'
+ UUID_NS_OID: '6ba7b812-9dad-11d1-80b4-00c04fd430c8'
+ UUID_NS_X500: '6ba7b814-9dad-11d1-80b4-00c04fd430c8'
+
+=cut
+
+use constant UUID_NS_DNS =>
+ "\x6b\xa7\xb8\x10\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8";
+use constant UUID_NS_URL =>
+ "\x6b\xa7\xb8\x11\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8";
+use constant UUID_NS_OID =>
+ "\x6b\xa7\xb8\x12\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8";
+use constant UUID_NS_X500 =>
+ "\x6b\xa7\xb8\x14\x9d\xad\x11\xd1\x80\xb4\x00\xc0\x4f\xd4\x30\xc8";
+
+=item B
+
+This module provides the UUID version numbers as constants:
+
+ UUID_V1
+ UUID_V3
+ UUID_V4
+ UUID_V5
+
+With C