doc: migrated to sphinx

This commit is contained in:
gwen 2012-11-20 17:14:58 +01:00
parent 60ef6cc2b4
commit 79cf82e328
45 changed files with 426 additions and 4118 deletions

View File

@ -1,23 +1,153 @@
SRC=$(wildcard *.txt)
HTMLFRAGMENT=$(addsuffix .html, $(basename $(SRC)))
# Makefile for Sphinx documentation
#
.SUFFIXES:
# You can set these variables from the command line.
SPHINXOPTS =
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = _build
.PHONY: all clean
# Internal variables.
PAPEROPT_a4 = -D latex_paper_size=a4
PAPEROPT_letter = -D latex_paper_size=letter
ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
# the i18n builder cannot share the environment and doctrees with the others
I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
all: html code
# make -C ./build/code all
# make -C ./build/test all
# make -C ./build all
html: $(HTMLFRAGMENT)
.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext
%.html: %.txt
./rst2html.py --stylesheet ./build/style.css $< > ./build/$@
code:
./code2html
help:
@echo "Please use \`make <target>' where <target> is one of"
@echo " html to make standalone HTML files"
@echo " dirhtml to make HTML files named index.html in directories"
@echo " singlehtml to make a single large HTML file"
@echo " pickle to make pickle files"
@echo " json to make JSON files"
@echo " htmlhelp to make HTML files and a HTML help project"
@echo " qthelp to make HTML files and a qthelp project"
@echo " devhelp to make HTML files and a Devhelp project"
@echo " epub to make an epub"
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
@echo " latexpdf to make LaTeX files and run them through pdflatex"
@echo " text to make text files"
@echo " man to make manual pages"
@echo " texinfo to make Texinfo files"
@echo " info to make Texinfo files and run them through makeinfo"
@echo " gettext to make PO message catalogs"
@echo " changes to make an overview of all changed/added/deprecated items"
@echo " linkcheck to check all external links for integrity"
@echo " doctest to run all doctests embedded in the documentation (if enabled)"
clean:
make -C ./build clean
-rm -rf $(BUILDDIR)/*
html:
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
dirhtml:
$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
@echo
@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
singlehtml:
$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
@echo
@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
pickle:
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
@echo
@echo "Build finished; now you can process the pickle files."
json:
$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
@echo
@echo "Build finished; now you can process the JSON files."
htmlhelp:
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
@echo
@echo "Build finished; now you can run HTML Help Workshop with the" \
".hhp project file in $(BUILDDIR)/htmlhelp."
qthelp:
$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
@echo
@echo "Build finished; now you can run "qcollectiongenerator" with the" \
".qhcp project file in $(BUILDDIR)/qthelp, like this:"
@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/tiramisu.qhcp"
@echo "To view the help file:"
@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/tiramisu.qhc"
devhelp:
$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
@echo
@echo "Build finished."
@echo "To view the help file:"
@echo "# mkdir -p $$HOME/.local/share/devhelp/tiramisu"
@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/tiramisu"
@echo "# devhelp"
epub:
$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
@echo
@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
latex:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo
@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
@echo "Run \`make' in that directory to run these through (pdf)latex" \
"(use \`make latexpdf' here to do that automatically)."
latexpdf:
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
@echo "Running LaTeX files through pdflatex..."
$(MAKE) -C $(BUILDDIR)/latex all-pdf
@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
text:
$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
@echo
@echo "Build finished. The text files are in $(BUILDDIR)/text."
man:
$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
@echo
@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
texinfo:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo
@echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo."
@echo "Run \`make' in that directory to run these through makeinfo" \
"(use \`make info' here to do that automatically)."
info:
$(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo
@echo "Running Texinfo files through makeinfo..."
make -C $(BUILDDIR)/texinfo info
@echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo."
gettext:
$(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale
@echo
@echo "Build finished. The message catalogs are in $(BUILDDIR)/locale."
changes:
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
@echo
@echo "The overview file is in $(BUILDDIR)/changes."
linkcheck:
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
@echo
@echo "Link check complete; look for any errors in the above output " \
"or in $(BUILDDIR)/linkcheck/output.txt."
doctest:
$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
@echo "Testing of doctests in the sources finished, look at the " \
"results in $(BUILDDIR)/doctest/output.txt."

7
doc/build/Makefile vendored
View File

@ -1,7 +0,0 @@
.PHONY: clean
.SUFFIXES:
clean:
rm -f *.html
rm -f api/*.html
make -C ./pydoc/ clean

View File

@ -1 +0,0 @@
API's directory

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.3 KiB

1080
doc/build/default.css vendored
View File

@ -1,1080 +0,0 @@
body,body.editor,body.body {
font: 110% "Times New Roman", Arial, Verdana, Helvetica, serif;
background: White;
color: Black;
}
a, a.reference {
text-decoration: none;
}
a[href]:hover { text-decoration: underline; }
img {
border: none;
vertical-align: middle;
}
p, div.text {
text-align: left;
line-height: 1.5em;
margin: 0.5em 0em 0em 0em;
}
p a:active {
color: Red;
background-color: transparent;
}
p img {
border: 0;
margin: 0;
}
img.inlinephoto {
padding: 0;
padding-right: 1em;
padding-top: 0.7em;
float: left;
}
hr {
clear: both;
height: 1px;
color: #8CACBB;
background-color: transparent;
}
ul {
line-height: 1.5em;
/*list-style-image: url("bullet.gif"); */
margin-left: 1.5em;
padding:0;
}
ol {
line-height: 1.5em;
margin-left: 1.5em;
padding:0;
}
ul a, ol a {
text-decoration: underline;
}
dl {
}
dt {
font-weight: bold;
}
dd {
line-height: 1.5em;
margin-bottom: 1em;
}
blockquote {
font-family: Times, "Times New Roman", serif;
font-style: italic;
font-size: 120%;
}
code {
color: Black;
/*background-color: #dee7ec;*/
background-color: #cccccc;
}
pre {
padding: 1em;
border: 1px solid #8cacbb;
color: Black;
background-color: #dee7ec;
background-color: #cccccc;
overflow: auto;
}
.netscape4 {
display: none;
}
/* main page styles */
/*a[href]:hover { color: black; text-decoration: underline; }
a[href]:link { color: black; text-decoration: underline; }
a[href] { color: black; text-decoration: underline; }
*/
span.menu_selected {
color: black;
font: 140% Verdana, Helvetica, Arial, sans-serif;
text-decoration: none;
padding-right: 0.3em;
background-color: #cccccc;
}
a.menu {
/*color: #3ba6ec; */
font: 140% Verdana, Helvetica, Arial, sans-serif;
text-decoration: none;
padding-right: 0.3em;
}
a.menu[href]:visited, a.menu[href]:link{
/*color: #3ba6ec; */
font: 140% Verdana, Helvetica, Arial, sans-serif;
text-decoration: none;
}
a.menu[href]:hover {
/*color: black;*/
}
div.project_title{
/*border-spacing: 20px;*/
font: 160% Verdana, Helvetica, Arial, sans-serif;
color: #3ba6ec;
vertical-align: middle;
padding-bottom: 0.3em;
}
a.wikicurrent {
font: 100% Verdana, Helvetica, Arial, sans-serif;
color: #3ba6ec;
vertical-align: middle;
}
table.body {
border: 0;
/*padding: 0;
border-spacing: 0px;
border-collapse: separate;
*/
}
td.page-header-left {
padding: 5px;
/*border-bottom: 1px solid #444444;*/
}
td.page-header-top {
padding: 0;
/*border-bottom: 1px solid #444444;*/
}
td.sidebar {
padding: 1 0 0 1;
}
td.sidebar p.classblock {
padding: 0 5 0 5;
margin: 1 1 1 1;
border: 1px solid #444444;
background-color: #eeeeee;
}
td.sidebar p.userblock {
padding: 0 5 0 5;
margin: 1 1 1 1;
border: 1px solid #444444;
background-color: #eeeeff;
}
td.content {
padding: 1 5 1 5;
vertical-align: top;
width: 100%;
}
p.ok-message {
background-color: #22bb22;
padding: 5 5 5 5;
color: white;
font-weight: bold;
}
p.error-message {
background-color: #bb2222;
padding: 5 5 5 5;
color: white;
font-weight: bold;
}
p:first-child {
margin: 0 ;
padding: 0;
}
/* style for forms */
table.form {
padding: 2;
border-spacing: 0px;
border-collapse: separate;
}
table.form th {
color: #333388;
text-align: right;
vertical-align: top;
font-weight: normal;
}
table.form th.header {
font-weight: bold;
background-color: #eeeeff;
text-align: left;
}
table.form th.required {
font-weight: bold;
}
table.form td {
color: #333333;
empty-cells: show;
vertical-align: top;
}
table.form td.optional {
font-weight: bold;
font-style: italic;
}
table.form td.html {
color: #777777;
}
/* style for lists */
table.list {
border-spacing: 0px;
border-collapse: separate;
vertical-align: top;
padding-top: 0;
width: 100%;
}
table.list th {
padding: 0 4 0 4;
color: #404070;
background-color: #eeeeff;
border-right: 1px solid #404070;
border-top: 1px solid #404070;
border-bottom: 1px solid #404070;
vertical-align: top;
empty-cells: show;
}
table.list th a[href]:hover { color: #404070 }
table.list th a[href]:link { color: #404070 }
table.list th a[href] { color: #404070 }
table.list th.group {
background-color: #f4f4ff;
text-align: center;
font-size: 120%;
}
table.list td {
padding: 0 4 0 4;
border: 0 2 0 2;
border-right: 1px solid #404070;
color: #404070;
background-color: white;
vertical-align: top;
empty-cells: show;
}
table.list tr.normal td {
background-color: white;
white-space: nowrap;
}
table.list tr.alt td {
background-color: #efefef;
white-space: nowrap;
}
table.list td:first-child {
border-left: 1px solid #404070;
border-right: 1px solid #404070;
}
table.list th:first-child {
border-left: 1px solid #404070;
border-right: 1px solid #404070;
}
table.list tr.navigation th {
text-align: right;
}
table.list tr.navigation th:first-child {
border-right: none;
text-align: left;
}
/* style for message displays */
table.messages {
border-spacing: 0px;
border-collapse: separate;
width: 100%;
}
table.messages th.header{
padding-top: 10px;
border-bottom: 1px solid gray;
font-weight: bold;
background-color: white;
color: #707040;
}
table.messages th {
font-weight: bold;
color: black;
text-align: left;
border-bottom: 1px solid #afafaf;
}
table.messages td {
font-family: monospace;
background-color: #efefef;
border-bottom: 1px solid #afafaf;
color: black;
empty-cells: show;
border-right: 1px solid #afafaf;
vertical-align: top;
padding: 2 5 2 5;
}
table.messages td:first-child {
border-left: 1px solid #afafaf;
border-right: 1px solid #afafaf;
}
/* style for file displays */
table.files {
border-spacing: 0px;
border-collapse: separate;
width: 100%;
}
table.files th.header{
padding-top: 10px;
border-bottom: 1px solid gray;
font-weight: bold;
background-color: white;
color: #707040;
}
table.files th {
border-bottom: 1px solid #afafaf;
font-weight: bold;
text-align: left;
}
table.files td {
font-family: monospace;
empty-cells: show;
}
/* style for history displays */
table.history {
border-spacing: 0px;
border-collapse: separate;
width: 100%;
}
table.history th.header{
padding-top: 10px;
border-bottom: 1px solid gray;
font-weight: bold;
background-color: white;
color: #707040;
font-size: 100%;
}
table.history th {
border-bottom: 1px solid #afafaf;
font-weight: bold;
text-align: left;
font-size: 90%;
}
table.history td {
font-size: 90%;
vertical-align: top;
empty-cells: show;
}
/* style for class list */
table.classlist {
border-spacing: 0px;
border-collapse: separate;
width: 100%;
}
table.classlist th.header{
padding-top: 10px;
border-bottom: 1px solid gray;
font-weight: bold;
background-color: white;
color: #707040;
}
table.classlist th {
font-weight: bold;
text-align: left;
}
/* style for class help display */
table.classhelp {
border-spacing: 0px;
border-collapse: separate;
width: 100%;
}
table.classhelp th {
font-weight: bold;
text-align: left;
color: #707040;
}
table.classhelp td {
padding: 2 2 2 2;
border: 1px solid black;
text-align: left;
vertical-align: top;
empty-cells: show;
}
/* style for "other" displays */
table.otherinfo {
border-spacing: 0px;
border-collapse: separate;
width: 100%;
}
table.otherinfo th.header{
padding-top: 10px;
border-bottom: 1px solid gray;
font-weight: bold;
background-color: white;
color: #707040;
}
table.otherinfo th {
border-bottom: 1px solid #afafaf;
font-weight: bold;
text-align: left;
}
input {
border: 1px solid #8cacbb;
color: Black;
background-color: white;
vertical-align: middle;
margin-bottom: 1px; /* IE bug fix */
padding: 0.1em;
}
select {
border: 1px solid #8cacbb;
color: Black;
background-color: white;
vertical-align: middle;
margin-bottom: 1px; /* IE bug fix */
padding: 0.1em;
}
a.nonexistent {
color: #FF2222;
}
a.nonexistent:visited {
color: #FF2222;
}
a.external {
color: #AA6600;
}
/*
dl,ul,ol {
margin-top: 1pt;
}
tt,pre {
font-family: Lucida Console,Courier New,Courier,monotype;
font-size: 12pt;
}
pre.code {
margin-top: 8pt;
margin-bottom: 8pt;
background-color: #FFFFEE;
white-space:pre;
border-style:solid;
border-width:1pt;
border-color:#999999;
color:#111111;
padding:5px;
width:100%;
}
*/
div.diffold {
background-color: #FFFF80;
border-style:none;
border-width:thin;
width:100%;
}
div.diffnew {
background-color: #80FF80;
border-style:none;
border-width:thin;
width:100%;
}
div.message {
margin-top: 6pt;
background-color: #E8FFE8;
border-style:solid;
border-width:1pt;
border-color:#999999;
color:#440000;
padding:5px;
width:100%;
}
strong.highlight {
background-color: #FFBBBB;
/* as usual, NetScape fucks up with innocent CSS
border-color: #FFAAAA;
border-style: solid;
border-width: 1pt;
*/
}
table.navibar {
background-color: #C8C8C8;
border-spacing: 3px;
}
td.navibar {
background-color: #E8E8E8;
vertical-align: top;
text-align: right;
padding: 0px;
}
div.pagename {
font-size: 140%;
color: blue;
text-align: center;
font-weight: bold;
background-color: white;
padding: 0 ;
}
a.wikiaction, input.wikiaction {
color: black;
text-decoration: None;
text-align: center;
color: black;
/*border: 1px solid #3ba6ec; */
margin: 4px;
padding: 5;
padding-bottom: 0;
white-space: nowrap;
}
a.wikiaction[href]:hover {
color: black;
text-decoration: none;
/*background-color: #dddddd; */
}
span.wikiuserpref {
padding-top: 1em;
font-size: 120%;
}
div.wikitrail {
vertical-align: bottom;
/*font-size: -1;*/
padding-top: 1em;
display: none;
}
div.wikiaction {
vertical-align: middle;
/*border-bottom: 1px solid #8cacbb;*/
padding-bottom:1em;
text-align: left;
width: 100%;
}
div.wikieditmenu {
text-align: right;
}
form.wikiedit {
border: 1px solid #8cacbb;
background-color: #f0f0f0;
background-color: #fabf00;
padding: 1em;
padding-right: 0em;
}
div.legenditem {
padding-top: 0.5em;
padding-left: 0.3em;
}
span.wikitoken {
background-color: #eeeeee;
}
div#contentspace h1:first-child, div.heading:first-child {
padding-top: 0;
margin-top: 0;
}
div#contentspace h2:first-child {
padding-top: 0;
margin-top: 0;
}
/* heading and paragraph text */
div.heading, h1 {
font-family: Verdana, Helvetica, Arial, sans-serif;
background-color: #58b3ef;
background-color: #FFFFFF;
/*color: #4893cf;*/
color: black;
padding-top: 1.0em;
padding-bottom:0.2em;
text-align: left;
margin-top: 0em;
/*margin-bottom:8pt;*/
font-weight: bold;
font-size: 115%;
border-bottom: 1px solid #8CACBB;
}
h1, h2, h3, h4, h5, h6 {
color: orange;
clear: left;
font: 100% Verdana, Helvetica, Arial, sans-serif;
margin: 0;
padding-left: 0em;
padding-top: 1em;
padding-bottom: 0.2em;
/*border-bottom: 1px solid #8CACBB;*/
}
/* h1,h2 { padding-top: 0; }*/
h1 { font-size: 145%; }
h2 { font-size: 135%; }
h3 { font-size: 125%; }
h4 { font-size: 120%; }
h5 { font-size: 110%; }
h6 { font-size: 80%; }
h1 a { text-decoration: None;}
div.exception {
background-color: #bb2222;
padding: 5 5 5 5;
color: white;
font-weight: bold;
}
pre.exception {
font-size: 110%;
padding: 1em;
border: 1px solid #8cacbb;
color: Black;
background-color: #dee7ec;
background-color: #cccccc;
}
/* defines for navgiation bar (documentation) */
div.direntry {
padding-top: 0.3em;
padding-bottom: 0.3em;
margin-right: 1em;
font-weight: bold;
background-color: #dee7ec;
font-size: 110%;
}
div.fileentry {
font-family: Verdana, Helvetica, Arial, sans-serif;
padding-bottom: 0.3em;
white-space: nowrap;
line-height: 150%;
}
a.fileentry {
white-space: nowrap;
}
span.left {
text-align: left;
}
span.right {
text-align: right;
}
div.navbar {
/*margin: 0;*/
font-size: 80% /*smaller*/;
font-weight: bold;
text-align: left;
/* position: fixed; */
top: 100pt;
left: 0pt; /* auto; */
width: 120pt;
/* right: auto;
right: 0pt; 2em; */
}
div.history a {
/* font-size: 70%; */
}
div.wikiactiontitle {
font-weight: bold;
}
/* REST defines */
div.document {
margin: 0;
}
h1.title {
margin: 0;
margin-bottom: 0.5em;
}
td.toplist {
vertical-align: top;
}
img#pyimg {
position: absolute;
top: 4px;
left: 4px;
}
div#navspace {
position: absolute;
top: 130px;
left: 11px;
font-size: 100%;
width: 150px;
overflow: hidden; /* scroll; */
}
div#metaspace {
position: absolute;
top: 40px;
left: 170px;
}
div#errorline {
position: relative;
top: 5px;
float: right;
}
div#contentspace {
position: absolute;
/* font: 120% "Times New Roman", serif;*/
font: 110% Verdana, Helvetica, Arial, sans-serif;
top: 130px;
left: 170px;
margin-right: 5px;
}
div#menubar {
/* width: 400px; */
float: left;
}
/* for the documentation page */
div#docinfoline {
position: relative;
top: 5px;
left: 0px;
/*background-color: #dee7ec; */
padding: 5pt;
padding-bottom: 1em;
color: black;
/*border-width: 1pt;
border-style: solid;*/
}
div#docnavlist {
/*background-color: #dee7ec; */
padding: 5pt;
padding-bottom: 2em;
color: black;
border-width: 1pt;
/*border-style: solid;*/
}
/* text markup */
div.listtitle {
color: Black;
clear: left;
font: 120% Verdana, Helvetica, Arial, sans-serif;
margin: 0;
padding-left: 0em;
padding-top: 0em;
padding-bottom: 0.2em;
margin-right: 0.5em;
border-bottom: 1px solid #8CACBB;
}
div.actionbox h3 {
padding-top: 0;
padding-right: 0.5em;
padding-left: 0.5em;
background-color: #fabf00;
text-align: center;
border: 1px solid black; /* 8cacbb; */
}
div.actionbox a {
display: block;
padding-bottom: 0.5em;
padding-top: 0.5em;
margin-left: 0.5em;
}
div.actionbox a.history {
display: block;
padding-bottom: 0.5em;
padding-top: 0.5em;
margin-left: 0.5em;
font-size: 90%;
}
div.actionbox {
margin-bottom: 2em;
padding-bottom: 1em;
overflow: hidden; /* scroll; */
}
/* taken from docutils (oh dear, a bit senseless) */
ol.simple, ul.simple {
margin-bottom: 1em }
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 }
/*
:Author: David Goodger
:Contact: goodger@users.sourceforge.net
:date: $Date: 2003/01/22 22:26:48 $
:version: $Revision: 1.29 $
:copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
*/
/*
.first {
margin-top: 0 }
.last {
margin-bottom: 0 }
a.toc-backref {
text-decoration: none ;
color: black }
dd {
margin-bottom: 0.5em }
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.attention, div.caution, div.danger, div.error, div.hint,
div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title {
color: red ;
font-weight: bold ;
font-family: sans-serif }
div.hint p.admonition-title, div.important p.admonition-title,
div.note p.admonition-title, div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em }
div.footer, div.header {
font-size: smaller }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.title {
text-align: center ;
color: orange}
h2.subtitle {
color: orange;
text-align: center }
hr {
width: 75% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font-family: serif ;
font-size: 100% }
pre.line-block {
font-family: serif ;
font-size: 100% }
pre.literal-block, pre.doctest-block {
margin-left: 2em ;
margin-right: 2em ;
background-color: #eeeeee }
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.option-argument {
font-style: italic }
span.pre {
white-space: pre }
span.problematic {
color: red }
table {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.citation {
border-left: solid thin gray ;
padding-left: 0.5ex }
table.docinfo {
margin: 2em 4em }
table.footnote {
border-left: solid thin black ;
padding-left: 0.5ex }
td, th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
th.docinfo-name, th.field-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap }
h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
font-size: 100% }
tt {
background-color: #eeeeee }
ul.auto-toc {
list-style-type: none }
*/
div.section {
margin-top: 1.0em ;
}

255
doc/build/docutils.css vendored
View File

@ -1,255 +0,0 @@
.first {
margin-top: 0 ! important }
.last {
margin-bottom: 0 ! important }
.hidden {
display: none }
a.toc-backref {
text-decoration: none ;
color: inherit }
blockquote.epigraph {
margin: 2em 5em }
dl.docutils dd {
margin-bottom: 0.5em }
dl.docutils dt {
font-weight: bold }
dl dt { line-height: 150% }
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title {
color: red ;
font-weight: bold ;
font-family: sans-serif }
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.document {
width: 600px ;
margin-left: 5em ;
margin-right: 5em }
div.figure {
margin-left: 2em }
div.footer, div.header {
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin-left: 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1, h2, h3, h4, h5 {
font-family: sans-serif ;
line-height: 150% ;
color: orange} /* #666 } */
h1.title {
text-align: center
}
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
ol.simple, ul.simple {
margin-bottom: 1em }
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 }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font-family: serif ;
font-size: 100% }
pre.line-block {
font-family: serif ;
font-size: 100% }
pre.literal-block, pre.doctest-block {
margin-left: 2em ;
margin-right: 2em ;
font-size: small ;
background-color: #eeeeee }
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.option-argument {
font-style: italic }
span.pre {
white-space: pre }
span.problematic {
color: red }
table.citation {
border-left: solid thin gray }
table.docinfo {
/* float: right ; */
margin: 2em 4em ;
color: #666 }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid thin black }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
th.docinfo-name, th.field-name {
font-weight: bold ;
text-align: right ;
white-space: nowrap }
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
tt.docutils {
background-color: #eeeeee }
ul.auto-toc {
list-style-type: none }

32
doc/build/style.css vendored
View File

@ -1,32 +0,0 @@
@import url(docutils.css);
@import url(default.css);
a:link {
color: orange;
font-weight: bold;
text-decoration: none;
}
a:visited {
text-decoration: none;
color: #999999;
}
a:hover {
text-decoration: none;
color: #999999;
}
a:active {
text-decoration: none;
color: #999999;
}
.header {
color: orange;
background-color: white;
padding: 1em;
}
.footer {
color: #666;
background-color: inherit;
font-size: 75%;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

View File

@ -1,83 +0,0 @@
#!/usr/bin/env python
import types
from os.path import join
from inspect import getsource, getmembers, isclass, isfunction, ismethod, ismodule
from importlib import import_module
root="./build/api"
# autopath
from os.path import dirname, abspath, join, normpath
import sys
HERE = dirname(abspath(__file__))
PATH = normpath(join(HERE, '..', '..'))
if PATH not in sys.path:
sys.path.insert(1, PATH)
htmltmpl = """
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>{title}</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta http-equiv="content-type" content="application/xhtml+xml; charset=UTF-8">
<meta http-equiv="content-style-type" content="text/css">
<meta http-equiv="expires" content="0">
</head>
<body>
<pre>
{content}
</pre>
</body>
</html>
"""
def write_source(name, content):
fh = file(join(root, name)+'.html', 'w')
fh.write(format_html(name, content))
fh.close()
def format_html(title, content):
return htmltmpl.format(title=title, content=content)
def parse_module(module):
module = import_module(module)
write_source(module.__name__, getsource(module))
# classes = [(cls, value) for cls, value in getattr(module, '__dict__').items() if value == types.ClassType]
classes = getmembers(module, isclass)
for name, obj in classes:
print module.__name__
print obj
write_source(module.__name__ + '.' + name, getsource(obj))
# methods = [(meth, value) for meth, value in getattr(obj, '__dict__').items() if type(value) == types.MethodType]
methods = getmembers(obj, ismethod)
for meth, value in methods:
write_source(module.__name__ + '.' + name + '.' + meth, getsource(value))
#functions = [(func, value) for func, value in getattr(module, '__dict__').items() if type(value) == types.FunctionType]
functions = getmembers(module, isfunction)
for name, obj in functions:
write_source(module.__name__ + '.' + name, getsource(obj))
def process_modules():
from glob import glob
from os.path import abspath, dirname, normpath, splitext, basename
here = abspath(__file__)
directory = dirname(here)
pyfiles = glob(normpath(join(directory, '..', 'tiramisu', '*.py')))
for pyf in pyfiles:
pyf = splitext(basename(pyf))[0]
modname = 'tiramisu.' + pyf
if not '__init__' in modname:
parse_module(modname)
pyfiles = glob(normpath(join(directory, '..', 'test', '*.py')))
for pyf in pyfiles:
pyf = splitext(basename(pyf))[0]
modname = 'test.' + pyf
if not '__init__' in modname:
parse_module(modname)
process_modules()

View File

@ -1,25 +1,21 @@
.. default-role:: literal
=======================
Configuration Handling
=======================
:module: :api:`config.py`
:tests: - :api:`test_config.py`
- :api:`test_option_setting.py`
===============================
Configuration handling basics
===============================
Main Assumption
===============
Configuration option objects :api:`config.Config()` are produced at the
Configuration option objects `config.Config()` are produced at the
entry points and handed down to where they are actually used. This keeps
configuration local but available everywhere and consistent.
`Config` and `Option` objects
==============================
=========================================
Configuration option objects can be created in different ways. Let's perform
very basic `Config` object manipulations:
very basic :class:`tiramisu.config.Config` object manipulations:
::
@ -35,8 +31,8 @@ very basic `Config` object manipulations:
>>> config.bool
True
Take a look at :api:`test_config.test_base_config()` or
:api:`test_config.test_base_config_and_groups()`.
Take a look at `test_config.test_base_config()` or
`test_config.test_base_config_and_groups()`.
Accessing the configuration `Option`'s
@ -90,7 +86,7 @@ name of the option are separated by dots: e.g.
the value of the option.
What if a value has been set and `None` is to be returned again ? Don't
worry, an option value can be "reseted" with the help of the :api:`option.Option.reset()`
worry, an option value can be "reseted" with the help of the `option.Option.reset()`
method.
If you do not want to use the pythonic way, that is the attribute access
@ -133,7 +129,7 @@ the first one is of course the `__setattr__` method
cfg.name = value
wich has the same effect that the "global" `set()` method : it expects that
the value owner is the default :ref:`glossary#valueowner`
the value owner is the default `glossary#valueowner`
::

View File

@ -1,11 +1,9 @@
.. default-role:: literal
Config API Details
==================
.. module:: tiramisu.config
:module: :api:`config.py`
:test cases: - :api:`test_config_api.py`
- :api:`test_config_big_example.py`
`tiramisu.config`, the configuration management main entry
================================================================
The handling of options is split into two parts: the description of
which options are available, what their possible values and defaults are
@ -14,43 +12,45 @@ bundled into a configuration object which has a reference to its option
description (and therefore makes sure that the configuration values
adhere to the option description).
The configuration object
-------------------------
The configuration object important methods
---------------------------------------------
:api:`config.Config()` object that lives in :api:`config.py` hold the
`config.Config()` object that lives in `config.py` hold the
choosen values for the options (or the default value for the
:api:`option.Option()` object, if no choice was made).
`option.Option()` object, if no choice was made).
A `Config` object is informed by an :api:`option.OptionDescription`
A `Config` object is informed by an `option.OptionDescription`
instance. The attributes of the ``Config`` objects are the names of the
children of the ``OptionDescription``.
Here are the (useful) methods on ``Config``:
:api:`config.Config.__init__(self, descr, **overrides)`:
``descr`` is an instance of :api:`option.OptionDescription` that
describes the configuration object. ``override`` can be used to
set different default values (see method ``override``).
.. currentmodule:: tiramisu.config
:api:`config.Config.set(self, **kwargs)`:
"do what I mean"-interface to option setting. Searches all paths
starting from that config for matches of the optional arguments
and sets the found option if the match is not ambiguous.
.. autoclass:: Config
:api:`config.Config.get(self, name)`:
the behavior is much like the attribute access way, except that
the search for the option is performed recursively in the whole
configuration tree.
.. automethod:: __init__
.. rubric:: Methods
.. autosummary::
~Config.__init__
~Config.set
~Config.setoption
.. automethod:: set
.. automethod:: setoption
Here are some private attributes of a `Config()` object, for a
comprehension of the internal merchanism:
- `_cfgimpl_descr =` :api:`option.OptionDescription()`,
e.g. the :ref:`optionapi#schema`
- `_cfgimpl_descr =` `option.OptionDescription()`,
e.g. the `optionapi#schema`
- `_cfgimpl_values` contains the :api:`option.Option()`'s values.
- `_cfgimpl_values` contains the `option.Option()`'s values.
Yes, the values of the options: remember that the values are stored **inside**
the :api:`config.Config()` and not in the `Option()`
the `config.Config()` and not in the `Option()`
`_cfgimpl_values` contains something like that
@ -65,28 +65,40 @@ sub-namespaces that are stored in the values as `Config()` objects.
convenience utilities (iteration, exports...)
-----------------------------------------------
With this :api:`config.Config()` configuration management entry point,
With this `config.Config()` configuration management entry point,
it is possible to
- `iter` on config, notice that there is an iteration order wich is
the order of the :ref:`optionapi#schema` specification entries,
the order of the `optionapi#schema` specification entries,
- compare two configs (equality),
- export the whole config into a `dict` with :api:`config.make_dict()`,
- export the whole config into a `dict` with `config.make_dict()`,
.. - `validate()` an option value into a config, see :doc:`consistency`.
:api:`option.Option()` objects in a config are iterable in the pythonic
`option.Option()` objects in a config are iterable in the pythonic
way, that is something like `[(name, value) for name, value in config]`.
To iter on groups in the same manner, use the
:api:`config.Config.iter_groups()` method wich yields generators too.
`config.Config.iter_groups()` method wich yields generators too.
**iteration utilities**
:api:`config.Config.__iter__()`
Pythonesque way of parsing group's ordered options.
.. autoclass:: Config
:api:`config.Config.iter_groups(group_type=None)`:
To iter on groups objects only.
All groups are returned if `group_type` is `None`, otherwise the groups
can be filtered by categories (families, or whatever).
.. automethod:: __init__
.. rubric:: Methods
.. autosummary::
~Config.get
~Config.find
~Config.find_first
~Config.getpaths
~Config.iter_groups
~Config.__iter__
.. automethod:: get
.. automethod:: find
.. automethod:: find_first
.. automethod:: getpaths
.. automethod:: iter_groups
.. automethod:: __iter__

View File

@ -3,14 +3,11 @@
The global configuration's consistency
========================================
:module: :api:`config.py`
:tests: :api:`test_option_consistency.py`
Identical option names
----------------------
If an :api:`option.Option()` happens to be defined twice in the
:ref:`glossary#schema` (e.g. the :api:`option.OptionDescription()`),
If an `option.Option()` happens to be defined twice in the
`glossary#schema` (e.g. the `option.OptionDescription()`),
that is the two options actually have the same name, an exception is raised.
The calculation is currently carried out in the samespace, for example
@ -22,7 +19,7 @@ Option's values type validation
--------------------------------
When a value is set to the option, the value is validated by the
option's :api:`option.Option()` validator's type.
option's `option.Option()` validator's type.
Notice that if the option is `multi`, that is the `multi` attribute is set to
`True`, then the validation of the option value accepts a list of values
@ -46,7 +43,7 @@ third one is the callback's action name (`hide`, `show`...)::
requires=[('int', 1, 'hide')])
Take a look at an example here
:api:`test_option_consistency.test_hidden_if_in()`
`test_option_consistency.test_hidden_if_in()`
Config updates
---------------
@ -67,9 +64,9 @@ passed to the Config objet, see:
in
- :api:`test_option_consistency.test_newoption_add_in_descr()`
- :api:`test_option_consistency.test_newoption_add_in_subdescr()`
- :api:`test_option_consistency.test_newoption_add_in_config()`
- `test_option_consistency.test_newoption_add_in_descr()`
- `test_option_consistency.test_newoption_add_in_subdescr()`
- `test_option_consistency.test_newoption_add_in_config()`
Validation upon a whole configuration object
----------------------------------------------
@ -81,9 +78,9 @@ has a certain value, and the value of this option can change the owner
of another option or option group... Everything is possible.
For example, the configuration paths have to be unique in the
:ref:`glossary#schema`, the validation is carried out at the
:api:`config.Config._cfgimpl_build()` time in the
:api:`config.Config._validate_duplicates()` method.
`glossary#schema`, the validation is carried out at the
`config.Config._cfgimpl_build()` time in the
`config.Config._validate_duplicates()` method.
Other hook are availables to validate upon a whole configuration at any
time.

View File

@ -1,82 +0,0 @@
.. default-role:: literal
.. include:: inc/preambule.txt
Accès aux variables
====================
Protocole d'accès aux valeurs
-------------------------------
**Créole**
- Si la variable n'a pas été déclarée, une erreur est levée
- Si la variable a été déclarée, mais qu'aucune valeur n'a été définie, (ni valeur affectée, ni valeur par défaut) la valeur retournée est `[]` ou `""` ou `[""]` ou `["",""]`,
- Si la variable a été déclarée et qu'une valeur par défaut a été définie, la valeur retournée et la valeur par défaut,
- Si la variable a été déclarée et qu'une valeur a été définie, la valeur retournée est la valeur de la variable.
**tiramisu**
- Si la variable n'a pas été déclarée, une erreur est levée
- Si la variable a été déclarée, mais qu'aucune valeur n'a été définie, (ni valeur affectée, ni valeur par défaut) la valeur retournée est `None`,
- Si la variable a été déclarée et qu'une valeur par défaut a été définie, la valeur retournée et la valeur par défaut,
- Si la variable a été déclarée et qu'une valeur a été définie, la valeur retournée est la valeur de la variable.
la différence tient au fait de la valeur nulle (`None`) qui a été mal définie
dès le début dans `Créole`.
Accès Créole par "dictionnaire"
--------------------------------
La définition est dans le `XML`
::
<family name="general">
<variable name="adresse_ip_eth0">
Le dictionnaire est chargé dans un `EoleDict()`
::
from creole.cfgparser import EoleDict
eoldict = EoleDict(...)
Un export dans un dictionnaire est necessaire pour manipuler les données
::
from creole.parsedico import parse_dico
flatdict = parse_dico(eoldict)
assert dico['ip'] == '10.10.1.11'
le resultat de l'accès aux données vient de `typeole.EoleVar('ip').get_value()`
Accès `tiramisu` par espace de nommage
----------------------------------------
- espaces de nommages ;
- c'est la configuration qui est responsable de l'accès aux valeurs ;
- une configuration par accès direct (pas d'export) ;
- un point d'entrée unique aisément manipulable grâce aux espaces de nommage.
::
from tiramisu.config import Config
from tiramisu.option import OptionDescription
subdescr = OptionDescription("creole", [IPOption('ip')])
descr = OptionDescription("creole", [subdescr])
config = Config(descr)
assert config.creole.general.ip == '10.10.1.11'
Les valeurs sont dépendantes **de la configuration** et donc la responsabilité
des valeurs dépend de la configuration et pas de la variable elle-même.

View File

@ -1,109 +0,0 @@
.. default-role:: literal
.. include:: inc/preambule.txt
Cohérence des valeurs des variables
====================================
type des variables
-------------------
**Créole**
pas d'unicité du type abstrait : `Multivar`, `CreoleVar` et `TypedVar`
- `String`
- `Ip`
- `Netmask`
- `Number`
- `Boolean`
- `OuiNon`
**tiramisu**
unicité du type abstrait : `Option()`
pas de nouveau type multivalué, mais un attribut des types existants::
>>> from option import BoolOption
>>> boolopt = BoolOption('bool', 'description de bool', multi=True)
tous les types Créole, plus
- `SymlinkOption`
- `CheckOption` qui permet de définir les "oui/non", "On/Off"
Validations suivant l'organisation en familles
-----------------------------------------------
**Créole**
**Organisation par accumulation de références sur des dictionnaires (`EoleDict`)**
On peut charger un EoleDict avec des variables qui pointent vers des families
qui n'existent pas, aucune validation n'est faite (confiance absolument faite au
moment du chargemzent du XML)
exemple, dans l'espace de nommage racine::
<variables>
<variable name="adresse_ip_eth0">
::
from creole.parsedico import parse_dico
flatdict = parse_dico(eoldict)
dico['adresse_ip_eth0']
KeyError: 'adresse_ip_eth0'
**Tiramisu**
**Organisation par arborescence.**
Un espace de nommage doit systématiquement être défini, la variable n'est
accessible **que** par un path.
Variables présentes deux fois
-------------------------------
- Créole : pas de validation possible
- tiramisu : comportement règlable (on autorise l'unicité ou pas)
- dans Créole les valeurs sont **fausses** (c'est la dernière variable qui qui gagne)
Il faut faire confiance au XML
::
<family name="general">
<variable name="adresse_ip_eth0">
<valeur>toto
<family name="services">
<variable name="adresse_ip_eth0">
<valeur>tutu
dans `gen_config` la valeur retenue est::
general/adresse_ip_eth0 -> tutu
services/adresse_ip_eth0 -> tutu
dans `parsedico`, la variable est écrasée::
>>> from creole.parsedico import parse_dico
>>> d = parse_dico()
>>> d['adresse_ip_eth0']
tutu
dans tiramisu::
>>> config.general.adresse_ip_eth0
toto
>>> config.services.adresse_ip_eth0
tutu

View File

@ -1,113 +0,0 @@
.. default-role:: literal
.. include:: inc/preambule.txt
Etats et statuts des options de configuration
================================================
état des variables et lisibilité de l'API
-------------------------------------------
**Creole**
`EoleVar()`
- `get_value()`
- `get_final_value()`
- `get_final_value_at_index()`
- `check_value()`
- `get_prec_value()`
- `get_calculated_value()` -> automatique
**tiramisu**
`Option()`
- **aucune API** d'accès à la valeur d'une option au niveau de l'option de configuration
- `option.getdefault()`
- `option.setoption(config, value, owner)`
variables "automatiques"
------------------------------
si `owner` == 'auto', la variable est automatique et la configuration le sait,
elle lance alors les fonctions de calcul à chaque évaluation
dans Créole, c'est validé aux niveau de la variable par un appel à `eval_func()`
Accès suivant les états de la configuration
--------------------------------------------
- disabled
- hidden
- mode (normal/expert)
- obligatoire (mandatory)
- ...
- `EoleVar.hidden`
- `EoleVar.disabled`
pas d'objet `Family` dans Créole donc l'organisation des hiérarchie de
hidden est opaque
- `EoleDict.families['hidden']` pour avoir accès à l'état d'une famille
dans Tiramisu
- `hidden` au niveau `Option`, `OptionDescription` et **aussi** au niveau de
la configuration ce qui permet d'avoir des états (inexistant dans `Créole`)
.. maitres/esclaves avec Créole : `mavar.get_slaves()`
`hidden_if_in`, `hidden_if_not_in`
-------------------------------------
La notion est généralisée dans tiramisu avec les `requires`.
Dans Créole : très difficile de conserver une cohérence des `hidden_if_in`
quand il y en a plusieurs.
Dans Tiramisu : validation et levée d'exception si les **requirements** sont
incohérents, action inverse si aucun requires n'est matché.
exemple de requires
::
<family name="clamav">
<variable name="activer_clam">
<variable name="activer_clam_exim">
<valeur>non
<variable name="activer_clam_samba">
<valeur>oui
<condition name='hidden_if_in' source='activer_clam_exim'>
<param>non
<target type='variable'>activer_clam
<!-- ça hide (momentanément)-->
<condition name='hidden_if_in' source='activer_clam_samba'>
<param>non
<target type='variable'>activer_clam
<!-- ça show (et c'est le dernier qui a raison) -->
:résultat: `activer_clam` est visible, c'est la dernière condition qui a raison
avec tiramisu, `activer_clam` **dans les même conditions**, est cachée.
::
>>> activer_clam = StrOption('activer_clam', 'activer clamav',
requires=[('activer_clam_exim', 'non', 'hide'),
('activer_clam_samba', 'non', 'hide'),])
>>> config.clamav.activer_clam_exim = 'non'
>>> config.clamav.activer_clam_samba = 'oui'
>>> config.clamav.activer_clam
>>> Traceback (most recent call last):
File "<stdin>", line 1, in <module>
HiddenOptionError("trying to access to a hidden option:activer_clam")
>>>

View File

@ -1,7 +0,0 @@
%.odt: %.txt
rst2odt --create-links --custom-odt-footer="Page %p% de %P%" --endnotes-end-doc --no-generator --stylesheet=styles.odt $< $@
%.html: %.txt
rst2html --stylesheet ./build/style.css $< > ./build/$@

View File

@ -1,6 +0,0 @@
.PHONY: clean
.SUFFIXES:
clean:
rm -f *.html
rm -f api/*.html

View File

@ -1,1080 +0,0 @@
body,body.editor,body.body {
font: 110% "Times New Roman", Arial, Verdana, Helvetica, serif;
background: White;
color: Black;
}
a, a.reference {
text-decoration: none;
}
a[href]:hover { text-decoration: underline; }
img {
border: none;
vertical-align: middle;
}
p, div.text {
text-align: left;
line-height: 1.5em;
margin: 0.5em 0em 0em 0em;
}
p a:active {
color: Red;
background-color: transparent;
}
p img {
border: 0;
margin: 0;
}
img.inlinephoto {
padding: 0;
padding-right: 1em;
padding-top: 0.7em;
float: left;
}
hr {
clear: both;
height: 1px;
color: #8CACBB;
background-color: transparent;
}
ul {
line-height: 1.5em;
/*list-style-image: url("bullet.gif"); */
margin-left: 1.5em;
padding:0;
}
ol {
line-height: 1.5em;
margin-left: 1.5em;
padding:0;
}
ul a, ol a {
text-decoration: underline;
}
dl {
}
dt {
font-weight: bold;
}
dd {
line-height: 1.5em;
margin-bottom: 1em;
}
blockquote {
font-family: Times, "Times New Roman", serif;
font-style: italic;
font-size: 120%;
}
code {
color: Black;
/*background-color: #dee7ec;*/
background-color: #cccccc;
}
pre {
padding: 1em;
border: 1px solid #8cacbb;
color: Black;
background-color: #dee7ec;
background-color: #cccccc;
overflow: auto;
}
.netscape4 {
display: none;
}
/* main page styles */
/*a[href]:hover { color: black; text-decoration: underline; }
a[href]:link { color: black; text-decoration: underline; }
a[href] { color: black; text-decoration: underline; }
*/
span.menu_selected {
color: black;
font: 140% Verdana, Helvetica, Arial, sans-serif;
text-decoration: none;
padding-right: 0.3em;
background-color: #cccccc;
}
a.menu {
/*color: #3ba6ec; */
font: 140% Verdana, Helvetica, Arial, sans-serif;
text-decoration: none;
padding-right: 0.3em;
}
a.menu[href]:visited, a.menu[href]:link{
/*color: #3ba6ec; */
font: 140% Verdana, Helvetica, Arial, sans-serif;
text-decoration: none;
}
a.menu[href]:hover {
/*color: black;*/
}
div.project_title{
/*border-spacing: 20px;*/
font: 160% Verdana, Helvetica, Arial, sans-serif;
color: #3ba6ec;
vertical-align: middle;
padding-bottom: 0.3em;
}
a.wikicurrent {
font: 100% Verdana, Helvetica, Arial, sans-serif;
color: #3ba6ec;
vertical-align: middle;
}
table.body {
border: 0;
/*padding: 0;
border-spacing: 0px;
border-collapse: separate;
*/
}
td.page-header-left {
padding: 5px;
/*border-bottom: 1px solid #444444;*/
}
td.page-header-top {
padding: 0;
/*border-bottom: 1px solid #444444;*/
}
td.sidebar {
padding: 1 0 0 1;
}
td.sidebar p.classblock {
padding: 0 5 0 5;
margin: 1 1 1 1;
border: 1px solid #444444;
background-color: #eeeeee;
}
td.sidebar p.userblock {
padding: 0 5 0 5;
margin: 1 1 1 1;
border: 1px solid #444444;
background-color: #eeeeff;
}
td.content {
padding: 1 5 1 5;
vertical-align: top;
width: 100%;
}
p.ok-message {
background-color: #22bb22;
padding: 5 5 5 5;
color: white;
font-weight: bold;
}
p.error-message {
background-color: #bb2222;
padding: 5 5 5 5;
color: white;
font-weight: bold;
}
p:first-child {
margin: 0 ;
padding: 0;
}
/* style for forms */
table.form {
padding: 2;
border-spacing: 0px;
border-collapse: separate;
}
table.form th {
color: #333388;
text-align: right;
vertical-align: top;
font-weight: normal;
}
table.form th.header {
font-weight: bold;
background-color: #eeeeff;
text-align: left;
}
table.form th.required {
font-weight: bold;
}
table.form td {
color: #333333;
empty-cells: show;
vertical-align: top;
}
table.form td.optional {
font-weight: bold;
font-style: italic;
}
table.form td.html {
color: #777777;
}
/* style for lists */
table.list {
border-spacing: 0px;
border-collapse: separate;
vertical-align: top;
padding-top: 0;
width: 100%;
}
table.list th {
padding: 0 4 0 4;
color: #404070;
background-color: #eeeeff;
border-right: 1px solid #404070;
border-top: 1px solid #404070;
border-bottom: 1px solid #404070;
vertical-align: top;
empty-cells: show;
}
table.list th a[href]:hover { color: #404070 }
table.list th a[href]:link { color: #404070 }
table.list th a[href] { color: #404070 }
table.list th.group {
background-color: #f4f4ff;
text-align: center;
font-size: 120%;
}
table.list td {
padding: 0 4 0 4;
border: 0 2 0 2;
border-right: 1px solid #404070;
color: #404070;
background-color: white;
vertical-align: top;
empty-cells: show;
}
table.list tr.normal td {
background-color: white;
white-space: nowrap;
}
table.list tr.alt td {
background-color: #efefef;
white-space: nowrap;
}
table.list td:first-child {
border-left: 1px solid #404070;
border-right: 1px solid #404070;
}
table.list th:first-child {
border-left: 1px solid #404070;
border-right: 1px solid #404070;
}
table.list tr.navigation th {
text-align: right;
}
table.list tr.navigation th:first-child {
border-right: none;
text-align: left;
}
/* style for message displays */
table.messages {
border-spacing: 0px;
border-collapse: separate;
width: 100%;
}
table.messages th.header{
padding-top: 10px;
border-bottom: 1px solid gray;
font-weight: bold;
background-color: white;
color: #707040;
}
table.messages th {
font-weight: bold;
color: black;
text-align: left;
border-bottom: 1px solid #afafaf;
}
table.messages td {
font-family: monospace;
background-color: #efefef;
border-bottom: 1px solid #afafaf;
color: black;
empty-cells: show;
border-right: 1px solid #afafaf;
vertical-align: top;
padding: 2 5 2 5;
}
table.messages td:first-child {
border-left: 1px solid #afafaf;
border-right: 1px solid #afafaf;
}
/* style for file displays */
table.files {
border-spacing: 0px;
border-collapse: separate;
width: 100%;
}
table.files th.header{
padding-top: 10px;
border-bottom: 1px solid gray;
font-weight: bold;
background-color: white;
color: #707040;
}
table.files th {
border-bottom: 1px solid #afafaf;
font-weight: bold;
text-align: left;
}
table.files td {
font-family: monospace;
empty-cells: show;
}
/* style for history displays */
table.history {
border-spacing: 0px;
border-collapse: separate;
width: 100%;
}
table.history th.header{
padding-top: 10px;
border-bottom: 1px solid gray;
font-weight: bold;
background-color: white;
color: #707040;
font-size: 100%;
}
table.history th {
border-bottom: 1px solid #afafaf;
font-weight: bold;
text-align: left;
font-size: 90%;
}
table.history td {
font-size: 90%;
vertical-align: top;
empty-cells: show;
}
/* style for class list */
table.classlist {
border-spacing: 0px;
border-collapse: separate;
width: 100%;
}
table.classlist th.header{
padding-top: 10px;
border-bottom: 1px solid gray;
font-weight: bold;
background-color: white;
color: #707040;
}
table.classlist th {
font-weight: bold;
text-align: left;
}
/* style for class help display */
table.classhelp {
border-spacing: 0px;
border-collapse: separate;
width: 100%;
}
table.classhelp th {
font-weight: bold;
text-align: left;
color: #707040;
}
table.classhelp td {
padding: 2 2 2 2;
border: 1px solid black;
text-align: left;
vertical-align: top;
empty-cells: show;
}
/* style for "other" displays */
table.otherinfo {
border-spacing: 0px;
border-collapse: separate;
width: 100%;
}
table.otherinfo th.header{
padding-top: 10px;
border-bottom: 1px solid gray;
font-weight: bold;
background-color: white;
color: #707040;
}
table.otherinfo th {
border-bottom: 1px solid #afafaf;
font-weight: bold;
text-align: left;
}
input {
border: 1px solid #8cacbb;
color: Black;
background-color: white;
vertical-align: middle;
margin-bottom: 1px; /* IE bug fix */
padding: 0.1em;
}
select {
border: 1px solid #8cacbb;
color: Black;
background-color: white;
vertical-align: middle;
margin-bottom: 1px; /* IE bug fix */
padding: 0.1em;
}
a.nonexistent {
color: #FF2222;
}
a.nonexistent:visited {
color: #FF2222;
}
a.external {
color: #AA6600;
}
/*
dl,ul,ol {
margin-top: 1pt;
}
tt,pre {
font-family: Lucida Console,Courier New,Courier,monotype;
font-size: 12pt;
}
pre.code {
margin-top: 8pt;
margin-bottom: 8pt;
background-color: #FFFFEE;
white-space:pre;
border-style:solid;
border-width:1pt;
border-color:#999999;
color:#111111;
padding:5px;
width:100%;
}
*/
div.diffold {
background-color: #FFFF80;
border-style:none;
border-width:thin;
width:100%;
}
div.diffnew {
background-color: #80FF80;
border-style:none;
border-width:thin;
width:100%;
}
div.message {
margin-top: 6pt;
background-color: #E8FFE8;
border-style:solid;
border-width:1pt;
border-color:#999999;
color:#440000;
padding:5px;
width:100%;
}
strong.highlight {
background-color: #FFBBBB;
/* as usual, NetScape fucks up with innocent CSS
border-color: #FFAAAA;
border-style: solid;
border-width: 1pt;
*/
}
table.navibar {
background-color: #C8C8C8;
border-spacing: 3px;
}
td.navibar {
background-color: #E8E8E8;
vertical-align: top;
text-align: right;
padding: 0px;
}
div.pagename {
font-size: 140%;
color: blue;
text-align: center;
font-weight: bold;
background-color: white;
padding: 0 ;
}
a.wikiaction, input.wikiaction {
color: black;
text-decoration: None;
text-align: center;
color: black;
/*border: 1px solid #3ba6ec; */
margin: 4px;
padding: 5;
padding-bottom: 0;
white-space: nowrap;
}
a.wikiaction[href]:hover {
color: black;
text-decoration: none;
/*background-color: #dddddd; */
}
span.wikiuserpref {
padding-top: 1em;
font-size: 120%;
}
div.wikitrail {
vertical-align: bottom;
/*font-size: -1;*/
padding-top: 1em;
display: none;
}
div.wikiaction {
vertical-align: middle;
/*border-bottom: 1px solid #8cacbb;*/
padding-bottom:1em;
text-align: left;
width: 100%;
}
div.wikieditmenu {
text-align: right;
}
form.wikiedit {
border: 1px solid #8cacbb;
background-color: #f0f0f0;
background-color: #fabf00;
padding: 1em;
padding-right: 0em;
}
div.legenditem {
padding-top: 0.5em;
padding-left: 0.3em;
}
span.wikitoken {
background-color: #eeeeee;
}
div#contentspace h1:first-child, div.heading:first-child {
padding-top: 0;
margin-top: 0;
}
div#contentspace h2:first-child {
padding-top: 0;
margin-top: 0;
}
/* heading and paragraph text */
div.heading, h1 {
font-family: Verdana, Helvetica, Arial, sans-serif;
background-color: #58b3ef;
background-color: #FFFFFF;
/*color: #4893cf;*/
color: black;
padding-top: 1.0em;
padding-bottom:0.2em;
text-align: left;
margin-top: 0em;
/*margin-bottom:8pt;*/
font-weight: bold;
font-size: 115%;
border-bottom: 1px solid #8CACBB;
}
h1, h2, h3, h4, h5, h6 {
color: orange;
clear: left;
font: 100% Verdana, Helvetica, Arial, sans-serif;
margin: 0;
padding-left: 0em;
padding-top: 1em;
padding-bottom: 0.2em;
/*border-bottom: 1px solid #8CACBB;*/
}
/* h1,h2 { padding-top: 0; }*/
h1 { font-size: 145%; }
h2 { font-size: 135%; }
h3 { font-size: 125%; }
h4 { font-size: 120%; }
h5 { font-size: 110%; }
h6 { font-size: 80%; }
h1 a { text-decoration: None;}
div.exception {
background-color: #bb2222;
padding: 5 5 5 5;
color: white;
font-weight: bold;
}
pre.exception {
font-size: 110%;
padding: 1em;
border: 1px solid #8cacbb;
color: Black;
background-color: #dee7ec;
background-color: #cccccc;
}
/* defines for navgiation bar (documentation) */
div.direntry {
padding-top: 0.3em;
padding-bottom: 0.3em;
margin-right: 1em;
font-weight: bold;
background-color: #dee7ec;
font-size: 110%;
}
div.fileentry {
font-family: Verdana, Helvetica, Arial, sans-serif;
padding-bottom: 0.3em;
white-space: nowrap;
line-height: 150%;
}
a.fileentry {
white-space: nowrap;
}
span.left {
text-align: left;
}
span.right {
text-align: right;
}
div.navbar {
/*margin: 0;*/
font-size: 80% /*smaller*/;
font-weight: bold;
text-align: left;
/* position: fixed; */
top: 100pt;
left: 0pt; /* auto; */
width: 120pt;
/* right: auto;
right: 0pt; 2em; */
}
div.history a {
/* font-size: 70%; */
}
div.wikiactiontitle {
font-weight: bold;
}
/* REST defines */
div.document {
margin: 0;
}
h1.title {
margin: 0;
margin-bottom: 0.5em;
}
td.toplist {
vertical-align: top;
}
img#pyimg {
position: absolute;
top: 4px;
left: 4px;
}
div#navspace {
position: absolute;
top: 130px;
left: 11px;
font-size: 100%;
width: 150px;
overflow: hidden; /* scroll; */
}
div#metaspace {
position: absolute;
top: 40px;
left: 170px;
}
div#errorline {
position: relative;
top: 5px;
float: right;
}
div#contentspace {
position: absolute;
/* font: 120% "Times New Roman", serif;*/
font: 110% Verdana, Helvetica, Arial, sans-serif;
top: 130px;
left: 170px;
margin-right: 5px;
}
div#menubar {
/* width: 400px; */
float: left;
}
/* for the documentation page */
div#docinfoline {
position: relative;
top: 5px;
left: 0px;
/*background-color: #dee7ec; */
padding: 5pt;
padding-bottom: 1em;
color: black;
/*border-width: 1pt;
border-style: solid;*/
}
div#docnavlist {
/*background-color: #dee7ec; */
padding: 5pt;
padding-bottom: 2em;
color: black;
border-width: 1pt;
/*border-style: solid;*/
}
/* text markup */
div.listtitle {
color: Black;
clear: left;
font: 120% Verdana, Helvetica, Arial, sans-serif;
margin: 0;
padding-left: 0em;
padding-top: 0em;
padding-bottom: 0.2em;
margin-right: 0.5em;
border-bottom: 1px solid #8CACBB;
}
div.actionbox h3 {
padding-top: 0;
padding-right: 0.5em;
padding-left: 0.5em;
background-color: #fabf00;
text-align: center;
border: 1px solid black; /* 8cacbb; */
}
div.actionbox a {
display: block;
padding-bottom: 0.5em;
padding-top: 0.5em;
margin-left: 0.5em;
}
div.actionbox a.history {
display: block;
padding-bottom: 0.5em;
padding-top: 0.5em;
margin-left: 0.5em;
font-size: 90%;
}
div.actionbox {
margin-bottom: 2em;
padding-bottom: 1em;
overflow: hidden; /* scroll; */
}
/* taken from docutils (oh dear, a bit senseless) */
ol.simple, ul.simple {
margin-bottom: 1em }
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 }
/*
:Author: David Goodger
:Contact: goodger@users.sourceforge.net
:date: $Date: 2003/01/22 22:26:48 $
:version: $Revision: 1.29 $
:copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
*/
/*
.first {
margin-top: 0 }
.last {
margin-bottom: 0 }
a.toc-backref {
text-decoration: none ;
color: black }
dd {
margin-bottom: 0.5em }
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.attention, div.caution, div.danger, div.error, div.hint,
div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title {
color: red ;
font-weight: bold ;
font-family: sans-serif }
div.hint p.admonition-title, div.important p.admonition-title,
div.note p.admonition-title, div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em }
div.footer, div.header {
font-size: smaller }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.title {
text-align: center ;
color: orange}
h2.subtitle {
color: orange;
text-align: center }
hr {
width: 75% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font-family: serif ;
font-size: 100% }
pre.line-block {
font-family: serif ;
font-size: 100% }
pre.literal-block, pre.doctest-block {
margin-left: 2em ;
margin-right: 2em ;
background-color: #eeeeee }
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.option-argument {
font-style: italic }
span.pre {
white-space: pre }
span.problematic {
color: red }
table {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.citation {
border-left: solid thin gray ;
padding-left: 0.5ex }
table.docinfo {
margin: 2em 4em }
table.footnote {
border-left: solid thin black ;
padding-left: 0.5ex }
td, th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
th.docinfo-name, th.field-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap }
h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
font-size: 100% }
tt {
background-color: #eeeeee }
ul.auto-toc {
list-style-type: none }
*/
div.section {
margin-top: 1.0em ;
}

View File

@ -1,255 +0,0 @@
.first {
margin-top: 0 ! important }
.last {
margin-bottom: 0 ! important }
.hidden {
display: none }
a.toc-backref {
text-decoration: none ;
color: inherit }
blockquote.epigraph {
margin: 2em 5em }
dl.docutils dd {
margin-bottom: 0.5em }
dl.docutils dt {
font-weight: bold }
dl dt { line-height: 150% }
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title {
color: red ;
font-weight: bold ;
font-family: sans-serif }
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.document {
width: 600px ;
margin-left: 5em ;
margin-right: 5em }
div.figure {
margin-left: 2em }
div.footer, div.header {
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin-left: 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1, h2, h3, h4, h5 {
font-family: sans-serif ;
line-height: 150% ;
color: orange} /* #666 } */
h1.title {
text-align: center
}
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
ol.simple, ul.simple {
margin-bottom: 1em }
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 }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font-family: serif ;
font-size: 100% }
pre.line-block {
font-family: serif ;
font-size: 100% }
pre.literal-block, pre.doctest-block {
margin-left: 2em ;
margin-right: 2em ;
font-size: small ;
background-color: #eeeeee }
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.option-argument {
font-style: italic }
span.pre {
white-space: pre }
span.problematic {
color: red }
table.citation {
border-left: solid thin gray }
table.docinfo {
/* float: right ; */
margin: 2em 4em ;
color: #666 }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid thin black }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
th.docinfo-name, th.field-name {
font-weight: bold ;
text-align: right ;
white-space: nowrap }
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
tt.docutils {
background-color: #eeeeee }
ul.auto-toc {
list-style-type: none }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

View File

@ -1,76 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.8.1: http://docutils.sourceforge.net/" />
<title>rapports eole</title>
<style type="text/css">
@import url(docutils.css);
@import url(default.css);
a:link {
color: orange;
font-weight: bold;
text-decoration: none;
}
a:visited {
text-decoration: none;
color: #999999;
}
a:hover {
text-decoration: none;
color: #999999;
}
a:active {
text-decoration: none;
color: #999999;
}
.header {
color: orange;
background-color: white;
padding: 1em;
}
.footer {
color: #666;
background-color: inherit;
font-size: 75%;
}
</style>
</head>
<body>
<div class="document">
<img alt="imgs/eol.png" class="align-right" src="imgs/eol.png" />
<table class="docutils field-list" frame="void" rules="none">
<col class="field-name" />
<col class="field-body" />
<tbody valign="top">
<tr class="field"><th class="field-name">date:</th><td class="field-body">mai 2012</td>
</tr>
<tr class="field"><th class="field-name">description:</th><td class="field-body">rapports <tt class="docutils literal">Créole</tt>, compatibilités <tt class="docutils literal">Creole</tt> et <tt class="docutils literal">tiramisu</tt></td>
</tr>
</tbody>
</table>
<div class="section" id="vue-d-ensemble-des-rapports">
<h1>Vue d'ensemble des rapports</h1>
<p>Les rapports ci-dessous résument et permettent de donner des points d'appui à
des discussions de recherche et développement concernant l'évolution du
projet <tt class="docutils literal">Creole</tt> (comprenant <tt class="docutils literal">Creole_Serv</tt>). Il y a aussi le support de
documentation développeur <tt class="docutils literal">tiramisu</tt> (en anglais) qui constitue une bonne
base pour connaître et comprendre plus en détails les motivations de
la nouvelle implementation.</p>
<ul class="simple">
<li><a class="reference external" href="pdfreport/D01AccesVariables.pdf">D01AccesVariables.pdf</a></li>
<li><a class="reference external" href="pdfreport/D02CoherenceVariables.pdf">D02CoherenceVariables.pdf</a></li>
<li><a class="reference external" href="pdfreport/D03ReglesEtats.pdf">D03ReglesEtats.pdf</a></li>
</ul>
</div>
</div>
</body>
</html>

View File

@ -1,22 +0,0 @@
#!/usr/bin/env python
import sys
from glob import glob
from os.path import isfile, dirname, abspath, join, basename, splitext
from rst import Rest, Paragraph, Strong, ListItem, Link
here = abspath(dirname(__file__))
html = glob(join(here, '*.pdf'))
basehtml = [basename(htm) for htm in html]
basehtml.sort()
content = Rest()
for htm in basehtml:
link = Link( htm , "pdfreport/" +htm)
content.add(ListItem(link))
sys.stdout.write(content.text())

View File

@ -1,410 +0,0 @@
# unproudly borrowed from pypy :
# http://codespeak.net/svn/pypy/trunk/pypy/tool/rest/rst.py
""" reStructuredText generation tools
provides an api to build a tree from nodes, which can be converted to
ReStructuredText on demand
note that not all of ReST is supported, a usable subset is offered, but
certain features aren't supported, and also certain details (like how links
are generated, or how escaping is done) can not be controlled
"""
import re
def escape(txt):
"""escape ReST markup"""
if not isinstance(txt, str) and not isinstance(txt, unicode):
txt = str(txt)
# XXX this takes a very naive approach to escaping, but it seems to be
# sufficient...
for c in '\\*`|:_':
txt = txt.replace(c, '\\%s' % (c,))
return txt
class RestError(Exception):
""" raised on containment errors (wrong parent) """
class AbstractMetaclass(type):
def __new__(cls, *args):
obj = super(AbstractMetaclass, cls).__new__(cls, *args)
parent_cls = obj.parentclass
if parent_cls is None:
return obj
if not isinstance(parent_cls, list):
class_list = [parent_cls]
else:
class_list = parent_cls
if obj.allow_nesting:
class_list.append(obj)
for _class in class_list:
if not _class.allowed_child:
_class.allowed_child = {obj:True}
else:
_class.allowed_child[obj] = True
return obj
class AbstractNode(object):
""" Base class implementing rest generation
"""
sep = ''
__metaclass__ = AbstractMetaclass
parentclass = None # this exists to allow parent to know what
# children can exist
allow_nesting = False
allowed_child = {}
defaults = {}
_reg_whitespace = re.compile('\s+')
def __init__(self, *args, **kwargs):
self.parent = None
self.children = []
for child in args:
self._add(child)
for arg in kwargs:
setattr(self, arg, kwargs[arg])
def join(self, *children):
""" add child nodes
returns a reference to self
"""
for child in children:
self._add(child)
return self
def add(self, child):
""" adds a child node
returns a reference to the child
"""
self._add(child)
return child
def _add(self, child):
if child.__class__ not in self.allowed_child:
raise RestError("%r cannot be child of %r" % \
(child.__class__, self.__class__))
self.children.append(child)
child.parent = self
def __getitem__(self, item):
return self.children[item]
def __setitem__(self, item, value):
self.children[item] = value
def text(self):
""" return a ReST string representation of the node """
return self.sep.join([child.text() for child in self.children])
def wordlist(self):
""" return a list of ReST strings for this node and its children """
return [self.text()]
class Rest(AbstractNode):
""" Root node of a document """
sep = "\n\n"
def __init__(self, *args, **kwargs):
AbstractNode.__init__(self, *args, **kwargs)
self.links = {}
def render_links(self, check=False):
"""render the link attachments of the document"""
assert not check, "Link checking not implemented"
if not self.links:
return ""
link_texts = []
# XXX this could check for duplicates and remove them...
for link, target in self.links.iteritems():
link_texts.append(".. _`%s`: %s" % (escape(link), target))
return "\n" + "\n".join(link_texts) + "\n\n"
def text(self):
outcome = []
if (isinstance(self.children[0], Transition) or
isinstance(self.children[-1], Transition)):
raise ValueError, ('document must not begin or end with a '
'transition')
for child in self.children:
outcome.append(child.text())
# always a trailing newline
text = self.sep.join([i for i in outcome if i]) + "\n"
return text + self.render_links()
class Transition(AbstractNode):
""" a horizontal line """
parentclass = Rest
def __init__(self, char='-', width=80, *args, **kwargs):
self.char = char
self.width = width
super(Transition, self).__init__(*args, **kwargs)
def text(self):
return (self.width - 1) * self.char
class Paragraph(AbstractNode):
""" simple paragraph """
parentclass = Rest
sep = " "
indent = ""
# FIXME
width = 880
def __init__(self, *args, **kwargs):
# make shortcut
args = list(args)
for num, arg in enumerate(args):
if isinstance(arg, str):
args[num] = Text(arg)
super(Paragraph, self).__init__(*args, **kwargs)
def text(self):
texts = []
for child in self.children:
texts += child.wordlist()
buf = []
outcome = []
lgt = len(self.indent)
def grab(buf):
outcome.append(self.indent + self.sep.join(buf))
texts.reverse()
while texts:
next = texts[-1]
if not next:
texts.pop()
continue
if lgt + len(self.sep) + len(next) <= self.width or not buf:
buf.append(next)
lgt += len(next) + len(self.sep)
texts.pop()
else:
grab(buf)
lgt = len(self.indent)
buf = []
grab(buf)
return "\n".join(outcome)
class SubParagraph(Paragraph):
""" indented sub paragraph """
indent = " "
class Title(Paragraph):
""" title element """
parentclass = Rest
belowchar = "="
abovechar = ""
def text(self):
txt = self._get_text()
lines = []
if self.abovechar:
lines.append(self.abovechar * len(txt))
lines.append(txt)
if self.belowchar:
lines.append(self.belowchar * len(txt))
return "\n".join(lines)
def _get_text(self):
txt = []
for node in self.children:
txt += node.wordlist()
return ' '.join(txt)
class AbstractText(AbstractNode):
parentclass = [Paragraph, Title]
start = ""
end = ""
def __init__(self, _text):
self._text = _text
def text(self):
text = self.escape(self._text)
return self.start + text + self.end
def escape(self, text):
if not isinstance(text, str) and not isinstance(text, unicode):
text = str(text)
if self.start:
text = text.replace(self.start, '\\%s' % (self.start,))
if self.end and self.end != self.start:
text = text.replace(self.end, '\\%s' % (self.end,))
return text
class Text(AbstractText):
def wordlist(self):
text = escape(self._text)
return self._reg_whitespace.split(text)
class LiteralBlock(AbstractText):
parentclass = Rest
start = '::\n\n'
def text(self):
if not self._text.strip():
return ''
text = self.escape(self._text).split('\n')
for i, line in enumerate(text):
if line.strip():
text[i] = ' %s' % (line,)
return self.start + '\n'.join(text)
class Em(AbstractText):
start = "*"
end = "*"
class Strong(AbstractText):
start = "**"
end = "**"
class Quote(AbstractText):
start = '``'
end = '``'
class Anchor(AbstractText):
start = '_`'
end = '`'
class Footnote(AbstractText):
def __init__(self, note, symbol=False):
raise NotImplemented('XXX')
class Citation(AbstractText):
def __init__(self, text, cite):
raise NotImplemented('XXX')
class ListItem(Paragraph):
allow_nesting = True
item_chars = '*+-'
def text(self):
idepth = self.get_indent_depth()
indent = self.indent + (idepth + 1) * ' '
txt = '\n\n'.join(self.render_children(indent))
ret = []
item_char = self.item_chars[idepth]
ret += [indent[len(item_char)+1:], item_char, ' ', txt[len(indent):]]
return ''.join(ret)
def render_children(self, indent):
txt = []
buffer = []
def render_buffer(fro, to):
if not fro:
return
p = Paragraph(indent=indent, *fro)
p.parent = self.parent
to.append(p.text())
for child in self.children:
if isinstance(child, AbstractText):
buffer.append(child)
else:
if buffer:
render_buffer(buffer, txt)
buffer = []
txt.append(child.text())
render_buffer(buffer, txt)
return txt
def get_indent_depth(self):
depth = 0
current = self
while (current.parent is not None and
isinstance(current.parent, ListItem)):
depth += 1
current = current.parent
return depth
class OrderedListItem(ListItem):
item_chars = ["#."] * 5
class DListItem(ListItem):
item_chars = None
def __init__(self, term, definition, *args, **kwargs):
self.term = term
super(DListItem, self).__init__(definition, *args, **kwargs)
def text(self):
idepth = self.get_indent_depth()
indent = self.indent + (idepth + 1) * ' '
txt = '\n\n'.join(self.render_children(indent))
ret = []
ret += [indent[2:], self.term, '\n', txt]
return ''.join(ret)
class Link(AbstractText):
start = '`'
end = '`_'
def __init__(self, _text, target):
self._text = _text
self.target = target
self.rest = None
def text(self):
if self.rest is None:
self.rest = self.find_rest()
if self.rest.links.get(self._text, self.target) != self.target:
raise ValueError('link name %r already in use for a different '
'target' % (self.target,))
self.rest.links[self._text] = self.target
return AbstractText.text(self)
def find_rest(self):
# XXX little overkill, but who cares...
next = self
while next.parent is not None:
next = next.parent
return next
class InternalLink(AbstractText):
start = '`'
end = '`_'
class LinkTarget(Paragraph):
def __init__(self, name, target):
self.name = name
self.target = target
def text(self):
return ".. _`%s`:%s\n" % (self.name, self.target)
class Substitution(AbstractText):
def __init__(self, text, **kwargs):
raise NotImplemented('XXX')
class Directive(Paragraph):
indent = ' '
def __init__(self, name, *args, **options):
self.name = name
self.content = args
super(Directive, self).__init__()
self.options = options
def text(self):
# XXX not very pretty...
txt = '.. %s::' % (self.name,)
options = '\n'.join([' :%s: %s' % (k, v) for (k, v) in
self.options.iteritems()])
if options:
txt += '\n%s' % (options,)
if self.content:
txt += '\n'
for item in self.content:
txt += '\n ' + item
return txt

View File

@ -1,32 +0,0 @@
@import url(docutils.css);
@import url(default.css);
a:link {
color: orange;
font-weight: bold;
text-decoration: none;
}
a:visited {
text-decoration: none;
color: #999999;
}
a:hover {
text-decoration: none;
color: #999999;
}
a:active {
text-decoration: none;
color: #999999;
}
.header {
color: orange;
background-color: white;
padding: 1em;
}
.footer {
color: #666;
background-color: inherit;
font-size: 75%;
}

View File

@ -1,12 +0,0 @@
.. container:: rubric
**Rédacteurs**
| Gwenaël Rémond (gremond@cadoles.com)
| Emmanuel Garette (egarette@cadoles.com)
**Référence**
| ``tiramisu/doc/eole-reports``
| ``git clone ssh://gitosis@git.cadol.es:2222/tiramisu.git``

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

View File

@ -1,18 +0,0 @@
.. csv-table::
.. image:: inc/logo.png, .. image:: inc/eol.png
.. container:: title
Rapports de discussions de recherche et développements
------------
.. container:: subtitle
Comparaison ``tiramisu`` et ``Créole``
.. include:: 00-Redacteur.txt

View File

@ -1,33 +0,0 @@
.. default-role:: literal
.. title:: rapports eole
.. image:: imgs/eol.png
:align: right
:date: mai 2012
:description: rapports `Créole`, compatibilités `Creole` et `tiramisu`
Vue d'ensemble des rapports
===================================
Les rapports ci-dessous résument et permettent de donner des points d'appui à
des discussions de recherche et développement concernant l'évolution du
projet `Creole` (comprenant `Creole_Serv`). Il y a aussi le support de
documentation développeur `tiramisu` (en anglais) qui constitue une bonne
base pour connaître et comprendre plus en détails les motivations de
la nouvelle implementation.
* `D01AccesVariables.pdf`_
* `D02CoherenceVariables.pdf`_
* `D03ReglesEtats.pdf`_
.. _`D03ReglesEtats.pdf`: pdfreport/D03ReglesEtats.pdf
.. _`D02CoherenceVariables.pdf`: pdfreport/D02CoherenceVariables.pdf
.. _`D01AccesVariables.pdf`: pdfreport/D01AccesVariables.pdf

Binary file not shown.

View File

@ -1,67 +1,66 @@
==================================
`Tiramisu` - Getting Started
`Tiramisu` - getting started
==================================
What is Configuration handling ?
=================================
=================================
Due to more and more available configuration options required to set up
an operating system, it became quite annoying to hand the necessary
options to where they are actually used and even more annoying to add
new options. To circumvent these problems the configuration management
Due to more and more available configuration options required to set up
an operating system, it became quite annoying to hand the necessary
options to where they are actually used and even more annoying to add
new options. To circumvent these problems the configuration management
was introduced.
What is Tiramisu ?
===================
===================
Tiramisu is yet another configuration handler, wich aims at producing
flexible and fast configuration options access. The main advantages are
its access :ref:`glossary#rules` and the fact that the configuration 's
consistency is preserved at any time, see :ref:`glossary#consistency`.
Tiramisu is yet another configuration handler, wich aims at producing
flexible and fast configuration options access. The main advantages are
its access `glossary#rules` and the fact that the configuration 's
consistency is preserved at any time, see `glossary#consistency`.
There are type and structures's validations for configuration options,
There are type and structures's validations for configuration options,
and validations towards the whole configuration.
Last but not least, configuration options can be reached and changed
according to the access rules from nearly everywhere in the OS boxes,
Last but not least, configuration options can be reached and changed
according to the access rules from nearly everywhere in the OS boxes,
e.g. the containers via the `http/json` server.
Just the facts
==============
Just the facts
==============
.. _gettingtiramisu:
.. _gettingtiramisu:
Download
---------
To obtain a copy of the sources, check it out from the repository using
To obtain a copy of the sources, check it out from the repository using
`git`. We suggest using `git` if one wants to access the current development.
::
git clone git://git.labs.libre-entreprise.org/tiramisu.git
This will get you a fresh checkout of the code repository in a local
This will get you a fresh checkout of the code repository in a local
directory named ``tiramisu``.
Understanding Tiramisu's architecture
--------------------------------------
The :ref:`glossary#schema` is loaded from an XML file, and the values of
The `glossary#schema` is loaded from an XML file, and the values of
the configuration options are recovered from a `.ini` like file.
By now, all the in-depth informations about the configuration are stored
in a **single** object, the :api:`config.Config()` object, wich is
responsible of nearly everything. All the necessary options are stored
into a configuration object, which is available nearly everywhere, so
By now, all the in-depth informations about the configuration are stored
in a **single** object, the `config.Config()` object, wich is
responsible of nearly everything. All the necessary options are stored
into a configuration object, which is available nearly everywhere, so
that adding new options becomes trivial.
This `Config()` is available from everywhere with the help of an http server
that serves configuration datas as `json` strings.
that serves configuration datas as `json` strings.
.. figure:: architecture.png
The basics of Tiramisu's architecture.
Once loaded, http server serves the :api:`config.Config()` object, that is,
the configuration options and the configuration groups.
The basics of Tiramisu's architecture.
Once loaded, http server serves the `config.Config()` object, that is,
the configuration options and the configuration groups.

View File

@ -3,97 +3,106 @@
glossary
==========
.. _configuration:
.. glossary::
**configuration**
configuration
Global configuration object, wich contains the whole configuration
options *and* their descriptions (option types and group)
Global configuration object, wich contains the whole configuration
options *and* their descriptions (option types and group)
.. _`option description`:
.. _`schema`:
.. glossary::
**schema**:
**option description**
schema
option description
see :api:`option.OptionDescription`, see :ref:`optionapi#schema`
see `option.OptionDescription`, see `optionapi#schema`
The schema of a configuration :
- the option types
The schema of a configuration :
- how they are organised in groups or even subgroups, that's why we
call them **groups** too.
- the option types
.. _`configoption`:
- how they are organised in groups or even subgroups, that's why we
call them **groups** too.
**configuration option**
.. glossary::
An option object wich has a name and a value and can be accessed
from the configuration object
configuration option
.. _`defaultvalue`:
An option object wich has a name and a value and can be accessed
from the configuration object
**default value**
.. glossary::
Default value of a configuration option. The default value can be
set at instanciation time, or even at any moment. Remember that if
you reset the default value, the owner reset to `default`
default value
.. _`rules`:
Default value of a configuration option. The default value can be
set at instanciation time, or even at any moment. Remember that if
you reset the default value, the owner reset to `default`
**acces rules**
Access rules are : :api:`config.Config.cfgimpl_read_write()` or
:api:`config.Config.cfgimpl_read_only()`, see :doc:`status`
.. glossary::
**freeze**
acces rules
A whole configuration can be frozen (used in read only access). See
:ref:`status#frozenconfig` for details.
Access rules are : `config.Config.cfgimpl_read_write()` or
`config.Config.cfgimpl_read_only()`, see :doc:`status`
A single option can be frozen too.
.. glossary::
**forced on freeze**
freeze
A single option is frozen and we want the option to return something
else than his value, typically his default value, see
:ref:`status#frozen`
A whole configuration can be frozen (used in read only access). See
`status#frozenconfig` for details.
.. _`valueowner`:
A single option can be frozen too.
**value owner**
When an option is modified, including at the instanciation, we
always know who has modified it. It's the owner of the option, see
:doc:`status` for more details.
.. glossary::
**option with properties**
an option wich has property like 'hidden' or 'disabled' is an option
wich has restricted acces rules
forced on freeze
**hidden option**
A single option is frozen and we want the option to return something
else than his value, typically his default value, see
`status#frozen`
a hidden option has a different behaviour on regards to the access
of the value in the configuration, see :doc:`status` for more details.
.. glossary::
**disabled option**
value owner
a disabled option has a different behaviour on regards to the access
of the value in the configuration, see :doc:`status` for more details.
When an option is modified, including at the instanciation, we
always know who has modified it. It's the owner of the option, see
:doc:`status` for more details.
.. _mandatory:
.. glossary::
**mandatory option**
option with properties
A mandatory option is a configuration option wich value has to be
set, that is the default value cannot be `None`, see
:ref:`optionapi#optioninit`
.. _consistency:
an option wich has property like 'hidden' or 'disabled' is an option
wich has restricted acces rules
**consistency**
.. glossary::
Preserve the consistency in a whole configuration is a tricky thing,
tiramisu takes care of it for you, see :doc:`consistency` for details.
hidden option
a hidden option has a different behaviour on regards to the access
of the value in the configuration, see :doc:`status` for more details.
.. glossary::
disabled option
a disabled option has a different behaviour on regards to the access
of the value in the configuration, see :doc:`status` for more details.
.. glossary::
mandatory option
A mandatory option is a configuration option wich value has to be
set, that is the default value cannot be `None`, see
`optionapi#optioninit`
.. glossary::
consistency
Preserve the consistency in a whole configuration is a tricky thing,
tiramisu takes care of it for you, see :doc:`consistency` for details.

View File

@ -4,7 +4,7 @@
:description: configuration management
:keywords: config, configuration
.. title:: tiramisu
.. |version| replace:: 0.1
@ -14,28 +14,37 @@ The tasting of `Tiramisu`
.. image:: tiramisu.jpeg
:height: 150px
`Tiramisu`
is a cool, refreshing Italian dessert,
it is also a `configuration management tool`_.
.. _`configuration management tool`: http://en.wikipedia.org/wiki/Configuration_management
It's a pretty small, local (that is, straight on the operating system)
It's a pretty small, local (that is, straight on the operating system)
configuration handler.
- :doc:`getting-started`: where to go from here,
- :doc:`config` explains the good praticies of configuration handling,
- :doc:`configapi` and :doc:`optionapi` describe the API's details,
- :doc:`status` for a summary of the `Option`'s and `Config`'s statuses,
- :doc:`consistency` for the local and global integrity constraints,
- :doc:`glossary` describes the specific terms used in Tiramisu.
.. toctree::
:maxdepth: 1
getting-started
config
configapi
optionapi
status
consistency
glossary
Indices and tables
==================
* :ref:`genindex`
* :ref:`modindex`
* :ref:`search`
This work is licensed under a `Creative Commons Attribution-ShareAlike 3.0 Unported License`_.
.. _`Creative Commons Attribution-ShareAlike 3.0 Unported License`: http://creativecommons.org/licenses/by-sa/3.0/deed.en_US

View File

@ -1,11 +1,7 @@
.. default-role:: literal
Options API Details
=====================
:module: :api:`option.py`
.. _schema:
The `tiramisu.option.Option` options
======================================
Description of Options
----------------------
@ -16,24 +12,39 @@ Most constructors take a ``default`` argument that specifies the default
value of the option. If this argument is not supplied the default value
is assumed to be ``None``.
Appart from that, the `Option` object is not supposed to contain any
other value than the `tainted` attribute, which is explained later. The
container of the value is in the `Config` object.
``OptionDescription``
+++++++++++++++++++++
The `OptionDescription` class
-------------------------------
This class is used to group suboptions.
``__init__(self, name, doc, children)``
``children`` is a list of option descriptions (including
``OptionDescription`` instances for nested namespaces).
.. module:: tiramisu.option
``set_group_type(self, group_name)``
Three available group_types : `default`, `family`, `group` and
`master` (for master~slave group type). Notice that for a
master~slave group, the name of the group and the name of the
master option are identical.
.. autoclass: OptionDescription
.. automethod:: __init__
.. rubric:: Methods
.. autosummary::
~Config.__init__
~Config.set_group_type
.. automethod:: set_group_type
..
``__init__(self, name, doc, children)``
``children`` is a list of option descriptions (including
``OptionDescription`` instances for nested namespaces).
``set_group_type(self, group_name)``
Three available group_types : `default`, `family`, `group` and
`master` (for master~slave group type). Notice that for a
master~slave group, the name of the group and the name of the
master option are identical.
`Options description` objects lives in the `_cfgimpl_descr` config attribute.
@ -61,19 +72,21 @@ configuration option
or to hide it, or disable it, or... anything.
The `Option` class
---------------------
It's an abstract base class for option wich are typed (int, string...)
.. _optioninit:
.. autoclass:: Option
:special-members:
:members:
generic option ``__init__`` method:
``__init__(name, doc, default=None, requires=None, multi=False, mandatory=False)``
:``default``: specifies the default value of the option.
:``requires``: is a list of names of options located anywhere in the configuration.
:``multi``: means the value can be a list.
:``mandatory``: see :ref:`glossary#mandatory`.
.. _optiontype:
``BoolOption``
++++++++++++++

View File

@ -1,82 +0,0 @@
#!/usr/bin/python
# unproudly borrowed from David Goodger's rst2html.py
"""
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
# ____________________________________________________________
from docutils import nodes, utils
from docutils.parsers.rst import roles
"""
description of the new roles:
`:api:` : link to the code
- code.py becomes api/code.html
- code.Code.code_test becomes api/code.Code.code_test.html
- code.Code() becomes api/code.Code.html
`:doc:`a link to an internal file
example become example.html
ref: link with anchor as in an external file
:ref:`toto#titi` becomes toto.html#titi
"""
from os.path import splitext
def api_reference_role(role, rawtext, text, lineno, inliner,
options={}, content=[]):
basename = text
if "(" in text:
basename = text.split("(")[0]
if ".py" in text:
basename = splitext(text)[0]
if "test_" in text:
refuri = "api/" + "test." + basename + '.html'
else:
refuri = "api/" + "tiramisu." + basename + '.html'
roles.set_classes(options)
node = nodes.reference(rawtext, utils.unescape(text), refuri=refuri,
**options)
return [node], []
roles.register_local_role('api', api_reference_role)
def doc_reference_role(role, rawtext, text, lineno, inliner,
options={}, content=[]):
refuri = text + '.html'
roles.set_classes(options)
node = nodes.reference(rawtext, utils.unescape(text), refuri=refuri,
**options)
return [node], []
roles.register_local_role('doc', doc_reference_role)
def ref_reference_role(role, rawtext, text, lineno, inliner,
options={}, content=[]):
fname, anchor = text.split('#')
refuri = fname + '.html#' + anchor
roles.set_classes(options)
node = nodes.reference(rawtext, utils.unescape(anchor), refuri=refuri,
**options)
return [node], []
roles.register_local_role('ref', ref_reference_role)
# ____________________________________________________________
description = ('Generates (X)HTML documents from standalone reStructuredText '
'sources. ' + default_description)
publish_cmdline(writer_name='html', description=description)

View File

@ -3,18 +3,12 @@
Configuration status
======================
:module: :api:`config.py`
:tests: - :api:`test_option_owner.py`
- :api:`test_option_type.py`
- :api:`test_option_default.py`
Available configuration statuses
----------------------------------
The configuration's status lives in an :api:`setting.Setting` object.
The configuration's status lives in an `setting.Setting` object.
This configuration status corresponds to specific attributes or bunch of
attributes that can be accessed together with some :api:`setting.Setting`
attributes that can be accessed together with some `setting.Setting`
method:
**read write status**
@ -24,7 +18,7 @@ method:
possible to modify a disabled option.
To enable read-write status, call
:api:`setting.Setting.read_write()`
`setting.Setting.read_write()`
**read only status**
@ -35,7 +29,7 @@ method:
The configuration has not an access to the hidden options
but can read the disabled options.
To enable read only status, call :api:`setting.Setting.read_only()`
To enable read only status, call `setting.Setting.read_only()`
.. csv-table:: **Configuration's statuses summary**
:header: " ", "Hidden", "Disabled", "Mandatory"
@ -48,30 +42,30 @@ method:
Freezing a configuration
---------------------------
At the configuration level, :api:`setting.Setting.freeze` freezes
At the configuration level, `setting.Setting.freeze` freezes
the whole configuration options.
- :api:`test_option_type.test_frozen_value()`
- :api:`test_option_type.test_freeze()`
- `test_option_type.test_frozen_value()`
- `test_option_type.test_freeze()`
.. _`frozen`:
It is possible to *freeze* a single `Option` object with
:api:`option.Option.freeze()`. If you try to modify a frozen option, it
`option.Option.freeze()`. If you try to modify a frozen option, it
raises a `TypeError: trying to change a frozen option object`.
- :api:`test_option_type.test_freeze_one_option()`
- `test_option_type.test_freeze_one_option()`
Moreover, frozen option can return his default value if
:api:`option.Option.force_default()` has been called on this option,
see :api:`test_option_default.test_force_default_on_freeze()`
`option.Option.force_default()` has been called on this option,
see `test_option_default.test_force_default_on_freeze()`
Restricted access to an `Option()`
-----------------------------------
Configuration options access statuses are defined at configuration level
that corresponds to the :api:`option.Option()`'s `properties` attribute,
that corresponds to the `option.Option()`'s `properties` attribute,
for example
**hidden**
@ -80,7 +74,7 @@ for example
the value of the option.
See `hide()` or `show()` in `Option()` that comes from
:api:`option.HiddenBaseType`
`option.HiddenBaseType`
corresponding convenience API provided:
@ -95,7 +89,7 @@ corresponding convenience API provided:
This means that an option *doesn't exists* (doesn't say anything
much more thant an `AttibuteAccess` error)
See in :api:`option.DisabledBaseType` the origins of
See in `option.DisabledBaseType` the origins of
`Option.enable()` or `Option.disable()`
corresponding convenience API provided:
@ -158,15 +152,15 @@ Special behaviors for an option
This means that it is a calculated value and therefore automatically
protected it cannot be modified by attribute access.
Its inner state is represented by :api:`option.Option.has_callback()`
and :api:`option.Option.hascallback_and_isfrozen()`
Its inner state is represented by `option.Option.has_callback()`
and `option.Option.hascallback_and_isfrozen()`
**force default**
if the configuration option has a default value, the default is
returned, otherwise the value is calculated.
Its inner state is represented by :api:`option.Option.force_default()`
Its inner state is represented by `option.Option.force_default()`
Configuration options have default values that are stored in the
`Option()` object itself. Default values, the `default`, can be set in

View File

@ -1,73 +0,0 @@
:date: 20 janvier 2012
créer une variable implicite cachée
::
<variable name="toto"
exists='False' hidden='True'>
<value>non<value>
si la variable n'existe pas, elle est crée avec une valeur par défaut
cela permet une alternative aux dépendances (pour ne pas installer un
paquet inutilement)
coder ça exactement comme les hidden ou les disabled, avec une levée
d'exception supplémentaire comme filtre.
:date: 20 janvier 2012
coder un cache pour les options dont le propriétaire est "auto" ou "fill"
mettre ça dans un attribut `_cache` de l'option
mettre une contrainte de temps dans le cache
- pouvoir forcer le recalcul de toutes les variables (vider le cache)
globalement dans toute la config
- mettre une contrainte de temps donnée
expires = timestamp + deltatime
:date: 17 avril
- lever une exception parlante (pour l'instant, c'est une "KeyError")
lorsqu'on essaye d'affecter quelque chose
à un groupe, genre
::
cfg = Config(descr)
cfg.gc = "uvw"
alors que gc est un groupe
:date: 12 avril
- validations de longueur des maitres/esclaves ailleurs à sortir des requires
et à mettre dans des validators
:date: 3 avril 2012
2012-03-22
**groupe master**
faire une api du genre : `Option().is_master()`
pour cela, tester `if self.parent._name == self._name: return True`
A documenter
-------------
- les variables multiples
- documenter le typage des options descriptions descr_type
A ajouter
---------
Option -> attribut help (en plus de doc)
get_help() (à mettre en class Type avec Doc aussi)

View File

@ -270,7 +270,7 @@ class Config(object):
(typically called by the __setattr__)
:param who: is an owner's name
who is **not necessarily** a owner, because it cannot be a list
who is **not necessarily** a owner, because it cannot be a list
:type who: string
"""
child = getattr(self._cfgimpl_descr, name)
@ -292,7 +292,7 @@ class Config(object):
def set(self, **kwargs):
"""
"do what I mean"-interface to option setting. Searches all paths
do what I mean"-interface to option setting. Searches all paths
starting from that config for matches of the optional arguments
and sets the found option if the match is not ambiguous.
:param kwargs: dict of name strings to values.
@ -321,8 +321,8 @@ class Config(object):
def get(self, name):
"""
same as a find_first() method in a config that has identical names
that is : Returns the first item of an option named 'name'
same as a `find_first()` method in a config that has identical names:
it returns the first item of an option named `name`
much like the attribute access way, except that
the search for the option is performed recursively in the whole
@ -397,7 +397,8 @@ class Config(object):
return not self == other
# ______________________________________________________________________
def __iter__(self):
"iteration only on Options (not OptionDescriptions)"
"""Pythonesque way of parsing group's ordered options.
iteration only on Options (not OptionDescriptions)"""
for child in self._cfgimpl_descr._children:
if isinstance(child, Option):
try:
@ -406,7 +407,10 @@ class Config(object):
pass # option with properties
def iter_groups(self, group_type=None):
"iteration on OptionDescriptions"
"""iteration on groups objects only.
All groups are returned if `group_type` is `None`, otherwise the groups
can be filtered by categories (families, or whatever).
"""
if group_type == None:
groups = group_types
else:

View File

@ -85,20 +85,33 @@ class Multi(list):
#
class Option(HiddenBaseType, DisabledBaseType):
"""
Abstract base class for configuration option's
reminder: an Option object is **not** a container for the value
Abstract base class for configuration option's.
Reminder: an Option object is **not** a container for the value
"""
"freeze means: cannot modify the value of an Option once set"
#freeze means: cannot modify the value of an Option once set
_frozen = False
"if an Option has been frozen, shall return the default value"
#if an Option has been frozen, shall return the default value
_force_default_on_freeze = False
def __init__(self, name, doc, default=None, default_multi=None,
requires=None, mandatory=False, multi=False, callback=None,
callback_params=None, validator=None, validator_args={}):
"""
:param default: ['bla', 'bla', 'bla']
:param name: the option's name
:param doc: the option's description
:param default: specifies the default value of the option,
for a multi : ['bla', 'bla', 'bla']
:param default_multi: 'bla' (used in case of a reset to default only at
a given index)
a given index)
:param requires: is a list of names of options located anywhere
in the configuration.
:param multi: if true, the option's value is a list
:param callback: the name of a function. If set, the function's output
is responsible of the option's value
:param callback_params: the callback's parameter
:param validator: the name of a function wich stands for a custom
validation of the value
:param validator_args: the validator's parameters
"""
self._name = name
self.doc = doc
@ -224,9 +237,9 @@ class Option(HiddenBaseType, DisabledBaseType):
def setowner(self, config, owner):
"""
:param config: *must* be only the **parent** config
(not the toplevel config)
:param owner: is a **real* owner, that is a name or a list
which is allowable here
(not the toplevel config)
:param owner: is a **real** owner, that is a name or a list
which is allowable here
"""
name = self._name
if not type(owner) == str:
@ -246,7 +259,7 @@ class Option(HiddenBaseType, DisabledBaseType):
def is_default_owner(self, config):
"""
:param config: *must* be only the **parent** config
(not the toplevel config)
(not the toplevel config)
:return: boolean
"""
return self.getowner(config) == 'default'