first import
authorPierre <ratinaud@univ-tlse2.fr>
Sun, 10 Jun 2012 08:17:01 +0000 (10:17 +0200)
committerPierre <ratinaud@univ-tlse2.fr>
Sun, 10 Jun 2012 08:17:01 +0000 (10:17 +0200)
202 files changed:
HTML.py [new file with mode: 0644]
HTML/HTML.py [new file with mode: 0644]
HTML/HTML.py.html [new file with mode: 0644]
HTML/HTML_tutorial.py [new file with mode: 0644]
HTML/Licence_CeCILL_V2-en.html [new file with mode: 0644]
HTML/Licence_CeCILL_V2-fr.html [new file with mode: 0644]
HTML/PKG-INFO [new file with mode: 0644]
HTML/README.txt [new file with mode: 0644]
HTML/setup.py [new file with mode: 0644]
INSTALL_WINDOWS [new file with mode: 0644]
KeyFrame.py [new file with mode: 0755]
Liste.py [new file with mode: 0644]
OptionAlceste.py [new file with mode: 0755]
PrintRScript.py [new file with mode: 0644]
ProfList.py [new file with mode: 0644]
Rscripts/CHD.R [new file with mode: 0644]
Rscripts/CHD.R.old [new file with mode: 0644]
Rscripts/CHDKmeans.R [new file with mode: 0644]
Rscripts/CHDPOND.R [new file with mode: 0644]
Rscripts/Rfunct.R [new file with mode: 0644]
Rscripts/Rgraph.R [new file with mode: 0644]
Rscripts/Rprof.out [new file with mode: 0644]
Rscripts/afc.R [new file with mode: 0644]
Rscripts/afc_graph.R [new file with mode: 0644]
Rscripts/afc_lex.R [new file with mode: 0644]
Rscripts/anacor.R [new file with mode: 0644]
Rscripts/association.R [new file with mode: 0644]
Rscripts/chd.R [new file with mode: 0644]
Rscripts/chdfunct.R [new file with mode: 0644]
Rscripts/chdquest.R [new file with mode: 0644]
Rscripts/chdtxt.R [new file with mode: 0644]
Rscripts/graph.txt [new file with mode: 0644]
Rscripts/multipam.R [new file with mode: 0644]
Rscripts/mysvd.R [new file with mode: 0644]
Rscripts/pamtxt.R [new file with mode: 0644]
Rscripts/plotafcm.R [new file with mode: 0644]
Rscripts/simi.R [new file with mode: 0644]
Rscripts/simied.R [new file with mode: 0644]
Rscripts/simiold.R [new file with mode: 0644]
Rscripts/splitafc.R [new file with mode: 0644]
TODO [new file with mode: 0644]
agw/__init__.py [new file with mode: 0644]
agw/__init__.pyc [new file with mode: 0644]
agw/aui/__init__.py [new file with mode: 0644]
agw/aui/__init__.pyc [new file with mode: 0644]
agw/aui/aui_constants.py [new file with mode: 0644]
agw/aui/aui_constants.pyc [new file with mode: 0644]
agw/aui/aui_switcherdialog.py [new file with mode: 0644]
agw/aui/aui_utilities.py [new file with mode: 0644]
agw/aui/aui_utilities.pyc [new file with mode: 0644]
agw/aui/auibar.py [new file with mode: 0644]
agw/aui/auibar.pyc [new file with mode: 0644]
agw/aui/auibook.py [new file with mode: 0644]
agw/aui/auibook.pyc [new file with mode: 0644]
agw/aui/dockart.py [new file with mode: 0644]
agw/aui/dockart.pyc [new file with mode: 0644]
agw/aui/framemanager.py [new file with mode: 0644]
agw/aui/framemanager.pyc [new file with mode: 0644]
agw/aui/tabart.py [new file with mode: 0644]
agw/aui/tabart.pyc [new file with mode: 0644]
agw/aui/tabmdi.py [new file with mode: 0644]
agw/aui/tabmdi.pyc [new file with mode: 0644]
analysetxt.py [new file with mode: 0644]
app.fil [new file with mode: 0644]
bestsvg.py [new file with mode: 0644]
build_dictionnaries.py [new file with mode: 0644]
cable.py [new file with mode: 0644]
checkinstall.py [new file with mode: 0644]
checkversion.py [new file with mode: 0644]
chemins.py [new file with mode: 0644]
colors.py [new file with mode: 0644]
configuration/.corpus.cfg.swo [new file with mode: 0644]
configuration/.corpus.cfg.swp [new file with mode: 0644]
configuration/CHD.cfg [new file with mode: 0644]
configuration/alceste.cfg [new file with mode: 0644]
configuration/corpus.cfg [new file with mode: 0644]
configuration/global.cfg [new file with mode: 0644]
configuration/iramuteq.cfg [new file with mode: 0644]
configuration/key.cfg [new file with mode: 0644]
configuration/pam.cfg [new file with mode: 0644]
configuration/path.cfg [new file with mode: 0644]
corpus.py [new file with mode: 0644]
corpusNG.py [new file with mode: 0644]
debian/README [new file with mode: 0644]
debian/README.Debian [new file with mode: 0644]
debian/changelog [new file with mode: 0644]
debian/compat [new file with mode: 0644]
debian/control [new file with mode: 0644]
debian/copyright [new file with mode: 0644]
debian/dirs [new file with mode: 0644]
debian/docs [new file with mode: 0644]
debian/files [new file with mode: 0644]
debian/iramuteq.debhelper.log [new file with mode: 0644]
debian/rules [new file with mode: 0755]
dialog.py [new file with mode: 0755]
dictionnaires/About [new file with mode: 0644]
dictionnaires/expression.txt.back [new file with mode: 0644]
dictionnaires/expression.txt.old [new file with mode: 0644]
dictionnaires/expression_de.txt [new file with mode: 0644]
dictionnaires/expression_en.txt [new file with mode: 0644]
dictionnaires/expression_fr.txt [new file with mode: 0644]
dictionnaires/expression_it.txt [new file with mode: 0644]
dictionnaires/lexique.txt.back [new file with mode: 0644]
dictionnaires/lexique.txt.old [new file with mode: 0644]
dictionnaires/lexique_de.txt [new file with mode: 0644]
dictionnaires/lexique_en.txt [new file with mode: 0644]
dictionnaires/lexique_fr.txt [new file with mode: 0644]
dictionnaires/lexique_it.txt [new file with mode: 0644]
dictionnaires/lexiqueac.txt [new file with mode: 0644]
documentation/Warning_icon.png [new file with mode: 0644]
documentation/documentation-img1.png [new file with mode: 0644]
documentation/documentation-img2.png [new file with mode: 0644]
documentation/documentation.doc [new file with mode: 0644]
documentation/documentation.html [new file with mode: 0644]
documentation/documentation.odt [new file with mode: 0644]
documentation/documentation.pdf [new file with mode: 0644]
documentation/documentation.txt [new file with mode: 0644]
documentation/documentation_cln.doc [new file with mode: 0644]
documentation/documentation_html_m443ae5e9.png [new file with mode: 0644]
documentation/html/documentation.html [new file with mode: 0644]
documentation/similitude.txt [new file with mode: 0644]
documentation/test-wiki [new file with mode: 0644]
extract.py [new file with mode: 0644]
formes.db [new file with mode: 0644]
functions.py [new file with mode: 0644]
gpl-2.0-fr.txt [new file with mode: 0644]
gpl-2.0.txt [new file with mode: 0644]
guifunct.py [new file with mode: 0644]
guiparam3d.py [new file with mode: 0755]
images/LexTexte4.jpg [new file with mode: 0644]
images/Rlogo.jpg [new file with mode: 0644]
images/but_dendro.png [new file with mode: 0644]
images/button_afc.jpg [new file with mode: 0644]
images/button_export.jpg [new file with mode: 0644]
images/button_export.jpg.png [new file with mode: 0644]
images/button_simi.jpg [new file with mode: 0644]
images/iraicone.ico [new file with mode: 0644]
images/iraicone.png [new file with mode: 0644]
images/iraicone.svg [new file with mode: 0644]
images/iraicone16x16.png [new file with mode: 0644]
images/iraicone248x248.png [new file with mode: 0644]
images/iraicone255x255.png [new file with mode: 0644]
images/iraicone32x32.png [new file with mode: 0644]
images/iraicone48x48.png [new file with mode: 0644]
images/python-logo.jpg [new file with mode: 0644]
images/splash.png [new file with mode: 0644]
images/splash.svg [new file with mode: 0644]
images/svn-commit.tmp [new file with mode: 0644]
iracmd.py [new file with mode: 0644]
iramuteq [new file with mode: 0755]
iramuteq.desktop [new file with mode: 0644]
iramuteq.py [new file with mode: 0644]
iramuteq_en.po [new file with mode: 0644]
iramuteq_fr_FR.po [new file with mode: 0644]
iramuteqsvn.desktop [new file with mode: 0644]
iraopen.py [new file with mode: 0644]
layout.py [new file with mode: 0644]
listlex.py [new file with mode: 0644]
locale/en/LC_MESSAGES/iramuteq.mo [new file with mode: 0644]
locale/fr_FR/LC_MESSAGES/iramuteq.mo [new file with mode: 0644]
messages.pot [new file with mode: 0644]
mki18n.py [new file with mode: 0644]
newsimi.py [new file with mode: 0644]
ooolib.py [new file with mode: 0644]
openanalyse.py [new file with mode: 0644]
parse_factiva_html.py [new file with mode: 0644]
parse_factiva_txt.py [new file with mode: 0644]
parse_factiva_txt2.py [new file with mode: 0644]
parse_factiva_xml.py [new file with mode: 0644]
profile_segment.py [new file with mode: 0644]
putcorpusindb.py [new file with mode: 0644]
search_list.py [new file with mode: 0644]
search_tools.py [new file with mode: 0644]
setup.py [new file with mode: 0644]
setup.py.win [new file with mode: 0644]
sheet.py [new file with mode: 0644]
son_fin.wav [new file with mode: 0644]
tabafcm.py [new file with mode: 0644]
tabchdalc.py [new file with mode: 0644]
tabchddist.py [new file with mode: 0644]
tabchi2.py [new file with mode: 0755]
tabfrequence.py [new file with mode: 0644]
tableau.py [new file with mode: 0644]
tabrsimple.py [new file with mode: 0644]
tabsimi.py [new file with mode: 0644]
tabstudent.py [new file with mode: 0644]
tabverges.py [new file with mode: 0644]
testdecoupe.txt [new file with mode: 0644]
textafcuci.py [new file with mode: 0644]
textaslexico.py [new file with mode: 0644]
textchdalc.py [new file with mode: 0644]
textcheckcorpus.py [new file with mode: 0644]
textclassechd.py [new file with mode: 0644]
textdist.py [new file with mode: 0644]
textsimi.py [new file with mode: 0644]
textstat.py [new file with mode: 0644]
textwordcloud.py [new file with mode: 0644]
tree.py [new file with mode: 0644]
ttparser.py [new file with mode: 0644]
uces.db [new file with mode: 0644]
usecorpusNG.py [new file with mode: 0644]
word_stat.py [new file with mode: 0644]

diff --git a/HTML.py b/HTML.py
new file mode 100644 (file)
index 0000000..b03c0a2
--- /dev/null
+++ b/HTML.py
@@ -0,0 +1,493 @@
+#!/usr/bin/python\r
+# -*- coding: iso-8859-1 -*-\r
+"""\r
+HTML.py - v0.04 2009-07-28 Philippe Lagadec\r
+\r
+This module provides a few classes to easily generate HTML code such as tables\r
+and lists.\r
+\r
+Project website: http://www.decalage.info/python/html\r
+\r
+License: CeCILL (open-source GPL compatible), see source code for details.\r
+         http://www.cecill.info\r
+"""\r
+\r
+__version__ = '0.04'\r
+__date__    = '2009-07-28'\r
+__author__  = 'Philippe Lagadec'\r
+\r
+#--- LICENSE ------------------------------------------------------------------\r
+\r
+# Copyright Philippe Lagadec - see http://www.decalage.info/contact for contact info\r
+#\r
+# This module provides a few classes to easily generate HTML tables and lists.\r
+#\r
+# This software is governed by the CeCILL license under French law and\r
+# abiding by the rules of distribution of free software.  You can  use,\r
+# modify and/or redistribute the software under the terms of the CeCILL\r
+# license as circulated by CEA, CNRS and INRIA at the following URL\r
+# "http://www.cecill.info".\r
+#\r
+# A copy of the CeCILL license is also provided in these attached files:\r
+# Licence_CeCILL_V2-en.html and Licence_CeCILL_V2-fr.html\r
+#\r
+# As a counterpart to the access to the source code and  rights to copy,\r
+# modify and redistribute granted by the license, users are provided only\r
+# with a limited warranty  and the software's author, the holder of the\r
+# economic rights, and the successive licensors have only limited\r
+# liability.\r
+#\r
+# In this respect, the user's attention is drawn to the risks associated\r
+# with loading,  using,  modifying and/or developing or reproducing the\r
+# software by the user in light of its specific status of free software,\r
+# that may mean  that it is complicated to manipulate,  and  that  also\r
+# therefore means  that it is reserved for developers  and  experienced\r
+# professionals having in-depth computer knowledge. Users are therefore\r
+# encouraged to load and test the software's suitability as regards their\r
+# requirements in conditions enabling the security of their systems and/or\r
+# data to be ensured and,  more generally, to use and operate it in the\r
+# same conditions as regards security.\r
+#\r
+# The fact that you are presently reading this means that you have had\r
+# knowledge of the CeCILL license and that you accept its terms.\r
+\r
+\r
+#--- CHANGES ------------------------------------------------------------------\r
+\r
+# 2008-10-06 v0.01 PL: - First version\r
+# 2008-10-13 v0.02 PL: - added cellspacing and cellpadding to table\r
+#                      - added functions to ease one-step creation of tables\r
+#                        and lists\r
+# 2009-07-21 v0.03 PL: - added column attributes and styles (first attempt)\r
+#                        (thanks to an idea submitted by Michal Cernoevic)\r
+# 2009-07-28 v0.04 PL: - improved column styles, workaround for Mozilla\r
+\r
+\r
+#-------------------------------------------------------------------------------\r
+#TODO:\r
+# - method to return a generator (yield each row) instead of a single string\r
+# - unicode support (input and output)\r
+# - escape text in cells (optional)\r
+# - constants for standard colors\r
+# - use lxml to generate well-formed HTML ?\r
+# - add classes/functions to generate a HTML page, paragraphs, headings, etc...\r
+\r
+\r
+#--- THANKS --------------------------------------------------------------------\r
+\r
+# - Michal Cernoevic, for the idea of column styles.\r
+\r
+#--- REFERENCES ----------------------------------------------------------------\r
+\r
+# HTML 4.01 specs: http://www.w3.org/TR/html4/struct/tables.html\r
+\r
+# Colors: http://www.w3.org/TR/html4/types.html#type-color\r
+\r
+# Columns alignement and style, one of the oldest and trickiest bugs in Mozilla:\r
+# https://bugzilla.mozilla.org/show_bug.cgi?id=915\r
+\r
+\r
+#--- CONSTANTS -----------------------------------------------------------------\r
+\r
+# Table style to get thin black lines in Mozilla/Firefox instead of 3D borders\r
+TABLE_STYLE_THINBORDER = "border: 1px solid #000000; border-collapse: collapse;"\r
+#TABLE_STYLE_THINBORDER = "border: 1px solid #000000;"\r
+\r
+\r
+#=== CLASSES ===================================================================\r
+\r
+class TableCell (object):\r
+    """\r
+    a TableCell object is used to create a cell in a HTML table. (TD or TH)\r
+\r
+    Attributes:\r
+    - text: text in the cell (may contain HTML tags). May be any object which\r
+            can be converted to a string using str().\r
+    - header: bool, false for a normal data cell (TD), true for a header cell (TH)\r
+    - bgcolor: str, background color\r
+    - width: str, width\r
+    - align: str, horizontal alignement (left, center, right, justify or char)\r
+    - char: str, alignment character, decimal point if not specified\r
+    - charoff: str, see HTML specs\r
+    - valign: str, vertical alignment (top|middle|bottom|baseline)\r
+    - style: str, CSS style\r
+    - attribs: dict, additional attributes for the TD/TH tag\r
+\r
+    Reference: http://www.w3.org/TR/html4/struct/tables.html#h-11.2.6\r
+    """\r
+\r
+    def __init__(self, text="", bgcolor=None, header=False, width=None,\r
+                align=None, char=None, charoff=None, valign=None, style=None,\r
+                attribs=None):\r
+        """TableCell constructor"""\r
+        self.text    = text\r
+        self.bgcolor = bgcolor\r
+        self.header  = header\r
+        self.width   = width\r
+        self.align   = align\r
+        self.char    = char\r
+        self.charoff = charoff\r
+        self.valign  = valign\r
+        self.style   = style\r
+        self.attribs = attribs\r
+        if attribs==None:\r
+            self.attribs = {}\r
+\r
+    def __str__(self):\r
+        """return the HTML code for the table cell as a string"""\r
+        attribs_str = ""\r
+        if self.bgcolor: self.attribs['bgcolor'] = self.bgcolor\r
+        if self.width:   self.attribs['width']   = self.width\r
+        if self.align:   self.attribs['align']   = self.align\r
+        if self.char:    self.attribs['char']    = self.char\r
+        if self.charoff: self.attribs['charoff'] = self.charoff\r
+        if self.valign:  self.attribs['valign']  = self.valign\r
+        if self.style:   self.attribs['style']   = self.style\r
+        for attr in self.attribs:\r
+            attribs_str += ' %s="%s"' % (attr, self.attribs[attr])\r
+        if self.text:\r
+            text = str(self.text)\r
+        else:\r
+            # An empty cell should at least contain a non-breaking space\r
+            text = '&nbsp;'\r
+        if self.header:\r
+            return '  <TH%s>%s</TH>\n' % (attribs_str, text)\r
+        else:\r
+            return '  <TD%s>%s</TD>\n' % (attribs_str, text)\r
+\r
+#-------------------------------------------------------------------------------\r
+\r
+class TableRow (object):\r
+    """\r
+    a TableRow object is used to create a row in a HTML table. (TR tag)\r
+\r
+    Attributes:\r
+    - cells: list, tuple or any iterable, containing one string or TableCell\r
+             object for each cell\r
+    - header: bool, true for a header row (TH), false for a normal data row (TD)\r
+    - bgcolor: str, background color\r
+    - col_align, col_valign, col_char, col_charoff, col_styles: see Table class\r
+    - attribs: dict, additional attributes for the TR tag\r
+\r
+    Reference: http://www.w3.org/TR/html4/struct/tables.html#h-11.2.5\r
+    """\r
+\r
+    def __init__(self, cells=None, bgcolor=None, header=False, attribs=None,\r
+                col_align=None, col_valign=None, col_char=None,\r
+                col_charoff=None, col_styles=None):\r
+        """TableCell constructor"""\r
+        self.bgcolor     = bgcolor\r
+        self.cells       = cells\r
+        self.header      = header\r
+        self.col_align   = col_align\r
+        self.col_valign  = col_valign\r
+        self.col_char    = col_char\r
+        self.col_charoff = col_charoff\r
+        self.col_styles  = col_styles\r
+        self.attribs     = attribs\r
+        if attribs==None:\r
+            self.attribs = {}\r
+\r
+    def __str__(self):\r
+        """return the HTML code for the table row as a string"""\r
+        attribs_str = ""\r
+        if self.bgcolor: self.attribs['bgcolor'] = self.bgcolor\r
+        for attr in self.attribs:\r
+            attribs_str += ' %s="%s"' % (attr, self.attribs[attr])\r
+        result = ' <TR%s>\n' % attribs_str\r
+        for cell in self.cells:\r
+            col = self.cells.index(cell)    # cell column index\r
+            if not isinstance(cell, TableCell):\r
+                cell = TableCell(cell, header=self.header)\r
+            # apply column alignment if specified:\r
+            if self.col_align and cell.align==None:\r
+                cell.align = self.col_align[col]\r
+            if self.col_char and cell.char==None:\r
+                cell.char = self.col_char[col]\r
+            if self.col_charoff and cell.charoff==None:\r
+                cell.charoff = self.col_charoff[col]\r
+            if self.col_valign and cell.valign==None:\r
+                cell.valign = self.col_valign[col]\r
+            # apply column style if specified:\r
+            if self.col_styles and cell.style==None:\r
+                cell.style = self.col_styles[col]\r
+            result += str(cell)\r
+        result += ' </TR>\n'\r
+        return result\r
+\r
+#-------------------------------------------------------------------------------\r
+\r
+class Table (object):\r
+    """\r
+    a Table object is used to create a HTML table. (TABLE tag)\r
+\r
+    Attributes:\r
+    - rows: list, tuple or any iterable, containing one iterable or TableRow\r
+            object for each row\r
+    - header_row: list, tuple or any iterable, containing the header row (optional)\r
+    - border: str or int, border width\r
+    - style: str, table style in CSS syntax (thin black borders by default)\r
+    - width: str, width of the table on the page\r
+    - attribs: dict, additional attributes for the TABLE tag\r
+    - col_width: list or tuple defining width for each column\r
+    - col_align: list or tuple defining horizontal alignment for each column\r
+    - col_char: list or tuple defining alignment character for each column\r
+    - col_charoff: list or tuple defining charoff attribute for each column\r
+    - col_valign: list or tuple defining vertical alignment for each column\r
+    - col_styles: list or tuple of HTML styles for each column\r
+\r
+    Reference: http://www.w3.org/TR/html4/struct/tables.html#h-11.2.1\r
+    """\r
+\r
+    def __init__(self, rows=None, border='1', style=None, width=None,\r
+                cellspacing=None, cellpadding=4, attribs=None, header_row=None,\r
+                col_width=None, col_align=None, col_valign=None,\r
+                col_char=None, col_charoff=None, col_styles=None):\r
+        """TableCell constructor"""\r
+        self.border = border\r
+        self.style = style\r
+        # style for thin borders by default\r
+        if style == None: self.style = TABLE_STYLE_THINBORDER\r
+        self.width       = width\r
+        self.cellspacing = cellspacing\r
+        self.cellpadding = cellpadding\r
+        self.header_row  = header_row\r
+        self.rows        = rows\r
+        if not rows: self.rows = []\r
+        self.attribs     = attribs\r
+        if not attribs: self.attribs = {}\r
+        self.col_width   = col_width\r
+        self.col_align   = col_align\r
+        self.col_char    = col_char\r
+        self.col_charoff = col_charoff\r
+        self.col_valign  = col_valign\r
+        self.col_styles  = col_styles\r
+\r
+    def __str__(self):\r
+        """return the HTML code for the table as a string"""\r
+        attribs_str = ""\r
+        if self.border: self.attribs['border'] = self.border\r
+        if self.style:  self.attribs['style'] = self.style\r
+        if self.width:  self.attribs['width'] = self.width\r
+        if self.cellspacing:  self.attribs['cellspacing'] = self.cellspacing\r
+        if self.cellpadding:  self.attribs['cellpadding'] = self.cellpadding\r
+        for attr in self.attribs:\r
+            attribs_str += ' %s="%s"' % (attr, self.attribs[attr])\r
+        result = '<TABLE%s>\n' % attribs_str\r
+        # insert column tags and attributes if specified:\r
+        if self.col_width:\r
+            for width in self.col_width:\r
+                result += '  <COL width="%s">\n' % width\r
+        # The following code would also generate column attributes for style\r
+        # and alignement according to HTML4 specs,\r
+        # BUT it is not supported completely (only width) on Mozilla Firefox:\r
+        # see https://bugzilla.mozilla.org/show_bug.cgi?id=915\r
+##        n_cols = max(len(self.col_styles), len(self.col_width),\r
+##                     len(self.col_align), len(self.col_valign))\r
+##        for i in range(n_cols):\r
+##            col = ''\r
+##            try:\r
+##                if self.col_styles[i]:\r
+##                    col += ' style="%s"' % self.col_styles[i]\r
+##            except: pass\r
+##            try:\r
+##                if self.col_width[i]:\r
+##                    col += ' width="%s"' % self.col_width[i]\r
+##            except: pass\r
+##            try:\r
+##                if self.col_align[i]:\r
+##                    col += ' align="%s"' % self.col_align[i]\r
+##            except: pass\r
+##            try:\r
+##                if self.col_valign[i]:\r
+##                    col += ' valign="%s"' % self.col_valign[i]\r
+##            except: pass\r
+##            result += '<COL%s>\n' % col\r
+        # First insert a header row if specified:\r
+        if self.header_row:\r
+            if not isinstance(self.header_row, TableRow):\r
+                result += str(TableRow(self.header_row, header=True))\r
+            else:\r
+                result += str(self.header_row)\r
+        # Then all data rows:\r
+        for row in self.rows:\r
+            if not isinstance(row, TableRow):\r
+                row = TableRow(row)\r
+            # apply column alignments  and styles to each row if specified:\r
+            # (Mozilla bug workaround)\r
+            if self.col_align and not row.col_align:\r
+                row.col_align = self.col_align\r
+            if self.col_char and not row.col_char:\r
+                row.col_char = self.col_char\r
+            if self.col_charoff and not row.col_charoff:\r
+                row.col_charoff = self.col_charoff\r
+            if self.col_valign and not row.col_valign:\r
+                row.col_valign = self.col_valign\r
+            if self.col_styles and not row.col_styles:\r
+                row.col_styles = self.col_styles\r
+            result += str(row)\r
+        result += '</TABLE>'\r
+        return result\r
+\r
+\r
+#-------------------------------------------------------------------------------\r
+\r
+class List (object):\r
+    """\r
+    a List object is used to create an ordered or unordered list in HTML.\r
+    (UL/OL tag)\r
+\r
+    Attributes:\r
+    - lines: list, tuple or any iterable, containing one string for each line\r
+    - ordered: bool, choice between an ordered (OL) or unordered list (UL)\r
+    - attribs: dict, additional attributes for the OL/UL tag\r
+\r
+    Reference: http://www.w3.org/TR/html4/struct/lists.html\r
+    """\r
+\r
+    def __init__(self, lines=None, ordered=False, start=None, attribs=None):\r
+        """List constructor"""\r
+        if lines:\r
+            self.lines = lines\r
+        else:\r
+            self.lines = []\r
+        self.ordered = ordered\r
+        self.start = start\r
+        if attribs:\r
+            self.attribs = attribs\r
+        else:\r
+            self.attribs = {}\r
+\r
+    def __str__(self):\r
+        """return the HTML code for the list as a string"""\r
+        attribs_str = ""\r
+        if self.start:  self.attribs['start'] = self.start\r
+        for attr in self.attribs:\r
+            attribs_str += ' %s="%s"' % (attr, self.attribs[attr])\r
+        if self.ordered: tag = 'OL'\r
+        else:            tag = 'UL'\r
+        result = '<%s%s>\n' % (tag, attribs_str)\r
+        for line in self.lines:\r
+            result += ' <LI>%s\n' % str(line)\r
+        result += '</%s>\n' % tag\r
+        return result\r
+\r
+\r
+##class Link (object):\r
+##    """\r
+##    a Link object is used to create link in HTML. (<a> tag)\r
+##\r
+##    Attributes:\r
+##    - text: str, text of the link\r
+##    - url: str, URL of the link\r
+##    - attribs: dict, additional attributes for the A tag\r
+##\r
+##    Reference: http://www.w3.org/TR/html4\r
+##    """\r
+##\r
+##    def __init__(self, text, url=None, attribs=None):\r
+##        """Link constructor"""\r
+##        self.text = text\r
+##        self.url = url\r
+##        if attribs:\r
+##            self.attribs = attribs\r
+##        else:\r
+##            self.attribs = {}\r
+##\r
+##    def __str__(self):\r
+##        """return the HTML code for the link as a string"""\r
+##        attribs_str = ""\r
+##        if self.url:  self.attribs['href'] = self.url\r
+##        for attr in self.attribs:\r
+##            attribs_str += ' %s="%s"' % (attr, self.attribs[attr])\r
+##        return '<a%s>%s</a>' % (attribs_str, text)\r
+\r
+\r
+#=== FUNCTIONS ================================================================\r
+\r
+# much simpler definition of a link as a function:\r
+def Link(text, url):\r
+    return '<a href="%s">%s</a>' % (url, text)\r
+\r
+def link(text, url):\r
+    return '<a href="%s">%s</a>' % (url, text)\r
+\r
+def table(*args, **kwargs):\r
+    'return HTML code for a table as a string. See Table class for parameters.'\r
+    return str(Table(*args, **kwargs))\r
+\r
+def list(*args, **kwargs):\r
+    'return HTML code for a list as a string. See List class for parameters.'\r
+    return str(List(*args, **kwargs))\r
+\r
+\r
+#=== MAIN =====================================================================\r
+\r
+# Show sample usage when this file is launched as a script.\r
+\r
+if __name__ == '__main__':\r
+\r
+    # open an HTML file to show output in a browser\r
+    f = open('test.html', 'w')\r
+\r
+    t = Table()\r
+    t.rows.append(TableRow(['A', 'B', 'C'], header=True))\r
+    t.rows.append(TableRow(['D', 'E', 'F']))\r
+    t.rows.append(('i', 'j', 'k'))\r
+    f.write(str(t) + '<p>\n')\r
+    print str(t)\r
+    print '-'*79\r
+\r
+    t2 = Table([\r
+            ('1', '2'),\r
+            ['3', '4']\r
+        ], width='100%', header_row=('col1', 'col2'),\r
+        col_width=('', '75%'))\r
+    f.write(str(t2) + '<p>\n')\r
+    print t2\r
+    print '-'*79\r
+\r
+    t2.rows.append(['5', '6'])\r
+    t2.rows[1][1] = TableCell('new', bgcolor='red')\r
+    t2.rows.append(TableRow(['7', '8'], attribs={'align': 'center'}))\r
+    f.write(str(t2) + '<p>\n')\r
+    print t2\r
+    print '-'*79\r
+\r
+    # sample table with column attributes and styles:\r
+    table_data = [\r
+            ['Smith',       'John',         30,    4.5],\r
+            ['Carpenter',   'Jack',         47,    7],\r
+            ['Johnson',     'Paul',         62,    10.55],\r
+        ]\r
+    htmlcode = HTML.table(table_data,\r
+        header_row = ['Last name',   'First name',   'Age', 'Score'],\r
+        col_width=['', '20%', '10%', '10%'],\r
+        col_align=['left', 'center', 'right', 'char'],\r
+        col_styles=['font-size: large', '', 'font-size: small', 'background-color:yellow'])\r
+    f.write(htmlcode + '<p>\n')\r
+    print htmlcode\r
+    print '-'*79\r
+\r
+    def gen_table_squares(n):\r
+        """\r
+        Generator to create table rows for integers from 1 to n\r
+        """\r
+##        # First, header row:\r
+##        yield TableRow(('x', 'square(x)'), header=True, bgcolor='blue')\r
+##        # Then all rows:\r
+        for x in range(1, n+1):\r
+            yield (x, x*x)\r
+\r
+    t = Table(rows=gen_table_squares(10), header_row=('x', 'square(x)'))\r
+    f.write(str(t) + '<p>\n')\r
+\r
+    print '-'*79\r
+    l = List(['aaa', 'bbb', 'ccc'])\r
+    f.write(str(l) + '<p>\n')\r
+    l.ordered = True\r
+    f.write(str(l) + '<p>\n')\r
+    l.start=10\r
+    f.write(str(l) + '<p>\n')\r
+\r
+    f.close()\r
diff --git a/HTML/HTML.py b/HTML/HTML.py
new file mode 100644 (file)
index 0000000..b03c0a2
--- /dev/null
@@ -0,0 +1,493 @@
+#!/usr/bin/python\r
+# -*- coding: iso-8859-1 -*-\r
+"""\r
+HTML.py - v0.04 2009-07-28 Philippe Lagadec\r
+\r
+This module provides a few classes to easily generate HTML code such as tables\r
+and lists.\r
+\r
+Project website: http://www.decalage.info/python/html\r
+\r
+License: CeCILL (open-source GPL compatible), see source code for details.\r
+         http://www.cecill.info\r
+"""\r
+\r
+__version__ = '0.04'\r
+__date__    = '2009-07-28'\r
+__author__  = 'Philippe Lagadec'\r
+\r
+#--- LICENSE ------------------------------------------------------------------\r
+\r
+# Copyright Philippe Lagadec - see http://www.decalage.info/contact for contact info\r
+#\r
+# This module provides a few classes to easily generate HTML tables and lists.\r
+#\r
+# This software is governed by the CeCILL license under French law and\r
+# abiding by the rules of distribution of free software.  You can  use,\r
+# modify and/or redistribute the software under the terms of the CeCILL\r
+# license as circulated by CEA, CNRS and INRIA at the following URL\r
+# "http://www.cecill.info".\r
+#\r
+# A copy of the CeCILL license is also provided in these attached files:\r
+# Licence_CeCILL_V2-en.html and Licence_CeCILL_V2-fr.html\r
+#\r
+# As a counterpart to the access to the source code and  rights to copy,\r
+# modify and redistribute granted by the license, users are provided only\r
+# with a limited warranty  and the software's author, the holder of the\r
+# economic rights, and the successive licensors have only limited\r
+# liability.\r
+#\r
+# In this respect, the user's attention is drawn to the risks associated\r
+# with loading,  using,  modifying and/or developing or reproducing the\r
+# software by the user in light of its specific status of free software,\r
+# that may mean  that it is complicated to manipulate,  and  that  also\r
+# therefore means  that it is reserved for developers  and  experienced\r
+# professionals having in-depth computer knowledge. Users are therefore\r
+# encouraged to load and test the software's suitability as regards their\r
+# requirements in conditions enabling the security of their systems and/or\r
+# data to be ensured and,  more generally, to use and operate it in the\r
+# same conditions as regards security.\r
+#\r
+# The fact that you are presently reading this means that you have had\r
+# knowledge of the CeCILL license and that you accept its terms.\r
+\r
+\r
+#--- CHANGES ------------------------------------------------------------------\r
+\r
+# 2008-10-06 v0.01 PL: - First version\r
+# 2008-10-13 v0.02 PL: - added cellspacing and cellpadding to table\r
+#                      - added functions to ease one-step creation of tables\r
+#                        and lists\r
+# 2009-07-21 v0.03 PL: - added column attributes and styles (first attempt)\r
+#                        (thanks to an idea submitted by Michal Cernoevic)\r
+# 2009-07-28 v0.04 PL: - improved column styles, workaround for Mozilla\r
+\r
+\r
+#-------------------------------------------------------------------------------\r
+#TODO:\r
+# - method to return a generator (yield each row) instead of a single string\r
+# - unicode support (input and output)\r
+# - escape text in cells (optional)\r
+# - constants for standard colors\r
+# - use lxml to generate well-formed HTML ?\r
+# - add classes/functions to generate a HTML page, paragraphs, headings, etc...\r
+\r
+\r
+#--- THANKS --------------------------------------------------------------------\r
+\r
+# - Michal Cernoevic, for the idea of column styles.\r
+\r
+#--- REFERENCES ----------------------------------------------------------------\r
+\r
+# HTML 4.01 specs: http://www.w3.org/TR/html4/struct/tables.html\r
+\r
+# Colors: http://www.w3.org/TR/html4/types.html#type-color\r
+\r
+# Columns alignement and style, one of the oldest and trickiest bugs in Mozilla:\r
+# https://bugzilla.mozilla.org/show_bug.cgi?id=915\r
+\r
+\r
+#--- CONSTANTS -----------------------------------------------------------------\r
+\r
+# Table style to get thin black lines in Mozilla/Firefox instead of 3D borders\r
+TABLE_STYLE_THINBORDER = "border: 1px solid #000000; border-collapse: collapse;"\r
+#TABLE_STYLE_THINBORDER = "border: 1px solid #000000;"\r
+\r
+\r
+#=== CLASSES ===================================================================\r
+\r
+class TableCell (object):\r
+    """\r
+    a TableCell object is used to create a cell in a HTML table. (TD or TH)\r
+\r
+    Attributes:\r
+    - text: text in the cell (may contain HTML tags). May be any object which\r
+            can be converted to a string using str().\r
+    - header: bool, false for a normal data cell (TD), true for a header cell (TH)\r
+    - bgcolor: str, background color\r
+    - width: str, width\r
+    - align: str, horizontal alignement (left, center, right, justify or char)\r
+    - char: str, alignment character, decimal point if not specified\r
+    - charoff: str, see HTML specs\r
+    - valign: str, vertical alignment (top|middle|bottom|baseline)\r
+    - style: str, CSS style\r
+    - attribs: dict, additional attributes for the TD/TH tag\r
+\r
+    Reference: http://www.w3.org/TR/html4/struct/tables.html#h-11.2.6\r
+    """\r
+\r
+    def __init__(self, text="", bgcolor=None, header=False, width=None,\r
+                align=None, char=None, charoff=None, valign=None, style=None,\r
+                attribs=None):\r
+        """TableCell constructor"""\r
+        self.text    = text\r
+        self.bgcolor = bgcolor\r
+        self.header  = header\r
+        self.width   = width\r
+        self.align   = align\r
+        self.char    = char\r
+        self.charoff = charoff\r
+        self.valign  = valign\r
+        self.style   = style\r
+        self.attribs = attribs\r
+        if attribs==None:\r
+            self.attribs = {}\r
+\r
+    def __str__(self):\r
+        """return the HTML code for the table cell as a string"""\r
+        attribs_str = ""\r
+        if self.bgcolor: self.attribs['bgcolor'] = self.bgcolor\r
+        if self.width:   self.attribs['width']   = self.width\r
+        if self.align:   self.attribs['align']   = self.align\r
+        if self.char:    self.attribs['char']    = self.char\r
+        if self.charoff: self.attribs['charoff'] = self.charoff\r
+        if self.valign:  self.attribs['valign']  = self.valign\r
+        if self.style:   self.attribs['style']   = self.style\r
+        for attr in self.attribs:\r
+            attribs_str += ' %s="%s"' % (attr, self.attribs[attr])\r
+        if self.text:\r
+            text = str(self.text)\r
+        else:\r
+            # An empty cell should at least contain a non-breaking space\r
+            text = '&nbsp;'\r
+        if self.header:\r
+            return '  <TH%s>%s</TH>\n' % (attribs_str, text)\r
+        else:\r
+            return '  <TD%s>%s</TD>\n' % (attribs_str, text)\r
+\r
+#-------------------------------------------------------------------------------\r
+\r
+class TableRow (object):\r
+    """\r
+    a TableRow object is used to create a row in a HTML table. (TR tag)\r
+\r
+    Attributes:\r
+    - cells: list, tuple or any iterable, containing one string or TableCell\r
+             object for each cell\r
+    - header: bool, true for a header row (TH), false for a normal data row (TD)\r
+    - bgcolor: str, background color\r
+    - col_align, col_valign, col_char, col_charoff, col_styles: see Table class\r
+    - attribs: dict, additional attributes for the TR tag\r
+\r
+    Reference: http://www.w3.org/TR/html4/struct/tables.html#h-11.2.5\r
+    """\r
+\r
+    def __init__(self, cells=None, bgcolor=None, header=False, attribs=None,\r
+                col_align=None, col_valign=None, col_char=None,\r
+                col_charoff=None, col_styles=None):\r
+        """TableCell constructor"""\r
+        self.bgcolor     = bgcolor\r
+        self.cells       = cells\r
+        self.header      = header\r
+        self.col_align   = col_align\r
+        self.col_valign  = col_valign\r
+        self.col_char    = col_char\r
+        self.col_charoff = col_charoff\r
+        self.col_styles  = col_styles\r
+        self.attribs     = attribs\r
+        if attribs==None:\r
+            self.attribs = {}\r
+\r
+    def __str__(self):\r
+        """return the HTML code for the table row as a string"""\r
+        attribs_str = ""\r
+        if self.bgcolor: self.attribs['bgcolor'] = self.bgcolor\r
+        for attr in self.attribs:\r
+            attribs_str += ' %s="%s"' % (attr, self.attribs[attr])\r
+        result = ' <TR%s>\n' % attribs_str\r
+        for cell in self.cells:\r
+            col = self.cells.index(cell)    # cell column index\r
+            if not isinstance(cell, TableCell):\r
+                cell = TableCell(cell, header=self.header)\r
+            # apply column alignment if specified:\r
+            if self.col_align and cell.align==None:\r
+                cell.align = self.col_align[col]\r
+            if self.col_char and cell.char==None:\r
+                cell.char = self.col_char[col]\r
+            if self.col_charoff and cell.charoff==None:\r
+                cell.charoff = self.col_charoff[col]\r
+            if self.col_valign and cell.valign==None:\r
+                cell.valign = self.col_valign[col]\r
+            # apply column style if specified:\r
+            if self.col_styles and cell.style==None:\r
+                cell.style = self.col_styles[col]\r
+            result += str(cell)\r
+        result += ' </TR>\n'\r
+        return result\r
+\r
+#-------------------------------------------------------------------------------\r
+\r
+class Table (object):\r
+    """\r
+    a Table object is used to create a HTML table. (TABLE tag)\r
+\r
+    Attributes:\r
+    - rows: list, tuple or any iterable, containing one iterable or TableRow\r
+            object for each row\r
+    - header_row: list, tuple or any iterable, containing the header row (optional)\r
+    - border: str or int, border width\r
+    - style: str, table style in CSS syntax (thin black borders by default)\r
+    - width: str, width of the table on the page\r
+    - attribs: dict, additional attributes for the TABLE tag\r
+    - col_width: list or tuple defining width for each column\r
+    - col_align: list or tuple defining horizontal alignment for each column\r
+    - col_char: list or tuple defining alignment character for each column\r
+    - col_charoff: list or tuple defining charoff attribute for each column\r
+    - col_valign: list or tuple defining vertical alignment for each column\r
+    - col_styles: list or tuple of HTML styles for each column\r
+\r
+    Reference: http://www.w3.org/TR/html4/struct/tables.html#h-11.2.1\r
+    """\r
+\r
+    def __init__(self, rows=None, border='1', style=None, width=None,\r
+                cellspacing=None, cellpadding=4, attribs=None, header_row=None,\r
+                col_width=None, col_align=None, col_valign=None,\r
+                col_char=None, col_charoff=None, col_styles=None):\r
+        """TableCell constructor"""\r
+        self.border = border\r
+        self.style = style\r
+        # style for thin borders by default\r
+        if style == None: self.style = TABLE_STYLE_THINBORDER\r
+        self.width       = width\r
+        self.cellspacing = cellspacing\r
+        self.cellpadding = cellpadding\r
+        self.header_row  = header_row\r
+        self.rows        = rows\r
+        if not rows: self.rows = []\r
+        self.attribs     = attribs\r
+        if not attribs: self.attribs = {}\r
+        self.col_width   = col_width\r
+        self.col_align   = col_align\r
+        self.col_char    = col_char\r
+        self.col_charoff = col_charoff\r
+        self.col_valign  = col_valign\r
+        self.col_styles  = col_styles\r
+\r
+    def __str__(self):\r
+        """return the HTML code for the table as a string"""\r
+        attribs_str = ""\r
+        if self.border: self.attribs['border'] = self.border\r
+        if self.style:  self.attribs['style'] = self.style\r
+        if self.width:  self.attribs['width'] = self.width\r
+        if self.cellspacing:  self.attribs['cellspacing'] = self.cellspacing\r
+        if self.cellpadding:  self.attribs['cellpadding'] = self.cellpadding\r
+        for attr in self.attribs:\r
+            attribs_str += ' %s="%s"' % (attr, self.attribs[attr])\r
+        result = '<TABLE%s>\n' % attribs_str\r
+        # insert column tags and attributes if specified:\r
+        if self.col_width:\r
+            for width in self.col_width:\r
+                result += '  <COL width="%s">\n' % width\r
+        # The following code would also generate column attributes for style\r
+        # and alignement according to HTML4 specs,\r
+        # BUT it is not supported completely (only width) on Mozilla Firefox:\r
+        # see https://bugzilla.mozilla.org/show_bug.cgi?id=915\r
+##        n_cols = max(len(self.col_styles), len(self.col_width),\r
+##                     len(self.col_align), len(self.col_valign))\r
+##        for i in range(n_cols):\r
+##            col = ''\r
+##            try:\r
+##                if self.col_styles[i]:\r
+##                    col += ' style="%s"' % self.col_styles[i]\r
+##            except: pass\r
+##            try:\r
+##                if self.col_width[i]:\r
+##                    col += ' width="%s"' % self.col_width[i]\r
+##            except: pass\r
+##            try:\r
+##                if self.col_align[i]:\r
+##                    col += ' align="%s"' % self.col_align[i]\r
+##            except: pass\r
+##            try:\r
+##                if self.col_valign[i]:\r
+##                    col += ' valign="%s"' % self.col_valign[i]\r
+##            except: pass\r
+##            result += '<COL%s>\n' % col\r
+        # First insert a header row if specified:\r
+        if self.header_row:\r
+            if not isinstance(self.header_row, TableRow):\r
+                result += str(TableRow(self.header_row, header=True))\r
+            else:\r
+                result += str(self.header_row)\r
+        # Then all data rows:\r
+        for row in self.rows:\r
+            if not isinstance(row, TableRow):\r
+                row = TableRow(row)\r
+            # apply column alignments  and styles to each row if specified:\r
+            # (Mozilla bug workaround)\r
+            if self.col_align and not row.col_align:\r
+                row.col_align = self.col_align\r
+            if self.col_char and not row.col_char:\r
+                row.col_char = self.col_char\r
+            if self.col_charoff and not row.col_charoff:\r
+                row.col_charoff = self.col_charoff\r
+            if self.col_valign and not row.col_valign:\r
+                row.col_valign = self.col_valign\r
+            if self.col_styles and not row.col_styles:\r
+                row.col_styles = self.col_styles\r
+            result += str(row)\r
+        result += '</TABLE>'\r
+        return result\r
+\r
+\r
+#-------------------------------------------------------------------------------\r
+\r
+class List (object):\r
+    """\r
+    a List object is used to create an ordered or unordered list in HTML.\r
+    (UL/OL tag)\r
+\r
+    Attributes:\r
+    - lines: list, tuple or any iterable, containing one string for each line\r
+    - ordered: bool, choice between an ordered (OL) or unordered list (UL)\r
+    - attribs: dict, additional attributes for the OL/UL tag\r
+\r
+    Reference: http://www.w3.org/TR/html4/struct/lists.html\r
+    """\r
+\r
+    def __init__(self, lines=None, ordered=False, start=None, attribs=None):\r
+        """List constructor"""\r
+        if lines:\r
+            self.lines = lines\r
+        else:\r
+            self.lines = []\r
+        self.ordered = ordered\r
+        self.start = start\r
+        if attribs:\r
+            self.attribs = attribs\r
+        else:\r
+            self.attribs = {}\r
+\r
+    def __str__(self):\r
+        """return the HTML code for the list as a string"""\r
+        attribs_str = ""\r
+        if self.start:  self.attribs['start'] = self.start\r
+        for attr in self.attribs:\r
+            attribs_str += ' %s="%s"' % (attr, self.attribs[attr])\r
+        if self.ordered: tag = 'OL'\r
+        else:            tag = 'UL'\r
+        result = '<%s%s>\n' % (tag, attribs_str)\r
+        for line in self.lines:\r
+            result += ' <LI>%s\n' % str(line)\r
+        result += '</%s>\n' % tag\r
+        return result\r
+\r
+\r
+##class Link (object):\r
+##    """\r
+##    a Link object is used to create link in HTML. (<a> tag)\r
+##\r
+##    Attributes:\r
+##    - text: str, text of the link\r
+##    - url: str, URL of the link\r
+##    - attribs: dict, additional attributes for the A tag\r
+##\r
+##    Reference: http://www.w3.org/TR/html4\r
+##    """\r
+##\r
+##    def __init__(self, text, url=None, attribs=None):\r
+##        """Link constructor"""\r
+##        self.text = text\r
+##        self.url = url\r
+##        if attribs:\r
+##            self.attribs = attribs\r
+##        else:\r
+##            self.attribs = {}\r
+##\r
+##    def __str__(self):\r
+##        """return the HTML code for the link as a string"""\r
+##        attribs_str = ""\r
+##        if self.url:  self.attribs['href'] = self.url\r
+##        for attr in self.attribs:\r
+##            attribs_str += ' %s="%s"' % (attr, self.attribs[attr])\r
+##        return '<a%s>%s</a>' % (attribs_str, text)\r
+\r
+\r
+#=== FUNCTIONS ================================================================\r
+\r
+# much simpler definition of a link as a function:\r
+def Link(text, url):\r
+    return '<a href="%s">%s</a>' % (url, text)\r
+\r
+def link(text, url):\r
+    return '<a href="%s">%s</a>' % (url, text)\r
+\r
+def table(*args, **kwargs):\r
+    'return HTML code for a table as a string. See Table class for parameters.'\r
+    return str(Table(*args, **kwargs))\r
+\r
+def list(*args, **kwargs):\r
+    'return HTML code for a list as a string. See List class for parameters.'\r
+    return str(List(*args, **kwargs))\r
+\r
+\r
+#=== MAIN =====================================================================\r
+\r
+# Show sample usage when this file is launched as a script.\r
+\r
+if __name__ == '__main__':\r
+\r
+    # open an HTML file to show output in a browser\r
+    f = open('test.html', 'w')\r
+\r
+    t = Table()\r
+    t.rows.append(TableRow(['A', 'B', 'C'], header=True))\r
+    t.rows.append(TableRow(['D', 'E', 'F']))\r
+    t.rows.append(('i', 'j', 'k'))\r
+    f.write(str(t) + '<p>\n')\r
+    print str(t)\r
+    print '-'*79\r
+\r
+    t2 = Table([\r
+            ('1', '2'),\r
+            ['3', '4']\r
+        ], width='100%', header_row=('col1', 'col2'),\r
+        col_width=('', '75%'))\r
+    f.write(str(t2) + '<p>\n')\r
+    print t2\r
+    print '-'*79\r
+\r
+    t2.rows.append(['5', '6'])\r
+    t2.rows[1][1] = TableCell('new', bgcolor='red')\r
+    t2.rows.append(TableRow(['7', '8'], attribs={'align': 'center'}))\r
+    f.write(str(t2) + '<p>\n')\r
+    print t2\r
+    print '-'*79\r
+\r
+    # sample table with column attributes and styles:\r
+    table_data = [\r
+            ['Smith',       'John',         30,    4.5],\r
+            ['Carpenter',   'Jack',         47,    7],\r
+            ['Johnson',     'Paul',         62,    10.55],\r
+        ]\r
+    htmlcode = HTML.table(table_data,\r
+        header_row = ['Last name',   'First name',   'Age', 'Score'],\r
+        col_width=['', '20%', '10%', '10%'],\r
+        col_align=['left', 'center', 'right', 'char'],\r
+        col_styles=['font-size: large', '', 'font-size: small', 'background-color:yellow'])\r
+    f.write(htmlcode + '<p>\n')\r
+    print htmlcode\r
+    print '-'*79\r
+\r
+    def gen_table_squares(n):\r
+        """\r
+        Generator to create table rows for integers from 1 to n\r
+        """\r
+##        # First, header row:\r
+##        yield TableRow(('x', 'square(x)'), header=True, bgcolor='blue')\r
+##        # Then all rows:\r
+        for x in range(1, n+1):\r
+            yield (x, x*x)\r
+\r
+    t = Table(rows=gen_table_squares(10), header_row=('x', 'square(x)'))\r
+    f.write(str(t) + '<p>\n')\r
+\r
+    print '-'*79\r
+    l = List(['aaa', 'bbb', 'ccc'])\r
+    f.write(str(l) + '<p>\n')\r
+    l.ordered = True\r
+    f.write(str(l) + '<p>\n')\r
+    l.start=10\r
+    f.write(str(l) + '<p>\n')\r
+\r
+    f.close()\r
diff --git a/HTML/HTML.py.html b/HTML/HTML.py.html
new file mode 100644 (file)
index 0000000..4a1a80c
--- /dev/null
@@ -0,0 +1,206 @@
+\r
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">\r
+<html><head><title>Python: module HTML</title>\r
+</head><body bgcolor="#f0f0f8">\r
+\r
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">\r
+<tr bgcolor="#7799ee">\r
+<td valign=bottom>&nbsp;<br>\r
+<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong>HTML</strong></big></big> (version 0.04, 2009-07-28)</font></td\r
+><td align=right valign=bottom\r
+><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="html.py">html.py</a></font></td></tr></table>\r
+    <p><tt>HTML.py&nbsp;-&nbsp;v0.04&nbsp;2009-07-28&nbsp;Philippe&nbsp;Lagadec<br>\r
+&nbsp;<br>\r
+This&nbsp;module&nbsp;provides&nbsp;a&nbsp;few&nbsp;classes&nbsp;to&nbsp;easily&nbsp;generate&nbsp;HTML&nbsp;code&nbsp;such&nbsp;as&nbsp;tables<br>\r
+and&nbsp;lists.<br>\r
+&nbsp;<br>\r
+Project&nbsp;website:&nbsp;<a href="http://www.decalage.info/python/html">http://www.decalage.info/python/html</a><br>\r
+&nbsp;<br>\r
+License:&nbsp;CeCILL&nbsp;(open-source&nbsp;GPL&nbsp;compatible),&nbsp;see&nbsp;source&nbsp;code&nbsp;for&nbsp;details.<br>\r
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://www.cecill.info">http://www.cecill.info</a></tt></p>\r
+<p>\r
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">\r
+<tr bgcolor="#ee77aa">\r
+<td colspan=3 valign=bottom>&nbsp;<br>\r
+<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>\r
+    \r
+<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>\r
+<td width="100%"><dl>\r
+<dt><font face="helvetica, arial"><a href="__builtin__.html#object">__builtin__.object</a>\r
+</font></dt><dd>\r
+<dl>\r
+<dt><font face="helvetica, arial"><a href="HTML.html#List">List</a>\r
+</font></dt><dt><font face="helvetica, arial"><a href="HTML.html#Table">Table</a>\r
+</font></dt><dt><font face="helvetica, arial"><a href="HTML.html#TableCell">TableCell</a>\r
+</font></dt><dt><font face="helvetica, arial"><a href="HTML.html#TableRow">TableRow</a>\r
+</font></dt></dl>\r
+</dd>\r
+</dl>\r
+ <p>\r
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">\r
+<tr bgcolor="#ffc8d8">\r
+<td colspan=3 valign=bottom>&nbsp;<br>\r
+<font color="#000000" face="helvetica, arial"><a name="List">class <strong>List</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>\r
+    \r
+<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>\r
+<td colspan=2><tt>a&nbsp;<a href="#List">List</a>&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;is&nbsp;used&nbsp;to&nbsp;create&nbsp;an&nbsp;ordered&nbsp;or&nbsp;unordered&nbsp;list&nbsp;in&nbsp;HTML.<br>\r
+(UL/OL&nbsp;tag)<br>\r
+&nbsp;<br>\r
+Attributes:<br>\r
+-&nbsp;lines:&nbsp;list,&nbsp;tuple&nbsp;or&nbsp;any&nbsp;iterable,&nbsp;containing&nbsp;one&nbsp;string&nbsp;for&nbsp;each&nbsp;line<br>\r
+-&nbsp;ordered:&nbsp;bool,&nbsp;choice&nbsp;between&nbsp;an&nbsp;ordered&nbsp;(OL)&nbsp;or&nbsp;unordered&nbsp;list&nbsp;(UL)<br>\r
+-&nbsp;attribs:&nbsp;dict,&nbsp;additional&nbsp;attributes&nbsp;for&nbsp;the&nbsp;OL/UL&nbsp;tag<br>\r
+&nbsp;<br>\r
+Reference:&nbsp;<a href="http://www.w3.org/TR/html4/struct/lists.html">http://www.w3.org/TR/html4/struct/lists.html</a><br>&nbsp;</tt></td></tr>\r
+<tr><td>&nbsp;</td>\r
+<td width="100%">Methods defined here:<br>\r
+<dl><dt><a name="List-__init__"><strong>__init__</strong></a>(self, lines<font color="#909090">=None</font>, ordered<font color="#909090">=False</font>, start<font color="#909090">=None</font>, attribs<font color="#909090">=None</font>)</dt><dd><tt><a href="#List">List</a>&nbsp;constructor</tt></dd></dl>\r
+\r
+<dl><dt><a name="List-__str__"><strong>__str__</strong></a>(self)</dt><dd><tt>return&nbsp;the&nbsp;HTML&nbsp;code&nbsp;for&nbsp;the&nbsp;list&nbsp;as&nbsp;a&nbsp;string</tt></dd></dl>\r
+\r
+<hr>\r
+Data descriptors defined here:<br>\r
+<dl><dt><strong>__dict__</strong></dt>\r
+<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>\r
+</dl>\r
+<dl><dt><strong>__weakref__</strong></dt>\r
+<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>\r
+</dl>\r
+</td></tr></table> <p>\r
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">\r
+<tr bgcolor="#ffc8d8">\r
+<td colspan=3 valign=bottom>&nbsp;<br>\r
+<font color="#000000" face="helvetica, arial"><a name="Table">class <strong>Table</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>\r
+    \r
+<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>\r
+<td colspan=2><tt>a&nbsp;<a href="#Table">Table</a>&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;is&nbsp;used&nbsp;to&nbsp;create&nbsp;a&nbsp;HTML&nbsp;table.&nbsp;(TABLE&nbsp;tag)<br>\r
+&nbsp;<br>\r
+Attributes:<br>\r
+-&nbsp;rows:&nbsp;list,&nbsp;tuple&nbsp;or&nbsp;any&nbsp;iterable,&nbsp;containing&nbsp;one&nbsp;iterable&nbsp;or&nbsp;<a href="#TableRow">TableRow</a><br>\r
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;for&nbsp;each&nbsp;row<br>\r
+-&nbsp;header_row:&nbsp;list,&nbsp;tuple&nbsp;or&nbsp;any&nbsp;iterable,&nbsp;containing&nbsp;the&nbsp;header&nbsp;row&nbsp;(optional)<br>\r
+-&nbsp;border:&nbsp;str&nbsp;or&nbsp;int,&nbsp;border&nbsp;width<br>\r
+-&nbsp;style:&nbsp;str,&nbsp;table&nbsp;style&nbsp;in&nbsp;CSS&nbsp;syntax&nbsp;(thin&nbsp;black&nbsp;borders&nbsp;by&nbsp;default)<br>\r
+-&nbsp;width:&nbsp;str,&nbsp;width&nbsp;of&nbsp;the&nbsp;table&nbsp;on&nbsp;the&nbsp;page<br>\r
+-&nbsp;attribs:&nbsp;dict,&nbsp;additional&nbsp;attributes&nbsp;for&nbsp;the&nbsp;TABLE&nbsp;tag<br>\r
+-&nbsp;col_width:&nbsp;list&nbsp;or&nbsp;tuple&nbsp;defining&nbsp;width&nbsp;for&nbsp;each&nbsp;column<br>\r
+-&nbsp;col_align:&nbsp;list&nbsp;or&nbsp;tuple&nbsp;defining&nbsp;horizontal&nbsp;alignment&nbsp;for&nbsp;each&nbsp;column<br>\r
+-&nbsp;col_char:&nbsp;list&nbsp;or&nbsp;tuple&nbsp;defining&nbsp;alignment&nbsp;character&nbsp;for&nbsp;each&nbsp;column<br>\r
+-&nbsp;col_charoff:&nbsp;list&nbsp;or&nbsp;tuple&nbsp;defining&nbsp;charoff&nbsp;attribute&nbsp;for&nbsp;each&nbsp;column<br>\r
+-&nbsp;col_valign:&nbsp;list&nbsp;or&nbsp;tuple&nbsp;defining&nbsp;vertical&nbsp;alignment&nbsp;for&nbsp;each&nbsp;column<br>\r
+-&nbsp;col_styles:&nbsp;list&nbsp;or&nbsp;tuple&nbsp;of&nbsp;HTML&nbsp;styles&nbsp;for&nbsp;each&nbsp;column<br>\r
+&nbsp;<br>\r
+Reference:&nbsp;<a href="http://www.w3.org/TR/html4/struct/tables.html#h-11.2.1">http://www.w3.org/TR/html4/struct/tables.html#h-11.2.1</a><br>&nbsp;</tt></td></tr>\r
+<tr><td>&nbsp;</td>\r
+<td width="100%">Methods defined here:<br>\r
+<dl><dt><a name="Table-__init__"><strong>__init__</strong></a>(self, rows<font color="#909090">=None</font>, border<font color="#909090">='1'</font>, style<font color="#909090">=None</font>, width<font color="#909090">=None</font>, cellspacing<font color="#909090">=None</font>, cellpadding<font color="#909090">=4</font>, attribs<font color="#909090">=None</font>, header_row<font color="#909090">=None</font>, col_width<font color="#909090">=None</font>, col_align<font color="#909090">=None</font>, col_valign<font color="#909090">=None</font>, col_char<font color="#909090">=None</font>, col_charoff<font color="#909090">=None</font>, col_styles<font color="#909090">=None</font>)</dt><dd><tt><a href="#TableCell">TableCell</a>&nbsp;constructor</tt></dd></dl>\r
+\r
+<dl><dt><a name="Table-__str__"><strong>__str__</strong></a>(self)</dt><dd><tt>return&nbsp;the&nbsp;HTML&nbsp;code&nbsp;for&nbsp;the&nbsp;table&nbsp;as&nbsp;a&nbsp;string</tt></dd></dl>\r
+\r
+<hr>\r
+Data descriptors defined here:<br>\r
+<dl><dt><strong>__dict__</strong></dt>\r
+<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>\r
+</dl>\r
+<dl><dt><strong>__weakref__</strong></dt>\r
+<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>\r
+</dl>\r
+</td></tr></table> <p>\r
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">\r
+<tr bgcolor="#ffc8d8">\r
+<td colspan=3 valign=bottom>&nbsp;<br>\r
+<font color="#000000" face="helvetica, arial"><a name="TableCell">class <strong>TableCell</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>\r
+    \r
+<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>\r
+<td colspan=2><tt>a&nbsp;<a href="#TableCell">TableCell</a>&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;is&nbsp;used&nbsp;to&nbsp;create&nbsp;a&nbsp;cell&nbsp;in&nbsp;a&nbsp;HTML&nbsp;table.&nbsp;(TD&nbsp;or&nbsp;TH)<br>\r
+&nbsp;<br>\r
+Attributes:<br>\r
+-&nbsp;text:&nbsp;text&nbsp;in&nbsp;the&nbsp;cell&nbsp;(may&nbsp;contain&nbsp;HTML&nbsp;tags).&nbsp;May&nbsp;be&nbsp;any&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;which<br>\r
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;can&nbsp;be&nbsp;converted&nbsp;to&nbsp;a&nbsp;string&nbsp;using&nbsp;str().<br>\r
+-&nbsp;header:&nbsp;bool,&nbsp;false&nbsp;for&nbsp;a&nbsp;normal&nbsp;data&nbsp;cell&nbsp;(TD),&nbsp;true&nbsp;for&nbsp;a&nbsp;header&nbsp;cell&nbsp;(TH)<br>\r
+-&nbsp;bgcolor:&nbsp;str,&nbsp;background&nbsp;color<br>\r
+-&nbsp;width:&nbsp;str,&nbsp;width<br>\r
+-&nbsp;align:&nbsp;str,&nbsp;horizontal&nbsp;alignement&nbsp;(left,&nbsp;center,&nbsp;right,&nbsp;justify&nbsp;or&nbsp;char)<br>\r
+-&nbsp;char:&nbsp;str,&nbsp;alignment&nbsp;character,&nbsp;decimal&nbsp;point&nbsp;if&nbsp;not&nbsp;specified<br>\r
+-&nbsp;charoff:&nbsp;str,&nbsp;see&nbsp;HTML&nbsp;specs<br>\r
+-&nbsp;valign:&nbsp;str,&nbsp;vertical&nbsp;alignment&nbsp;(top|middle|bottom|baseline)<br>\r
+-&nbsp;style:&nbsp;str,&nbsp;CSS&nbsp;style<br>\r
+-&nbsp;attribs:&nbsp;dict,&nbsp;additional&nbsp;attributes&nbsp;for&nbsp;the&nbsp;TD/TH&nbsp;tag<br>\r
+&nbsp;<br>\r
+Reference:&nbsp;<a href="http://www.w3.org/TR/html4/struct/tables.html#h-11.2.6">http://www.w3.org/TR/html4/struct/tables.html#h-11.2.6</a><br>&nbsp;</tt></td></tr>\r
+<tr><td>&nbsp;</td>\r
+<td width="100%">Methods defined here:<br>\r
+<dl><dt><a name="TableCell-__init__"><strong>__init__</strong></a>(self, text<font color="#909090">=''</font>, bgcolor<font color="#909090">=None</font>, header<font color="#909090">=False</font>, width<font color="#909090">=None</font>, align<font color="#909090">=None</font>, char<font color="#909090">=None</font>, charoff<font color="#909090">=None</font>, valign<font color="#909090">=None</font>, style<font color="#909090">=None</font>, attribs<font color="#909090">=None</font>)</dt><dd><tt><a href="#TableCell">TableCell</a>&nbsp;constructor</tt></dd></dl>\r
+\r
+<dl><dt><a name="TableCell-__str__"><strong>__str__</strong></a>(self)</dt><dd><tt>return&nbsp;the&nbsp;HTML&nbsp;code&nbsp;for&nbsp;the&nbsp;table&nbsp;cell&nbsp;as&nbsp;a&nbsp;string</tt></dd></dl>\r
+\r
+<hr>\r
+Data descriptors defined here:<br>\r
+<dl><dt><strong>__dict__</strong></dt>\r
+<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>\r
+</dl>\r
+<dl><dt><strong>__weakref__</strong></dt>\r
+<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>\r
+</dl>\r
+</td></tr></table> <p>\r
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">\r
+<tr bgcolor="#ffc8d8">\r
+<td colspan=3 valign=bottom>&nbsp;<br>\r
+<font color="#000000" face="helvetica, arial"><a name="TableRow">class <strong>TableRow</strong></a>(<a href="__builtin__.html#object">__builtin__.object</a>)</font></td></tr>\r
+    \r
+<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>\r
+<td colspan=2><tt>a&nbsp;<a href="#TableRow">TableRow</a>&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;is&nbsp;used&nbsp;to&nbsp;create&nbsp;a&nbsp;row&nbsp;in&nbsp;a&nbsp;HTML&nbsp;table.&nbsp;(TR&nbsp;tag)<br>\r
+&nbsp;<br>\r
+Attributes:<br>\r
+-&nbsp;cells:&nbsp;list,&nbsp;tuple&nbsp;or&nbsp;any&nbsp;iterable,&nbsp;containing&nbsp;one&nbsp;string&nbsp;or&nbsp;<a href="#TableCell">TableCell</a><br>\r
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="__builtin__.html#object">object</a>&nbsp;for&nbsp;each&nbsp;cell<br>\r
+-&nbsp;header:&nbsp;bool,&nbsp;true&nbsp;for&nbsp;a&nbsp;header&nbsp;row&nbsp;(TH),&nbsp;false&nbsp;for&nbsp;a&nbsp;normal&nbsp;data&nbsp;row&nbsp;(TD)<br>\r
+-&nbsp;bgcolor:&nbsp;str,&nbsp;background&nbsp;color<br>\r
+-&nbsp;col_align,&nbsp;col_valign,&nbsp;col_char,&nbsp;col_charoff,&nbsp;col_styles:&nbsp;see&nbsp;<a href="#Table">Table</a>&nbsp;class<br>\r
+-&nbsp;attribs:&nbsp;dict,&nbsp;additional&nbsp;attributes&nbsp;for&nbsp;the&nbsp;TR&nbsp;tag<br>\r
+&nbsp;<br>\r
+Reference:&nbsp;<a href="http://www.w3.org/TR/html4/struct/tables.html#h-11.2.5">http://www.w3.org/TR/html4/struct/tables.html#h-11.2.5</a><br>&nbsp;</tt></td></tr>\r
+<tr><td>&nbsp;</td>\r
+<td width="100%">Methods defined here:<br>\r
+<dl><dt><a name="TableRow-__init__"><strong>__init__</strong></a>(self, cells<font color="#909090">=None</font>, bgcolor<font color="#909090">=None</font>, header<font color="#909090">=False</font>, attribs<font color="#909090">=None</font>, col_align<font color="#909090">=None</font>, col_valign<font color="#909090">=None</font>, col_char<font color="#909090">=None</font>, col_charoff<font color="#909090">=None</font>, col_styles<font color="#909090">=None</font>)</dt><dd><tt><a href="#TableCell">TableCell</a>&nbsp;constructor</tt></dd></dl>\r
+\r
+<dl><dt><a name="TableRow-__str__"><strong>__str__</strong></a>(self)</dt><dd><tt>return&nbsp;the&nbsp;HTML&nbsp;code&nbsp;for&nbsp;the&nbsp;table&nbsp;row&nbsp;as&nbsp;a&nbsp;string</tt></dd></dl>\r
+\r
+<hr>\r
+Data descriptors defined here:<br>\r
+<dl><dt><strong>__dict__</strong></dt>\r
+<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>\r
+</dl>\r
+<dl><dt><strong>__weakref__</strong></dt>\r
+<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>\r
+</dl>\r
+</td></tr></table></td></tr></table><p>\r
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">\r
+<tr bgcolor="#eeaa77">\r
+<td colspan=3 valign=bottom>&nbsp;<br>\r
+<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>\r
+    \r
+<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>\r
+<td width="100%"><dl><dt><a name="-Link"><strong>Link</strong></a>(text, url)</dt><dd><tt>#&nbsp;much&nbsp;simpler&nbsp;definition&nbsp;of&nbsp;a&nbsp;link&nbsp;as&nbsp;a&nbsp;function:</tt></dd></dl>\r
+ <dl><dt><a name="-link"><strong>link</strong></a>(text, url)</dt></dl>\r
+ <dl><dt><a name="-list"><strong>list</strong></a>(*args, **kwargs)</dt><dd><tt>return&nbsp;HTML&nbsp;code&nbsp;for&nbsp;a&nbsp;list&nbsp;as&nbsp;a&nbsp;string.&nbsp;See&nbsp;<a href="#List">List</a>&nbsp;class&nbsp;for&nbsp;parameters.</tt></dd></dl>\r
+ <dl><dt><a name="-table"><strong>table</strong></a>(*args, **kwargs)</dt><dd><tt>return&nbsp;HTML&nbsp;code&nbsp;for&nbsp;a&nbsp;table&nbsp;as&nbsp;a&nbsp;string.&nbsp;See&nbsp;<a href="#Table">Table</a>&nbsp;class&nbsp;for&nbsp;parameters.</tt></dd></dl>\r
+</td></tr></table><p>\r
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">\r
+<tr bgcolor="#55aa55">\r
+<td colspan=3 valign=bottom>&nbsp;<br>\r
+<font color="#ffffff" face="helvetica, arial"><big><strong>Data</strong></big></font></td></tr>\r
+    \r
+<tr><td bgcolor="#55aa55"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>\r
+<td width="100%"><strong>TABLE_STYLE_THINBORDER</strong> = 'border: 1px solid #000000; border-collapse: collapse;'<br>\r
+<strong>__author__</strong> = 'Philippe Lagadec'<br>\r
+<strong>__date__</strong> = '2009-07-28'<br>\r
+<strong>__version__</strong> = '0.04'</td></tr></table><p>\r
+<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">\r
+<tr bgcolor="#7799ee">\r
+<td colspan=3 valign=bottom>&nbsp;<br>\r
+<font color="#ffffff" face="helvetica, arial"><big><strong>Author</strong></big></font></td></tr>\r
+    \r
+<tr><td bgcolor="#7799ee"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>\r
+<td width="100%">Philippe&nbsp;Lagadec</td></tr></table>\r
+</body></html>
\ No newline at end of file
diff --git a/HTML/HTML_tutorial.py b/HTML/HTML_tutorial.py
new file mode 100644 (file)
index 0000000..bf01dde
--- /dev/null
@@ -0,0 +1,208 @@
+# HTML.py tutorial - P. Lagadec\r
+\r
+# see also http://www.decalage.info/en/python/html for more details and\r
+# updates.\r
+\r
+\r
+import HTML\r
+\r
+# open an HTML file to show output in a browser\r
+HTMLFILE = 'HTML_tutorial_output.html'\r
+f = open(HTMLFILE, 'w')\r
+\r
+\r
+#=== TABLES ===================================================================\r
+\r
+# 1) a simple HTML table may be built from a list of lists:\r
+\r
+table_data = [\r
+        ['Last name',   'First name',   'Age'],\r
+        ['Smith',       'John',         30],\r
+        ['Carpenter',   'Jack',         47],\r
+        ['Johnson',     'Paul',         62],\r
+    ]\r
+\r
+htmlcode = HTML.table(table_data)\r
+print htmlcode\r
+f.write(htmlcode)\r
+f.write('<p>')\r
+print '-'*79\r
+\r
+#-------------------------------------------------------------------------------\r
+\r
+# 2) a header row may be specified: it will appear in bold in browsers\r
+\r
+table_data = [\r
+        ['Smith',       'John',         30],\r
+        ['Carpenter',   'Jack',         47],\r
+        ['Johnson',     'Paul',         62],\r
+    ]\r
+\r
+htmlcode = HTML.table(table_data,\r
+    header_row=['Last name',   'First name',   'Age'])\r
+print htmlcode\r
+f.write(htmlcode)\r
+f.write('<p>')\r
+print '-'*79\r
+\r
+\r
+#-------------------------------------------------------------------------------\r
+\r
+# 3) you may also create a Table object and add rows one by one:\r
+\r
+t = HTML.Table(header_row=['x', 'square(x)', 'cube(x)'])\r
+for x in range(1,10):\r
+    t.rows.append([x, x*x, x*x*x])\r
+htmlcode = str(t)\r
+print htmlcode\r
+f.write(htmlcode)\r
+f.write('<p>')\r
+print '-'*79\r
+\r
+\r
+#-------------------------------------------------------------------------------\r
+\r
+# 4) rows may be any iterable (list, tuple, ...) including a generator:\r
+#    (this is useful to save memory when generating a large table)\r
+\r
+def gen_rows(i):\r
+    'rows generator'\r
+    for x in range(1,i):\r
+        yield [x, x*x, x*x*x]\r
+\r
+htmlcode = HTML.table(gen_rows(10), header_row=['x', 'square(x)', 'cube(x)'])\r
+print htmlcode\r
+f.write(htmlcode)\r
+f.write('<p>')\r
+print '-'*79\r
+\r
+\r
+#-------------------------------------------------------------------------------\r
+\r
+# 5) to choose a specific background color for a cell, use a TableCell\r
+#    object:\r
+\r
+HTML_COLORS = ['Black', 'Green', 'Silver', 'Lime', 'Gray', 'Olive', 'White',\r
+    'Maroon', 'Navy', 'Red', 'Blue', 'Purple', 'Teal', 'Fuchsia', 'Aqua']\r
+\r
+t = HTML.Table(header_row=['Name', 'Color'])\r
+for colorname in HTML_COLORS:\r
+    colored_cell = HTML.TableCell(' ', bgcolor=colorname)\r
+    t.rows.append([colorname, colored_cell])\r
+htmlcode = str(t)\r
+print htmlcode\r
+f.write(htmlcode)\r
+f.write('<p>')\r
+print '-'*79\r
+\r
+\r
+#-------------------------------------------------------------------------------\r
+\r
+# 6) A simple way to generate a test report:\r
+\r
+# dictionary of test results, indexed by test id:\r
+test_results = {\r
+        'test 1': 'success',\r
+        'test 2': 'failure',\r
+        'test 3': 'success',\r
+        'test 4': 'error',\r
+    }\r
+\r
+# dict of colors for each result:\r
+result_colors = {\r
+        'success':      'lime',\r
+        'failure':      'red',\r
+        'error':        'yellow',\r
+    }\r
+\r
+t = HTML.Table(header_row=['Test', 'Result'])\r
+for test_id in sorted(test_results):\r
+    # create the colored cell:\r
+    color = result_colors[test_results[test_id]]\r
+    colored_result = HTML.TableCell(test_results[test_id], bgcolor=color)\r
+    # append the row with two cells:\r
+    t.rows.append([test_id, colored_result])\r
+htmlcode = str(t)\r
+print htmlcode\r
+f.write(htmlcode)\r
+f.write('<p>')\r
+print '-'*79\r
+\r
+#-------------------------------------------------------------------------------\r
+\r
+# 7) sample table with column attributes and styles:\r
+table_data = [\r
+        ['Smith',       'John',         30,    4.5],\r
+        ['Carpenter',   'Jack',         47,    7],\r
+        ['Johnson',     'Paul',         62,    10.55],\r
+    ]\r
+htmlcode = HTML.table(table_data,\r
+    header_row = ['Last name',   'First name',   'Age', 'Score'],\r
+    col_width=['', '20%', '10%', '10%'],\r
+    col_align=['left', 'center', 'right', 'char'],\r
+    col_styles=['font-size: large', '', 'font-size: small', 'background-color:yellow'])\r
+f.write(htmlcode + '<p>\n')\r
+print htmlcode\r
+print '-'*79\r
+\r
+\r
+\r
+#=== LISTS ===================================================================\r
+\r
+# 1) a HTML list (with bullets) may be built from a Python list of strings:\r
+\r
+a_list = ['john', 'paul', 'jack']\r
+htmlcode = HTML.list(a_list)\r
+print htmlcode\r
+f.write(htmlcode)\r
+f.write('<p>')\r
+print '-'*79\r
+\r
+\r
+# 2) it is easy to change it into a numbered (ordered) list:\r
+\r
+htmlcode = HTML.list(a_list, ordered=True)\r
+print htmlcode\r
+f.write(htmlcode)\r
+f.write('<p>')\r
+print '-'*79\r
+\r
+\r
+# 3) Lines of a list may also be added one by one, when using the List class:\r
+\r
+html_list = HTML.List()\r
+for i in range(1,10):\r
+    html_list.lines.append('square(%d) = %d' % (i, i*i))\r
+htmlcode = str(html_list)\r
+print htmlcode\r
+f.write(htmlcode)\r
+f.write('<p>')\r
+print '-'*79\r
+\r
+\r
+# 4) To save memory, a large list may be built from a generator:\r
+\r
+def gen_lines(i):\r
+    'lines generator'\r
+    for x in range(1,i):\r
+        yield 'square(%d) = %d' % (x, x*x)\r
+htmlcode = HTML.list(gen_lines(10))\r
+print htmlcode\r
+f.write(htmlcode)\r
+f.write('<p>')\r
+print '-'*79\r
+\r
+\r
+#=== LINKS ===================================================================\r
+\r
+# How to create a link:\r
+\r
+htmlcode = HTML.link('Decalage website', 'http://www.decalage.info')\r
+print htmlcode\r
+f.write(htmlcode)\r
+f.write('<p>')\r
+print '-'*79\r
+\r
+\r
+f.close()\r
+print '\nOpen the file %s in a browser to see the result.' % HTMLFILE\r
diff --git a/HTML/Licence_CeCILL_V2-en.html b/HTML/Licence_CeCILL_V2-en.html
new file mode 100644 (file)
index 0000000..c573ce2
--- /dev/null
@@ -0,0 +1,1002 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<title>CeCILL FREE SOFTWARE LICENSINGE
+       AGREEMENT CeCILL</title>
+<style type="text/css">
+     h1.title {color: #008080; font-size: 200%; text-align: center}
+     h2 {color: #008080; font-size: 150%}
+     h3 {color: #008080; font-size: 140%} 
+     h4 {color: #008080; font-size: 120%} 
+     h5 {color: #008080; font-size: 100%} 
+     span.numbering {color: #008080}
+     span.definition {font-weight: bold}
+     div.version {font-style: italic}
+     div.footnote {font-size: 80%} 
+     ins {text-decoration: underline; background: #AAFFA4}
+     div.added {text-decoration: underline; background: #AAFFA4}
+     del {text-decoration:line-through; background: #8F8F8F}
+     div.deleted {text-decoration:line-through; background: #8F8F8F}
+  </style>
+</head>
+<body>
+
+<h1 class="title">CeCILL FREE SOFTWARE LICENSE
+       AGREEMENT </h1>
+
+
+
+<div class="notice">
+<h2>Notice</h2>
+<p>
+This
+Agreement is a Free Software
+license agreement that is the result of 
+discussions between its authors in order to ensure compliance with
+the two main principles guiding its drafting:</p>
+
+
+
+<ul>
+<li> firstly,
+compliance with the principles governing the distribution of Free Software:
+access to source code, broad rights granted to users,
+</li>
+<li>
+secondly, the election of a governing law, French law, with which it is
+conformant, both as regards the law of torts and
+intellectual property law, and the protection that it offers to
+both authors and holders of the economic rights over software. 
+</li>
+</ul>
+
+
+<p>The
+ authors of the 
+
+CeCILL<SUP><A HREF="#footnote1">1</A></SUP>
+license are:</p> 
+
+<p>Commissariat
+à l'Energie Atomique - CEA, a public
+scientific, technical and industrial establishment, having its
+principal place of business at 31-33 rue de la Fédération,
+75752  Paris
+cedex 15, France.</p>
+
+<p>Centre
+National de la Recherche Scientifique - CNRS,
+a public scientific and technological establishment, having its
+principal place of business at
+3 rue Michel-Ange 75794 Paris cedex 16, France.</p> 
+
+<p>Institut
+National de Recherche en Informatique et en Automatique - INRIA,
+a public scientific and technological establishment, having its
+principal place of business at Domaine de Voluceau, Rocquencourt, BP
+105, 78153 Le Chesnay cedex, France.</p>
+
+</div>
+<div class="preamble">
+<h2>Preamble</h2>
+
+<p>The
+purpose of this Free Software 
+license
+agreement 
+is to grant users
+the right to modify and redistribute the software governed by this
+license within the framework of an open source
+distribution model.  
+</p>
+
+<p>The
+exercising of these rights is conditional upon certain obligations
+for users so as to  preserve this status 
+ for all subsequent
+redistributions. </p>
+
+<p>In consideration of access to
+the source code and the rights to copy,
+modify and redistribute granted by the license, users are provided only
+with a limited warranty and the
+software's author, the holder of the economic rights, and the
+successive licensors only have limited liability.
+</p>
+
+<p>In
+this respect, 
+
+the risks
+associated with loading, using, modifying and/or developing or
+reproducing the software by the user 
+are brought to the user's attention,
+given its  Free Software 
+status, 
+which may  make it
+ complicated to use, 
+
+with the result that its use is 
+reserved for developers and experienced professionals having in-depth 
+computer knowledge. 
+Users are therefore encouraged to load and test the Software's suitability as
+regards their requirements in conditions enabling the security of their
+systems and/or data to be ensured and, more generally, to use and operate it
+in the same conditions of security. This Agreement may be freely reproduced
+and published, provided it is not altered, and that no 
+provisions are either added or removed
+herefrom.</p> 
+
+<p>This
+Agreement may apply to any or all software for which the holder of
+the economic rights decides to submit the use
+thereof to its provisions.</p>
+
+</div>
+<div class="article">
+<h2> Article <span class="numbering">1 </span> - DEFINITIONS</h2>
+
+       <p>For
+       the purpose of this Agreement, 
+        when the following expressions
+       commence with a capital letter, they shall have the following
+       meaning:</p>
+
+        <p class="definition"><span class="definition">Agreement</span>:
+        
+       means this license
+        agreement, and 
+        its possible subsequent versions and annexes.
+        
+        </p>
+
+       <p class="definition"><span class="definition">Software</span>:
+        
+       means the software in its Object Code and/or Source Code form and,
+       where applicable, its documentation, "as is" 
+       when the Licensee accepts the Agreement. 
+        
+        </p>
+
+       <p class="definition"><span class="definition">Initial Software</span>:
+        
+        means the Software in its Source Code and  
+        possibly its   Object Code form and, where applicable, its
+        documentation, "as is"  when it is
+        first distributed
+         under the terms and conditions of the
+        Agreement.  
+        
+        </p>
+
+        <p class="definition"><span class="definition">Modified Software</span>:
+        
+        means the Software modified by at least one Contribution.
+        
+        </p>
+
+       <p class="definition"><span class="definition">Source Code</span>:
+        
+        means all the Software's instructions and program lines to which
+        access is required so as to modify the Software. 
+        
+        </p>
+
+       <p class="definition"><span class="definition">Object Code</span>:
+        
+        means the binary files originating from the
+       compilation of the Source Code. 
+        
+        </p>
+
+       <p class="definition"><span class="definition">Holder</span>:
+        
+       means the holder(s) of the economic rights over the Initial Software. 
+        
+        </p>
+
+       <p class="definition"><span class="definition">Licensee</span>:
+        
+       means
+        the Software user(s) having accepted the Agreement. 
+         
+        </p>
+
+       <p class="definition"><span class="definition">Contributor</span>:
+        
+       means a Licensee having made at least one Contribution.
+        
+        </p>
+
+       <p class="definition"><span class="definition">Licensor</span>:
+        
+       means the Holder, or any  other individual or legal 
+        entity,        who distributes the Software under
+        the Agreement.  
+        
+        </p>
+
+       <p class="definition"><span class="definition">Contribution</span>:
+        
+       means any or all modifications,
+        corrections, translations, adaptations and/or new 
+        functions
+        integrated into the Software by any or all Contributors, 
+         as well as any or all 
+          Internal Modules.
+        
+        </p>
+
+       <p class="definition"><span class="definition">Module</span>:
+        
+       means a set of sources files including their documentation 
+        that enables
+        supplementary 
+       functions or services  in
+        addition to those offered by the Software.
+        
+        </p>
+
+       <p class="definition"><span class="definition"> External Module</span>:
+        
+        means any or all Modules, 
+        
+        not derived from the Software, 
+        so that this Module 
+        and the        Software  run in
+       separate address spaces, with one calling the other when they are
+       run.
+        
+        </p>
+
+       <p class="definition"><span class="definition"> Internal Module</span>: 
+        
+        means any or all
+        Module,  connected to the Software  so that they both execute
+        in the same address space. 
+        
+        
+        </p>
+
+        
+        <p class="definition"><span class="definition">GNU GPL</span>:
+        
+        means the GNU General Public License version 2 or any subsequent
+        version, as published by the Free Software Foundation Inc.
+        
+        </p>
+        
+
+       <p class="definition"><span class="definition">Parties</span>:
+        
+       mean both the Licensee and the Licensor.
+        
+        </p>
+
+       <p>These
+       expressions may be used both in singular and plural form.</p>
+
+</div>
+<div class="article">
+<h2> Article <span class="numbering">2 </span> - PURPOSE</h2>
+
+       <p>The
+       purpose of the Agreement is the grant
+        by the Licensor to  the
+       Licensee of a non-exclusive, transferable 
+        and worldwide license 
+        for the        Software as set forth in Article <a href="#scope"><span class="numbering">5</span></a>
+        hereinafter for the whole term of the
+        protection 
+        granted by the rights over said Software. 
+       </p>
+
+</div>
+<div class="article">
+<h2> Article <span class="numbering">3 </span> - ACCEPTANCE</h2>
+
+        <div class="clause">
+       <p><a name="accepting"></a><span class="numbering">3.1 </span>The
+       Licensee shall be deemed as having accepted
+       the terms and conditions of this Agreement 
+        upon the occurrence of the
+       first of the following events:</p>
+        <ul>
+       <li> (i)
+       loading the Software by any or all means, notably, by downloading
+       from a remote server, or by loading from a physical medium;</li>
+        <li> (ii)
+       the first time the Licensee exercises any of the rights granted
+       hereunder.</li>
+        </ul>
+        </div>
+
+        <div class="clause">
+       <p><span class="numbering">3.2 </span>One
+       copy of the Agreement, containing a notice relating to the 
+         characteristics
+        of the  Software, to the limited warranty, and to the
+        fact that its use is
+        restricted to
+         experienced users has been provided to the
+       Licensee prior to its acceptance as set forth in Article 
+        <a href="#accepting"><span class="numbering">3.1</span></a>
+       hereinabove, and the Licensee hereby acknowledges that it 
+        has read and understood it.</p>
+        </div>
+
+</div>
+<div class="article">
+<h2> Article <span class="numbering">4 </span> - EFFECTIVE DATE AND TERM</h2>
+
+
+        <div class="clause">
+        <h3>
+<span class="numbering">4.1 </span>EFFECTIVE DATE</h3>
+
+       <p>The
+       Agreement shall become effective on the date when it is accepted by
+       the Licensee as set forth in Article <a href="#accepting"><span class="numbering">3.1</span></a>.</p>
+        </div>
+
+       <div class="clause">
+        <h3>
+<a name="term"></a><span class="numbering">4.2 </span>TERM</h3>
+
+       <p>The
+       Agreement shall remain in force 
+        for the entire legal term of
+        protection of the economic rights over the Software.</p>
+
+        </div>
+
+</div>
+<div class="article">
+<h2>
+<a name="scope"></a> Article <span class="numbering">5 </span> - SCOPE OF  RIGHTS GRANTED</h2>
+
+       <p>The
+       Licensor hereby grants to the Licensee, who
+        accepts, the
+       following rights over the Software
+        for any or all use, and for 
+       the term of the Agreement, on the basis of the terms and conditions
+       set forth hereinafter. 
+       </p>
+       <p>
+        
+        Besides, if the Licensor owns or comes to
+        own one or more patents
+        protecting all or part of the 
+        functions of the Software
+        or of its components,
+        the Licensor undertakes not to enforce the rights granted by these
+        patents against  successive Licensees using, exploiting or
+        modifying the Software. If these patents are
+        transferred,  the Licensor
+        undertakes to have the transferees subscribe to the
+        obligations set forth in this
+        paragraph.
+        </p>
+
+        <div class="clause">
+        <h3>
+<span class="numbering">5.1 </span>RIGHT OF USE</h3>
+
+       <p>The
+       Licensee is authorized to use the Software, without any limitation as to its fields
+        of application, with it being hereinafter 
+       specified that this  comprises:
+        </p>
+       <ol>
+       <li><p>permanent
+       or temporary reproduction of all or part of the Software by any or
+       all means and in any or all form. 
+       </p></li>
+       <li><p>loading,
+       displaying, running, or storing the Software on any or all
+        medium.</p></li> 
+       <li><p>entitlement
+               to observe, study or test 
+                its operation
+                 so as to
+                 determine
+               the ideas and principles behind any or all
+               constituent elements of said Software. This shall apply when
+                the 
+               Licensee carries out any or all loading, displaying, running,
+               transmission or storage operation as regards the Software,
+                that it is entitled to carry out hereunder.</p></li>
+       </ol>
+
+        </div>
+
+        <div class="clause">
+       <h3>
+<span class="numbering">5.2 </span>ENTITLEMENT TO MAKE CONTRIBUTIONS</h3>
+
+       <p>
+       The
+       right to make Contributions includes the right to translate, adapt,
+       arrange, or make any or all modifications to the Software,
+        and the 
+       right to reproduce the resulting Software.</p>
+       <p>The
+       Licensee is authorized to make any or all Contributions to
+        the Software provided that it 
+        includes an explicit notice that it is the
+        author 
+       of said Contribution and indicates the date of the 
+         creation thereof.</p>
+
+        </div>
+
+        <div class="clause">
+        <h3>
+<span class="numbering">5.3 </span>RIGHT OF DISTRIBUTION
+       </h3>
+
+       <p>In
+       particular, the right of distribution includes the 
+       right to publish, transmit and communicate
+        the Software to the general public 
+       on any or all medium, and by any or all means, and the right to
+       market, either in consideration of a fee, or free of charge, 
+         one or more copies of the Software 
+        by any
+        means.</p>
+       <p>The
+       Licensee is further authorized to 
+        distribute copies of the
+       modified or unmodified Software to third parties according to the
+       terms and conditions set forth hereinafter.</p>
+
+        <div class="subclause">
+       <h4>
+<span class="numbering">5.3.1 </span>DISTRIBUTION OF SOFTWARE
+        WITHOUT MODIFICATION</h4>
+
+       <p>The
+       Licensee is authorized to distribute 
+        true copies of the Software
+       in Source Code or Object Code form, provided that
+       said distribution 
+        complies with all the provisions of the
+       Agreement and is accompanied by:</p>
+       <ol>
+               <li><p>a
+               copy of the Agreement,</p></li>
+               <li><p>a
+               notice relating to the limitation of both the Licensor's
+               warranty and liability as set forth in Articles 8 and 9,
+                </p></li>
+        </ol>
+       <p>and
+       that, in the event that only the   Object Code
+        of the Software is redistributed, the Licensee allows 
+        future Licensees unhindered access to the 
+        
+        full Source Code of the Software
+        by 
+        indicating how to access it,
+        it being understood that the additional cost of acquiring the Source
+        Code shall not exceed the cost of transferring the data. 
+       </p>
+
+        </div>
+
+        <div class="subclause">
+        <h4>
+<span class="numbering">5.3.2 </span>DISTRIBUTION OF MODIFIED  SOFTWARE</h4>
+
+       <p>When
+       the Licensee makes a Contribution to the Software, the terms and
+       conditions for the distribution 
+        of the Modified Software become subject to all the provisions 
+         of this Agreement. 
+       </p>
+       <p>The
+       Licensee is authorized to distribute 
+        the Modified Software, in
+       Source Code or Object Code form, provided that said 
+        distribution
+       complies with all the provisions of the Agreement and is accompanied
+       by: 
+       </p>
+       <ol>
+               <li><p>a
+               copy of the Agreement,</p></li>
+               <li>
+<p>a
+               notice relating to the limitation of both the Licensor's
+               warranty and liability as set forth in Articles 8 and 9,</p>
+                </li>
+       </ol>
+       <p>and
+       that, in the event that only the 
+        Object Code of the Modified Software
+        is redistributed, the Licensee allows future Licensees
+       unhindered access to the 
+        full Source Code of the Modified Software
+       by 
+        indicating how to access it,
+       it being understood that the additional cost of acquiring the Source
+       Code shall not exceed the cost of transferring the data. 
+       </p>
+
+        </div>
+
+        <div class="subclause">
+        <h4>
+<span class="numbering">5.3.3 </span>DISTRIBUTION OF 
+        EXTERNAL MODULES</h4>
+
+       <p>When
+       the Licensee has developed 
+        an External Module, the terms and
+       conditions 
+        of this Agreement do not apply to said 
+         External Module, that may be
+       distributed under a separate 
+        license
+        agreement.</p>
+
+        </div>
+
+        <div class="subclause">
+        <h4>
+<a name="compatibility"></a><span class="numbering">5.3.4 </span>COMPATIBILITY WITH THE GNU GPL 
+        </h4>
+
+        
+
+        
+        <p> The Licensee can include a code that is subject to the provisions
+            of one of the versions of the GNU GPL in the Modified or unmodified
+           Software, and distribute that entire code under the terms of the
+           same version of the GNU GPL.</p>
+
+       <p> The Licensee can include the Modified or unmodified Software in a
+           code that is subject to the provisions of one of the versions of
+            the GNU GPL, and distribute that entire code under the terms of
+            the same version of the GNU GPL.
+        </p>
+        
+
+        </div>
+
+        </div>
+
+</div>
+<div class="article">
+<h2> Article <span class="numbering">6 </span> - INTELLECTUAL PROPERTY 
+       </h2>
+
+        <div class="clause">
+        <h3>
+<span class="numbering">6.1 </span>OVER THE INITIAL SOFTWARE</h3>
+
+       <p>The
+       Holder owns the economic rights over the Initial Software. Any or
+       all use of the Initial Software is subject to compliance with the
+       terms and conditions under which the Holder has elected to
+       distribute its work and no one shall be entitled to modify the terms
+       and conditions for the distribution of said Initial Software.</p>
+       <p>The
+       Holder undertakes  that the Initial 
+       Software 
+        will remain ruled at least by the current license,
+        for the duration set 
+       forth in  article <a href="#term"><span class="numbering">4.2</span></a>.</p>
+
+        </div>
+
+        <div class="clause">
+       <h3>
+<span class="numbering">6.2 </span>OVER THE CONTRIBUTIONS</h3>
+
+       <p>
+        
+        
+        A Licensee who develops a Contribution is the owner 
+        of the intellectual property rights over this Contribution
+         as  defined by 
+         applicable law.</p>
+
+        </div>
+
+        <div class="clause">
+        <h3>
+<span class="numbering">6.3 </span>OVER THE  
+        EXTERNAL MODULES</h3>
+
+       <p>
+        A
+       Licensee 
+        
+        who develops an External Module
+        is the owner of the intellectual property rights over
+        this External Module as defined by applicable law and is
+         
+        free to        choose the type of agreement that shall govern its
+        distribution.</p> 
+
+        </div>
+
+        <div class="clause">
+        <h3>
+<span class="numbering">6.4 </span>JOINT PROVISIONS</h3>
+
+        <div class="subclause">
+       <p>The
+       Licensee expressly undertakes:</p>
+       <ol>
+        <li><p>not
+               to remove, or modify, in any  manner, the
+               intellectual 
+               property notices 
+               attached to the Software;</p></li>
+       <li>
+<p>to
+               reproduce said notices, in an identical manner, in the copies of
+              the Software modified or not.</p>
+               </li>
+       </ol>
+        </div>
+
+        <div class="subclause">
+       <p>The
+       Licensee undertakes not to directly or indirectly infringe
+       the intellectual property rights of the Holder and/or Contributors
+        on the Software
+       and to take, where applicable, vis-à-vis its staff, any 
+        and
+       all measures required to ensure respect of
+        said intellectual 
+       property rights of the Holder and/or Contributors.</p>
+        </div>
+
+        </div>
+
+</div>
+<div class="article">
+<h2> Article <span class="numbering">7 </span> - RELATED SERVICES</h2>
+
+        <div class="clause">
+
+       <p><span class="numbering">7.1 </span>Under
+       no circumstances shall the Agreement oblige the Licensor to provide
+       technical assistance or maintenance services for the Software.</p>
+
+       <p>However,
+       the Licensor is entitled to offer this type of 
+        services. The terms
+       and conditions of such technical assistance, and/or such
+       maintenance, shall  be set forth in a separate
+        instrument. Only 
+       the Licensor offering said maintenance and/or technical assistance
+       services shall incur liability therefor.</p>
+
+        </div>
+
+        <div class="clause">
+
+       <p><span class="numbering">7.2 </span>Similarly,
+       any Licensor is entitled to offer to its
+       licensees, under its 
+        sole responsibility,  
+        a warranty, that shall only
+       be binding upon itself, for the redistribution of the Software
+       and/or the Modified Software, under terms and conditions 
+        that 
+        it is free to decide. Said warranty, and the financial
+        terms and conditions of its application, shall be subject 
+        of a separate
+       instrument executed between the Licensor and the Licensee.</p>
+
+        </div>
+
+</div>
+<div class="article">
+<h2> Article <span class="numbering">8 </span> - LIABILITY</h2>
+
+        <div class="clause">
+       <p><span class="numbering">8.1 </span>Subject
+       to the provisions of Article 8.2, 
+        
+        the Licensee shall be entitled to claim compensation for
+        any direct
+        loss  it may have suffered from the Software
+        as a result of a fault on the part of the relevant
+        Licensor, subject to 
+        providing evidence thereof. 
+       </p>
+        </div>
+
+        <div class="clause">
+       <p><span class="numbering">8.2 </span>The
+       Licensor's liability is limited to the commitments made under
+       this Agreement and shall not be incurred as a result of in
+       particular: (i)  loss due the Licensee's total or partial
+       failure to fulfill its obligations, (ii) direct or consequential
+       loss that is suffered by the Licensee due to the
+         
+        use or performance of the Software,
+        
+        
+        and (iii) 
+        more generally, any
+        consequential loss.  
+        In particular
+        the Parties expressly
+       agree that any or all pecuniary or business loss (i.e. loss of data,
+       loss of profits, operating loss, loss of customers or orders,
+       opportunity cost, any disturbance to business activities) or any or
+       all legal proceedings instituted against the Licensee by a third
+       party, shall constitute consequential loss and shall not provide
+       entitlement to any or all compensation from the Licensor.
+       </p>
+        </div>
+
+</div>
+<div class="article">
+<h2> Article <span class="numbering">9 </span> - WARRANTY</h2>
+
+        <div class="clause">
+       <p><span class="numbering">9.1 </span>The
+       Licensee acknowledges that the 
+       scientific and technical 
+        state-of-the-art  when the Software
+        was 
+       distributed did not enable all possible uses to be tested and
+       verified, nor for the presence of 
+        
+        possible defects to be detected.
+       In this respect, the Licensee's attention has been drawn to
+       the risks associated with loading, using, modifying and/or
+       developing and reproducing the Software
+        which are reserved for 
+       experienced users.</p>
+       <p>The
+       Licensee shall be responsible for verifying, by any or all means,
+       the product's suitability for its requirements, its good working order, and for 
+        ensuring that it shall not cause damage
+       to either persons or 
+        properties. 
+       </p>
+        </div>
+
+        <div class="clause">
+       <p><a name="good-faith"></a><span class="numbering">9.2 </span>The Licensor
+       hereby represents, in good faith, that it is entitled to grant all
+       the rights over the  Software (including in
+        particular the rights set 
+       forth in Article <a href="#scope"><span class="numbering">5</span></a>).</p>
+        </div>
+
+        <div class="clause">
+       <p><span class="numbering">9.3 </span>
+       The
+       Licensee acknowledges that the Software is supplied "as is"
+       by the Licensor without any  other express or tacit
+        warranty, 
+       other than that provided for in Article 
+        <a href="#good-faith"><span class="numbering">9.2</span></a> and, in particular,
+       without any  warranty as to its 
+        
+        commercial value, its secured, safe,
+        innovative or relevant nature. 
+       </p>
+       <p>Specifically,
+       the Licensor does not warrant that the Software is free from any 
+         error, that it will
+        operate without interruption, 
+        that it will be 
+       compatible with the Licensee's own equipment and 
+        software configuration, 
+        nor that it will meet the
+        Licensee's requirements.    
+       </p>
+        </div>
+    
+        <div class="clause">
+       <p><span class="numbering">9.4 </span>The
+       Licensor does not either expressly or tacitly warrant that the
+       Software does not infringe any  third party
+        intellectual 
+        property right
+       relating to a patent, software or  any 
+        other property right. 
+         Therefore, the Licensor disclaims any and all liability towards the
+        Licensee arising out of any or all proceedings for
+        infringement that may be 
+       instituted in respect of the use, modification and redistribution of
+       the Software. Nevertheless, should such proceedings be instituted
+       against the Licensee, the Licensor shall provide it with technical
+       and legal assistance for its defense. Such technical and legal
+       assistance shall be decided  on a case-by-case basis
+        between the 
+       relevant Licensor and the Licensee pursuant to a memorandum of
+       understanding. The Licensor disclaims any and
+        all liability as
+       regards the Licensee's use of the 
+        
+        name of the Software. No
+       warranty is given as regards
+        the existence of prior rights 
+       over the name of the Software or as regards
+        the existence of a trademark.</p>
+        </div>
+
+</div>
+<div class="article">
+<h2> Article <span class="numbering">10 </span> - TERMINATION</h2>
+
+        <div class="clause">
+       <p><span class="numbering">10.1 </span>
+       In the event of a breach by the
+       Licensee of its obligations hereunder, the Licensor may
+       automatically terminate this Agreement thirty (30)
+       days after
+       notice has been sent to the Licensee and has remained ineffective.</p>
+        </div>
+
+        <div class="clause">
+       <p><span class="numbering">10.2 </span>A
+       Licensee whose Agreement is terminated shall no longer be authorized
+       to use, modify or distribute the Software. However, any
+        
+       licenses that it may have granted prior to termination of the
+       Agreement shall remain valid subject to their having been granted in
+       compliance with the terms and conditions hereof. 
+       </p>
+        </div>
+
+</div>
+<div class="article">
+<h2> Article <span class="numbering">11 </span> - MISCELLANEOUS </h2>
+
+        <div class="clause">
+        <h3>
+<span class="numbering">11.1 </span>EXCUSABLE EVENTS</h3>
+
+       <p>Neither
+       Party shall be liable for any or all delay, or failure to perform
+       the Agreement, that may be attributable to an event of force
+       majeure, an act of God or an outside cause, such as
+        
+       defective functioning or interruptions 
+        of the electricity or
+       telecommunications networks, network
+        paralysis following a
+       virus attack,  intervention by
+         government authorities,
+       natural disasters, water damage, 
+        earthquakes, fire, explosions,
+       strikes and labor unrest, war, etc.</p>
+        
+        </div>
+
+        <div class="clause">
+       <p><span class="numbering">11.2 </span>Any Failure by either 
+        Party, on one or more
+        occasions, to invoke one or more of the 
+        provisions hereof, shall under no
+       circumstances be interpreted as being a waiver by the interested
+       Party of its right to invoke said
+        provision(s) subsequently.</p> 
+        </div>
+
+        <div class="clause">
+       <p><span class="numbering">11.3 </span> The
+       Agreement cancels and replaces
+       any or all previous agreements, whether written or oral,
+        between the 
+       Parties and having the same purpose, and constitutes the entirety of
+       the agreement between said Parties concerning said purpose. No
+       supplement or modification to the terms and conditions hereof shall
+       be effective as between the Parties 
+        unless it is made in writing and
+       signed by their duly authorized representatives. 
+       </p>
+        </div>
+
+        <div class="clause">
+       <p><span class="numbering">11.4 </span>In
+       the event that one or more
+       of the provisions hereof were to conflict with a current or future
+       applicable act or legislative text, said act or legislative text
+       shall prevail, and the Parties
+        shall make the necessary 
+       amendments so as to comply with
+        said act or legislative
+       text. All  other provisions shall remain
+        effective. Similarly, 
+       invalidity of a provision of the
+        Agreement, 
+       for any reason whatsoever, shall not cause the Agreement as a whole
+       to be invalid. 
+       </p>
+        </div>
+
+        <div class="clause">
+        <h3>
+<span class="numbering">11.5 </span>LANGUAGE</h3>
+
+       <p>The
+       Agreement is drafted in both French and English
+        and both versions are
+        deemed authentic.
+       </p>
+        </div>
+
+</div>
+<div class="article">
+<h2> Article <span class="numbering">12 </span> - NEW VERSIONS OF THE AGREEMENT</h2>
+        <div class="clause">
+       <p><span class="numbering">12.1 </span>Any
+        person 
+        is authorized to duplicate and distribute copies of
+       this Agreement.</p>
+        </div>
+        <div class="clause">
+       <p><span class="numbering">12.2 </span>So
+       as to ensure coherence, the wording of this Agreement is protected
+       and may only be modified by the authors of the License, 
+        who reserve
+       the right to periodically publish updates or new versions of the
+       Agreement, each with a separate number. These subsequent versions
+       may 
+        address new issues encountered by Free Software.
+       </p>
+        </div>
+
+        <div class="clause">
+       <p><span class="numbering">12.3 </span>Any
+       
+        Software distributed under a given version of the Agreement
+       may only be subsequently distributed under the same version of the
+       Agreement or a subsequent version, subject to the provisions of
+       Article <a href="#compatibility"><span class="numbering">5.3.4</span></a>. 
+       </p>
+        </div>
+</div>
+<div class="article">
+<h2> Article <span class="numbering">13 </span> - GOVERNING LAW AND JURISDICTION</h2>
+
+        <div class="clause">
+       <p><span class="numbering">13.1 </span>
+       The Agreement is governed by French law.  The
+       Parties agree to endeavor to seek an amicable
+        solution to any disagreements or disputes
+       that may arise during the performance of 
+        the Agreement.
+       </p>
+        </div>
+
+        <div class="clause">
+       <p><span class="numbering">13.2 </span>Failing an amicable solution 
+        within two (2) months as from their
+       occurrence, and unless emergency proceedings are necessary, the
+       disagreements
+       or disputes shall be referred to the Paris Courts having
+       jurisdiction, by the more diligent
+        Party. 
+       </p>
+        </div>
+
+</div>
+
+<div class="footnote">
+       <p><a name="footnote1">
+        1 
+       CeCILL stands for Ce(a) C(nrs) I(nria) L(logiciel) L(ibre)
+        </a></p> 
+</div>
+
+<div class="version">Version 2.0 dated 2005-05-21.</div>
+</body>
+</html>
diff --git a/HTML/Licence_CeCILL_V2-fr.html b/HTML/Licence_CeCILL_V2-fr.html
new file mode 100644 (file)
index 0000000..d2324be
--- /dev/null
@@ -0,0 +1,968 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html><head>
+
+
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"><title>CONTRAT DE LICENCE DE LOGICIEL LIBRE CeCILL</title>
+
+<style type="text/css">
+     h1.title {color: #008080; font-size: 200%; text-align: center}
+     h2 {color: #008080; font-size: 150%}
+     h3 {color: #008080; font-size: 140%} 
+     h4 {color: #008080; font-size: 120%} 
+     h5 {color: #008080; font-size: 100%} 
+     span.numbering {color: #008080}
+     span.definition {font-weight: bold}
+     div.version {font-style: italic}
+     div.footnote {font-size: 80%} 
+     ins {text-decoration: underline; background: #AAFFA4}
+     div.added {text-decoration: underline; background: #AAFFA4}
+     del {text-decoration:line-through; background: #8F8F8F}
+     div.deleted {text-decoration:line-through; background: #8F8F8F}
+  </style></head><body>
+
+<h1 class="title">CONTRAT DE LICENCE DE LOGICIEL LIBRE CeCILL</h1>
+
+
+
+<div class="notice">
+<h2>Avertissement</h2>
+
+<p>Ce
+contrat est une licence de logiciel libre issue d'une
+concertation entre ses auteurs afin que le respect de deux grands
+principes préside à sa rédaction:</p>
+
+
+
+<ul>
+<li>
+d'une part, le respect des principes de diffusion des logiciels libres:
+accès au code  source, droits étendus conférés
+aux utilisateurs,</li>
+<li>
+d'autre
+part, la désignation d'un droit applicable, le droit français, auquel
+elle est conforme, tant au regard
+du droit de la responsabilité civile que du droit de la
+propriété intellectuelle et de la protection qu'il
+offre aux auteurs et titulaires des droits patrimoniaux sur un
+logiciel.</li>
+</ul>
+
+
+
+<p>Les
+auteurs de la licence 
+CeCILL<sup><a href="#footnote1">1</a></sup>
+
+sont:</p>
+
+<p>Commissariat
+à l'Energie Atomique - CEA, établissement
+public de caractère scientifique technique et industriel, dont
+le siège est situé 31-33 rue de la Fédération,
+75752 Paris cedex 15.</p>
+<p>Centre
+National de la Recherche Scientifique - CNRS,
+établissement public à caractère scientifique et
+technologique, dont le siège est situé 3 rue
+Michel-Ange 75794 Paris cedex 16.</p>
+
+<p>Institut
+National de Recherche en Informatique et en Automatique - INRIA,
+établissement public à caractère scientifique et
+technologique, dont le siège est situé Domaine de
+Voluceau, Rocquencourt, BP 105, 78153 Le Chesnay cedex.</p>
+
+</div>
+<div class="preamble">
+<h2>Préambule</h2>
+
+<p>Ce
+contrat est une licence de logiciel libre dont l'objectif est de
+conférer aux utilisateurs la liberté de modification et
+de redistribution du logiciel régi par cette licence dans le
+cadre d'un modèle de diffusion 
+
+en logiciel libre.
+</p>
+<p>L'exercice
+de ces libertés est assorti de certains devoirs à la
+charge des utilisateurs afin de préserver ce statut au cours
+des redistributions ultérieures.
+</p>
+
+<p>L'accessibilité
+au code source et les droits de copie, de modification et de
+redistribution qui en découlent ont pour contrepartie de
+n'offrir aux utilisateurs qu'une garantie limitée
+et de ne faire peser sur l'auteur du logiciel, le titulaire des
+droits patrimoniaux et les concédants successifs qu'une
+responsabilité restreinte.
+</p>
+
+<p>A
+cet égard l'attention de l'utilisateur est attirée
+sur les risques associés au chargement, à
+l'utilisation, à la modification et/ou au développement
+et à la reproduction du logiciel par l'utilisateur étant
+donné sa spécificité de logiciel libre, qui peut
+le rendre complexe à manipuler et qui le réserve donc à
+des développeurs  ou des professionnels avertis
+possédant des connaissances informatiques approfondies. Les utilisateurs sont
+donc invités à charger et tester l'adéquation
+du Logiciel à leurs besoins dans des conditions permettant
+d'assurer la sécurité de leurs systèmes et/ou de leurs données et,
+plus généralement, à l'utiliser et l'exploiter dans les même conditions de
+sécurité. Ce contrat peut être reproduit et diffusé librement, sous réserve
+de le conserver en l'état, sans ajout ni suppression de
+clauses.
+</p>
+<p>Ce
+contrat est susceptible de s'appliquer à tout logiciel
+dont le titulaire des droits patrimoniaux décide de soumettre
+l'exploitation aux dispositions qu'il  contient.</p>
+
+</div>
+<div class="article">
+
+       <h2> Article <span class="numbering">1 </span> - DEFINITIONS</h2>
+
+       <p>Dans
+       ce contrat, les termes suivants, lorsqu'ils seront écrits
+       avec une lettre capitale, auront la signification suivante:</p>
+
+       <p class="definition"><span class="definition">Contrat</span>:
+        
+       désigne le présent contrat de licence, ses
+        éventuelles versions postérieures  et annexes.
+        
+        </p>
+
+        <p class="definition"><span class="definition">Logiciel</span>:
+        
+       désigne le logiciel sous sa forme de Code Objet et/ou de Code
+       Source et le cas échéant sa documentation, dans leur
+       état au moment de l'acceptation du Contrat par le
+       Licencié.
+        
+        </p>
+
+       <p class="definition"><span class="definition">Logiciel Initial</span>:
+        
+        désigne  le Logiciel sous sa forme de
+       Code Source et éventuellement 
+        de Code Objet et le cas échéant sa
+       documentation, dans leur état au moment de leur première
+       diffusion sous les termes du Contrat.
+        
+        </p>
+
+       <p class="definition"><span class="definition">Logiciel Modifié</span>:
+        
+        désigne le Logiciel modifié par au moins une Contribution.
+        </p>
+
+       <p class="definition"><span class="definition">Code Source</span>:
+        
+        désigne l'ensemble des
+       instructions et des lignes de programme du Logiciel et auquel
+       l'accès est nécessaire en vue de modifier le
+       Logiciel.
+        
+        </p>
+
+       <p class="definition"><span class="definition">Code Objet</span>:
+        
+        désigne les fichiers binaires issus de la compilation du 
+        Code Source.
+        
+        </p>
+
+       <p class="definition"><span class="definition">Titulaire</span>:
+        
+        désigne le ou les détenteurs des droits
+        patrimoniaux d'auteur sur le Logiciel Initial
+        
+        </p>
+
+       <p class="definition"><span class="definition">Licencié</span>:
+        
+       désigne le ou les utilisateurs du Logiciel
+        ayant accepté 
+       le Contrat.
+        
+        </p>
+
+       <p class="definition"><span class="definition">Contributeur</span>:
+        
+        désigne le Licencié auteur d'au moins une Contribution.
+        </p>
+
+       <p class="definition"><span class="definition">Concédant</span>:
+        
+       désigne le Titulaire ou toute personne physique ou morale
+       distribuant le Logiciel sous le Contrat.
+        
+        </p>
+
+       <p class="definition"><span class="definition">Contribution</span>:
+        
+       désigne l'ensemble des modifications, corrections,
+       traductions, adaptations et/ou nouvelles fonctionnalités
+       intégrées dans le Logiciel par tout Contributeur,
+       ainsi que  tout
+         Module 
+        Interne.
+        
+        </p>
+
+       <p class="definition"><span class="definition">Module</span>:
+        
+       désigne un ensemble de fichiers sources y compris leur
+       documentation qui
+       permet de réaliser des fonctionnalités ou services
+       supplémentaires à ceux fournis par le Logiciel.
+        
+        </p>
+
+       <p class="definition"><span class="definition">Module Externe</span>:
+        
+        désigne tout Module,   non dérivé du Logiciel, tel que ce
+       Module et le Logiciel   s'exécutent dans 
+        
+        des espaces d'adressages différents, 
+        l'un appelant l'autre au moment de leur exécution. 
+        
+        </p>
+
+       <p class="definition"><span class="definition">Module Interne</span>:
+        
+        désigne tout Module 
+        lié au Logiciel 
+        de telle sorte qu'ils s'exécutent
+        dans le même espace d'adressage.
+        
+        </p>
+        
+        
+        
+        <p class="definition"><span class="definition">GNU GPL</span>:
+        
+        désigne la GNU General Public License dans sa version 2 ou toute
+        version ultérieure, telle que publiée par Free Software Foundation
+        Inc.
+        
+        </p>
+        
+        
+
+       <p class="definition"><span class="definition">Parties</span>:
+        désigne collectivement le Licencié et le Concédant.
+        </p>
+
+       <p>Ces termes s'entendent au singulier comme au pluriel.</p>
+
+</div>
+<div class="article">
+
+       <h2> Article <span class="numbering">2 </span> - OBJET</h2>
+
+       <p>Le
+       Contrat a pour objet la concession par le Concédant au
+       Licencié d'une 
+        licence 
+        non exclusive, 
+        cessible
+       et mondiale du Logiciel telle  
+        que définie ci-après à
+       l'article <a href="#etendue"><span class="numbering">5</span></a> pour toute la durée de protection 
+        des droits portant sur ce Logiciel. 
+       </p>
+
+</div>
+<div class="article">
+
+        <h2> Article <span class="numbering">3 </span> - ACCEPTATION</h2>
+
+        <div class="clause">
+       <p><a name="acceptation-acquise"></a><span class="numbering">3.1 </span>
+       L'acceptation
+       par le Licencié des termes du Contrat est réputée
+       acquise du fait du premier des faits suivants:
+       </p>
+       <ul>
+       <li> (i)
+       le chargement du Logiciel par tout moyen notamment par
+       téléchargement à partir d'un serveur
+       distant ou par chargement à partir d'un support
+       physique;</li>
+       <li>
+       (ii)
+       le premier exercice par le Licencié de l'un quelconque
+       des droits concédés par le Contrat.</li>
+        </ul>
+        </div>
+
+        <div class="clause">
+       <p><span class="numbering">3.2 </span> Un
+       exemplaire du Contrat, contenant notamment un avertissement relatif
+       aux spécificités du Logiciel, à la restriction
+       de garantie et à la limitation à un usage par des
+       utilisateurs expérimentés a été mis à
+       disposition du Licencié préalablement à son
+       acceptation telle que définie à l'article 
+        <a href="#acceptation-acquise"><span class="numbering">3.1</span></a> ci
+       dessus  et le Licencié reconnaît en avoir pris
+       connaissance.</p>
+        </div>
+
+</div>
+<div class="article">
+
+<h2> Article <span class="numbering">4 </span> - ENTREE EN VIGUEUR ET DUREE</h2>
+
+        <div class="clause">
+        <h3>
+<span class="numbering">4.1 </span>ENTREE EN VIGUEUR</h3>
+
+       <p>Le
+       Contrat entre en vigueur à la date de son acceptation par le
+       Licencié telle que définie en <a href="#acceptation-acquise"><span class="numbering">3.1</span></a>.</p>
+
+        </div>
+
+        <div class="clause">
+       <h3>
+<a name="duree"></a><span class="numbering">4.2 </span>DUREE</h3>
+
+       <p>Le
+       Contrat produira ses effets pendant toute la durée légale
+       de protection des droits patrimoniaux portant sur le Logiciel.</p>
+
+        </div>
+
+</div>
+<div class="article">
+
+        <h2>
+<a name="etendue"></a> Article <span class="numbering">5 </span> - ETENDUE DES DROITS CONCEDES</h2>
+
+       <p>Le
+       Concédant concède au Licencié, qui accepte, les
+       droits suivants sur le Logiciel pour toutes destinations et pour la
+       durée du Contrat dans les conditions ci-après
+       détaillées. 
+       </p>
+       <p>
+        Par ailleurs, 
+        
+        
+        si le Concédant détient ou venait à détenir un ou plusieurs
+        brevets d'invention protégeant tout ou partie des fonctionnalités 
+        du Logiciel ou de ses composants, il s'engage à ne pas
+        opposer les éventuels droits conférés par ces brevets aux Licenciés 
+        successifs qui utiliseraient, exploiteraient ou modifieraient le
+        Logiciel. En cas de cession de ces brevets, le 
+        Concédant s'engage à faire reprendre les obligations du présent alinéa
+        aux cessionnaires.
+        </p>
+
+        <div class="clause">
+        <h3>
+<span class="numbering">5.1 </span>DROIT D'UTILISATION</h3>
+
+       <p>Le
+       Licencié est autorisé à utiliser le Logiciel,
+       sans restriction quant aux domaines d'application, étant
+       ci-après précisé que cela comporte:</p>
+       <ol>
+       <li><p>la
+       reproduction permanente ou provisoire du Logiciel en tout ou partie
+       par tout moyen et sous toute forme. 
+       </p></li>
+       <li>
+<p>le
+       chargement, l'affichage, l'exécution, ou le
+       stockage du Logiciel sur tout support.</p>
+        </li>
+       <li>
+<p>la
+       possibilité d'en observer, d'en étudier,
+       ou d'en tester le fonctionnement afin de déterminer
+       les idées et principes qui sont à la base de
+       n'importe quel élément de ce Logiciel; et
+       ceci, lorsque le Licencié effectue toute opération de
+       chargement, d'affichage, d'exécution, de
+       transmission ou de stockage du Logiciel qu'il est en droit
+       d'effectuer en vertu du Contrat.</p>
+        </li>
+       </ol>
+
+        </div>
+
+        <div class="clause">
+        <h3>
+<span class="numbering">5.2 </span>DROIT D'APPORTER DES CONTRIBUTIONS</h3>
+
+       <p>
+       Le
+       droit d'apporter des Contributions comporte le droit de
+       traduire, d'adapter, d'arranger ou d'apporter
+       toute autre modification 
+        au Logiciel et le droit de reproduire le
+       Logiciel en résultant.</p>
+       <p>Le
+       Licencié est autorisé à apporter toute
+       Contribution au Logiciel sous réserve de mentionner, de façon
+       explicite, son nom en tant qu'auteur de cette Contribution et
+       la date de création de celle-ci.</p>
+
+        </div>
+
+        <div class="clause">
+       <h3>
+<span class="numbering">5.3 </span>DROIT
+       DE DISTRIBUTION </h3>
+
+       <p>Le
+       droit de distribution 
+        comporte notamment le droit de diffuser, de
+       transmettre et de  communiquer le Logiciel au public sur tout
+       support et par tout moyen ainsi que le droit de mettre sur le marché
+       à titre onéreux ou gratuit, un ou des exemplaires du
+       Logiciel par tout procédé.</p>
+       <p>Le
+       Licencié est autorisé à 
+        distribuer des copies
+       du Logiciel, modifié ou non, à des tiers dans les
+       conditions ci-après détaillées.</p>
+
+        <div class="subclause">
+        <h4>
+<span class="numbering">5.3.1 </span>DISTRIBUTION
+       DU LOGICIEL SANS MODIFICATION</h4>
+
+       <p>Le
+       Licencié est autorisé à 
+        distribuer des copies
+       conformes du Logiciel, sous forme de Code Source ou de Code Objet,
+        à condition que cette distribution respecte les
+        dispositions du Contrat dans leur totalité et soit accompagnée:</p>
+       <ol>
+       <li><p>d'un
+         exemplaire du Contrat,</p></li>
+       <li><p>d'un
+        avertissement relatif à la restriction de garantie et de
+        responsabilité du Concédant telle que prévue
+        aux articles <a href="#responsabilite"><span class="numbering">8</span></a> et 
+         <a href="#garantie"><span class="numbering">9</span></a>,</p></li>
+       </ol>
+       <p>et
+       que, dans le cas où seul le Code Objet du Logiciel est
+       redistribué, le Licencié permette aux futurs
+        Licenciés 
+       d'accéder facilement au Code Source complet du Logiciel
+       en indiquant les modalités d'accès, étant
+       entendu que le coût additionnel d'acquisition du Code
+       Source ne devra pas excéder le simple coût de transfert
+       des données.</p>
+        </div>
+
+        <div class="subclause">
+       <h4>
+<span class="numbering">5.3.2 </span>DISTRIBUTION
+               DU LOGICIEL MODIFIE</h4>
+
+        
+       <p>Lorsque
+       le Licencié apporte une Contribution au Logiciel, les
+       conditions de distribution du Logiciel Modifié sont alors
+       soumises à l'intégralité des dispositions
+       du Contrat. 
+       </p>
+       <p>Le
+       Licencié est autorisé à distribuer le
+       Logiciel Modifié, sous forme de Code Source ou de Code Objet,
+       à condition que cette distribution respecte les
+       dispositions du Contrat dans leur totalité et soit
+       accompagnée: 
+       </p>
+       <ol>
+        <li><p>d'un
+            exemplaire du Contrat,</p></li>
+         <li>
+<p>d'un
+               avertissement relatif à la restriction de garantie et de
+               responsabilité du  Concédant telle que
+                prévue aux articles <a href="#responsabilite"><span class="numbering">8</span></a> et 
+                <a href="#garantie"><span class="numbering">9</span></a>,</p>
+         </li>
+       </ol>
+       <p>et que, dans le cas où seul le Code Objet du Logiciel
+        Modifié est redistribué, le Licencié permette aux futurs
+       Licenciés d'accéder facilement au Code Source complet du Logiciel
+        Modifié en indiquant les modalités d'accès, étant entendu que le coût
+       additionnel d'acquisition du Code Source ne devra pas excéder le
+        simple coût de transfert des données.</p> 
+        
+
+        
+        </div>
+
+        <div class="subclause">
+       <h4>
+<span class="numbering">5.3.3 </span>DISTRIBUTION DES MODULES 
+                
+               EXTERNES</h4>
+
+       <p>Lorsque le Licencié a développé un Module 
+        Externe les conditions du Contrat ne s'appliquent pas à ce
+        Module Externe, qui peut être
+        distribué sous un contrat de  licence différent.</p>
+
+        </div>
+
+        <div class="subclause">
+
+        
+       <h4>
+<a name="compatibilite"></a><span class="numbering">5.3.4 </span>COMPATIBILITE AVEC LA LICENCE 
+               GNU GPL</h4>
+
+        
+
+        
+        <p> Le Licencié peut inclure un code soumis aux dispositions d'une
+        des versions de la licence GNU GPL dans le Logiciel modifié ou non et
+        distribuer l'ensemble sous les conditions de la même version de la
+        licence GNU GPL. 
+        </p>
+         
+        <p> Le Licencié peut inclure le Logiciel modifié ou non dans un code
+        soumis aux dispositions d'une des versions de la licence GNU GPL et
+        distribuer l'ensemble sous les conditions de la même version de la
+        licence GNU GPL. 
+        </p>
+        
+
+        
+
+        
+
+        </div>
+
+        </div>
+
+</div>
+<div class="article">
+
+        <h2> Article <span class="numbering">6 </span> - PROPRIETE INTELLECTUELLE</h2>
+
+        <div class="clause">
+        <h3>
+<span class="numbering">6.1 </span>SUR LE LOGICIEL INITIAL</h3>
+
+       <p>Le
+       Titulaire est détenteur des droits patrimoniaux sur le
+       Logiciel Initial. Toute utilisation du Logiciel Initial est soumise
+       au respect des conditions dans lesquelles le Titulaire a choisi de
+       diffuser son oeuvre et nul autre n'a la faculté de
+       modifier les conditions de diffusion de ce Logiciel Initial. 
+       </p>
+       <p>Le
+       Titulaire s'engage à 
+        ce que le Logiciel Initial 
+        
+        reste  au moins régi par la présente
+        licence
+         et ce, pour la durée visée à l'article <a href="#duree"><span class="numbering">4.2</span></a>.</p>
+
+        </div>
+
+        <div class="clause">
+        <h3>
+<span class="numbering">6.2 </span>SUR LES CONTRIBUTIONS</h3>
+
+       <p>
+        
+        
+        Le Licencié qui a développé une Contribution est titulaire
+        sur celle-ci des droits de propriété intellectuelle dans les conditions
+        définies par la législation applicable.
+        
+        </p>
+
+        </div>
+
+        <div class="clause">
+        <h3>
+<span class="numbering">6.3 </span>SUR LES MODULES 
+        EXTERNES</h3>
+
+       <p>
+        Le
+       Licencié 
+         qui a développé un Module Externe est titulaire
+        sur celui-ci des droits de propriété intellectuelle dans les conditions
+        définies par la législation applicable
+        et reste
+        libre du choix du contrat régissant
+       sa diffusion.</p>
+
+        </div>        
+
+        <div class="clause">
+       <h3>
+<a name="citations"></a><span class="numbering">6.4 </span>DISPOSITIONS COMMUNES</h3>
+
+        
+        <div class="subclause">
+       <p>
+        Le Licencié s'engage expressément:</p>
+       <ol>
+           <li>
+<p>à
+       ne pas supprimer ou modifier de quelque manière que ce soit
+       les mentions de propriété intellectuelle apposées
+       sur le Logiciel;</p>
+        </li>
+       <li>
+<p>à reproduire à l'identique lesdites mentions de
+       propriété intellectuelle sur les copies du Logiciel modifié ou
+        non.</p> 
+        </li>
+       </ol>
+        </div>
+        
+
+        
+
+        <div class="subclause">
+       <p>Le
+       Licencié s'engage à ne pas porter atteinte,
+       directement ou indirectement, aux droits de propriété
+       intellectuelle du Titulaire et/ou des Contributeurs 
+        sur le Logiciel et à
+       prendre, le cas échéant, à l'égard
+       de son personnel toutes les mesures nécessaires pour assurer
+       le respect des dits droits de propriété intellectuelle
+       du Titulaire et/ou des Contributeurs.</p>
+        </div>
+
+        </div>
+
+</div>
+<div class="article">
+
+        <h2> Article <span class="numbering">7 </span> - SERVICES ASSOCIES</h2>
+
+        <div class="clause">
+       <p><span class="numbering">7.1 </span>Le
+       Contrat n'oblige en aucun cas le Concédant à la
+       réalisation de prestations d'assistance technique ou de
+       maintenance du Logiciel.</p>
+       <p>Cependant
+       le Concédant reste libre de proposer ce type de services. Les
+       termes et conditions d'une telle assistance technique et/ou
+       d'une telle maintenance seront alors déterminés
+       dans un acte séparé. Ces actes de maintenance et/ou
+       assistance technique n'engageront que la seule responsabilité
+       du Concédant qui les propose.</p>
+        </div>
+        <div class="clause">
+       <p><span class="numbering">7.2 </span>De
+       même, tout Concédant est libre de proposer, sous sa
+       seule responsabilité, à ses licenciés une
+       garantie, qui n'engagera que lui, lors de la redistribution du
+       Logiciel et/ou du Logiciel Modifié et ce, dans les conditions
+       qu'il souhaite. Cette garantie et les modalités
+       financières de son application feront l'objet d'un
+       acte séparé entre le Concédant et le Licencié.</p>
+        </div>
+
+</div>
+<div class="article">
+
+        <h2>
+<a name="responsabilite"></a> Article <span class="numbering">8 </span> - RESPONSABILITE</h2>
+
+        <div class="clause">
+       <p><span class="numbering">8.1 </span>Sous
+       réserve des dispositions de
+        l'article <a href="#limite-responsabilite"><span class="numbering">8.2</span></a>, 
+        
+        le Licencié a la faculté, sous réserve de prouver la faute du
+       Concédant concerné, de solliciter la réparation
+       du préjudice direct qu'il  subirait du fait du
+        logiciel et dont il apportera la preuve.
+        </p>
+        </div>
+
+        <div class="clause">
+       <p><a name="limite-responsabilite"></a><span class="numbering">8.2 </span>
+        La
+       responsabilité du Concédant est limitée aux
+       engagements pris en application du Contrat et ne saurait être
+       engagée en raison notamment: (i) des dommages dus à
+       l'inexécution, totale ou partielle, de ses obligations
+       par le Licencié, (ii) des dommages directs ou indirects
+       découlant de l'utilisation ou des performances du
+       Logiciel subis par le Licencié 
+        
+        et  (iii) 
+        plus généralement d'un quelconque 
+         dommage 
+        indirect. 
+        En particulier, les Parties
+       conviennent expressément que tout préjudice financier
+       ou commercial (par exemple perte de données, perte de
+       bénéfices, perte d'exploitation, perte de
+       clientèle ou de commandes, manque à gagner, trouble
+       commercial quelconque) ou  toute action dirigée contre le
+       Licencié par un tiers, constitue un dommage indirect et
+       n'ouvre pas droit à réparation par le
+        Concédant.
+        </p> 
+        </div>
+
+</div>
+<div class="article">
+
+        <h2>
+<a name="garantie"></a> Article <span class="numbering">9 </span> - GARANTIE</h2>
+
+        <div class="clause">
+       <p><span class="numbering">9.1 </span>
+       Le
+       Licencié reconnaît que l'état actuel des
+       connaissances scientifiques et techniques au moment de la mise en
+       circulation du Logiciel ne permet pas d'en tester et d'en
+       vérifier toutes les utilisations ni de détecter
+       l'existence d'éventuels défauts.
+       L'attention du Licencié a été attirée
+       sur ce point sur les risques associés au chargement, à
+       l'utilisation, la modification et/ou au développement
+       et à la reproduction du Logiciel qui sont réservés
+       à des utilisateurs avertis.</p>
+       <p>Il
+       relève de la responsabilité du Licencié de
+       contrôler, par tous moyens, l'adéquation du
+       produit à ses besoins, son bon fonctionnement et de s'assurer
+       qu'il ne causera pas de dommages aux personnes et aux biens.
+       </p>
+        </div>
+
+        <div class="clause">
+       <p><a name="bonne-foi"></a><span class="numbering">9.2 </span>
+       Le Concédant déclare de bonne foi être en droit
+       de concéder l'ensemble des droits attachés au Logiciel
+       (comprenant notamment les droits visés à l'article 
+        <a href="#etendue"><span class="numbering">5</span></a>).
+        </p> 
+        </div>
+
+        <div class="clause">
+       <p><span class="numbering">9.3 </span>Le
+       Licencié reconnaît que le Logiciel est fourni "en
+       l'état" par le Concédant sans autre
+       garantie, expresse ou tacite, que celle prévue à
+       l'article <a href="#bonne-foi"><span class="numbering">9.2</span></a> et notamment sans aucune garantie sur sa
+        valeur commerciale, son caractère sécurisé, innovant
+       ou pertinent.
+       </p>
+       <p>En
+       particulier, le Concédant ne garantit pas que le Logiciel est
+       exempt d'erreur, qu'il fonctionnera sans interruption,
+        qu'il 
+       sera compatible avec l'équipement du Licencié et
+       sa configuration logicielle ni qu'il remplira les besoins du
+       Licencié.</p>
+        </div>
+
+        <div class="clause">
+       <p><span class="numbering">9.4 </span>Le
+       Concédant ne garantit pas, de manière expresse ou
+       tacite, que le Logiciel ne porte pas atteinte à un quelconque
+       droit de propriété intellectuelle d'un tiers
+       portant sur un brevet, un logiciel ou sur tout autre droit de
+       propriété. Ainsi, le Concédant exclut toute
+       garantie au profit du Licencié contre les actions en
+       contrefaçon qui pourraient être diligentées au
+       titre de l'utilisation, de la modification, et de la
+       redistribution du Logiciel. Néanmoins, si de telles actions
+       sont exercées contre le Licencié, le Concédant
+       lui apportera son aide technique et juridique pour sa défense.
+       Cette aide technique et juridique est déterminée au
+       cas par cas entre le Concédant concerné et le
+        Licencié 
+       dans le cadre d'un protocole d'accord. Le Concédant
+       dégage toute responsabilité quant à
+       l'utilisation de la dénomination du Logiciel par le
+       Licencié. Aucune garantie n'est apportée quant
+        à 
+       l'existence de droits antérieurs sur le nom du Logiciel
+       et sur l'existence d'une marque.</p>
+        </div>
+
+</div>
+<div class="article">
+
+        <h2> Article <span class="numbering">10 </span> - RESILIATION</h2>
+    
+        <div class="clause">
+       <p><span class="numbering">10.1 </span>En
+       cas de manquement par le Licencié aux obligations mises à
+       sa charge par le Contrat, le Concédant pourra résilier
+       de plein droit le Contrat trente (30) jours après
+       notification adressée au Licencié et restée
+       sans effet.</p>
+        </div>
+
+        <div class="clause">
+       <p><span class="numbering">10.2 </span>Le
+       Licencié dont le Contrat est résilié n'est
+       plus autorisé à utiliser, modifier ou distribuer le
+       Logiciel. Cependant, toutes les licences qu'il aura
+        concédées 
+       antérieurement à la résiliation du Contrat
+       resteront valides sous réserve qu'elles aient
+        été 
+       effectuées en conformité avec le Contrat.</p>
+        </div>
+
+</div>
+<div class="article">
+
+        <h2> Article <span class="numbering">11 </span> - DISPOSITIONS DIVERSES</h2>
+
+        <div class="clause">
+        <h3>
+<span class="numbering">11.1 </span>CAUSE EXTERIEURE</h3>
+
+       <p>Aucune
+       des Parties ne sera responsable d'un retard ou d'une
+       défaillance d'exécution du Contrat qui serait dû
+       à un cas de force majeure, un cas fortuit ou une cause
+       extérieure, telle que, notamment, le mauvais fonctionnement
+       ou les interruptions du réseau électrique ou de
+       télécommunication, la paralysie du réseau liée
+       à une attaque informatique, l'intervention des
+       autorités gouvernementales, les catastrophes naturelles, les
+       dégâts des eaux, les tremblements de terre, le feu, les
+       explosions, les grèves et les conflits sociaux, l'état
+       de guerre...</p>
+        </div>
+        <div class="clause">
+       <p><span class="numbering">11.2 </span>Le
+       fait, par l'une ou l'autre des Parties, d'omettre
+       en une ou plusieurs occasions de se prévaloir d'une ou
+       plusieurs dispositions du Contrat, ne pourra en aucun cas impliquer
+       renonciation par la Partie intéressée à s'en
+       prévaloir ultérieurement.</p>
+        </div>
+
+        <div class="clause">
+       <p><span class="numbering">11.3 </span>Le
+       Contrat annule et remplace toute convention antérieure,
+       écrite ou orale, entre les Parties sur le même objet et
+       constitue l'accord entier entre les Parties sur cet objet.
+       Aucune addition ou modification aux termes du Contrat n'aura
+       d'effet à l'égard des Parties à
+       moins d'être faite par écrit et signée par
+       leurs représentants dûment habilités.</p>
+        </div>
+
+        <div class="clause">
+       <p><span class="numbering">11.4 </span>Dans
+       l'hypothèse où une ou plusieurs des dispositions
+       du Contrat s'avèrerait contraire à une loi ou à
+       un texte applicable, existants ou futurs, cette loi ou ce texte
+       prévaudrait, et les Parties feraient les amendements
+       nécessaires pour se conformer à cette loi ou à
+       ce texte. Toutes les autres dispositions resteront en vigueur. De
+       même, la nullité, pour quelque raison que ce soit,
+       d'une des dispositions du Contrat ne saurait entraîner
+       la nullité de l'ensemble du Contrat.</p>
+        </div>
+
+        <div class="clause">
+        <h3>
+<span class="numbering">11.5 </span>LANGUE</h3>
+       <p>Le
+       Contrat est rédigé en langue française et en
+       langue anglaise, ces deux versions 
+        faisant également foi.
+        </p>
+        </div>
+
+</div>
+<div class="article">
+
+        <h2> Article <span class="numbering">12 </span> - NOUVELLES VERSIONS DU CONTRAT</h2>
+
+        <div class="clause">
+       <p><span class="numbering">12.1 </span>Toute personne est autorisée à copier et distribuer des
+       copies de ce Contrat.</p>
+        </div>
+
+        <div class="clause">
+       <p><span class="numbering">12.2 </span>Afin     d'en préserver la cohérence, le texte du Contrat
+       est protégé et ne peut être modifié que
+       par les auteurs de la licence, lesquels se réservent le droit
+       de publier périodiquement des mises à jour ou de
+       nouvelles versions du Contrat, qui possèderont chacune un
+       numéro distinct. Ces versions ultérieures seront
+       susceptibles de prendre en compte de nouvelles problématiques
+       rencontrées par les logiciels libres.</p>
+        </div>
+
+        <div class="clause">
+       <p><span class="numbering">12.3 </span>Tout
+       Logiciel diffusé sous une version donnée du Contrat ne
+       pourra faire l'objet d'une diffusion ultérieure que sous la
+       même version du Contrat ou une version postérieure,
+       sous réserve des dispositions de l'article 
+        <a href="#compatibilite"><span class="numbering">5.3.4</span></a>.</p>
+        </div>
+
+</div>
+<div class="article">  
+
+        <h2> Article <span class="numbering">13 </span> - LOI APPLICABLE ET COMPETENCE TERRITORIALE</h2>
+
+        <div class="clause">
+       <p><span class="numbering">13.1 </span>
+       Le Contrat est régi par la loi
+       française. Les Parties conviennent de tenter de régler
+       à l'amiable les différends ou litiges qui
+       viendraient à se produire par suite ou à l'occasion
+       du Contrat.
+       </p>
+        </div>
+
+        <div class="clause">
+        <p><span class="numbering">13.2 </span>
+       A défaut d'accord amiable dans un délai de deux
+       (2) mois à compter de leur survenance et sauf situation
+       relevant d'une procédure d'urgence, les
+       différends ou litiges seront portés par la Partie la
+       plus diligente devant les Tribunaux compétents de
+        Paris.</p>
+        </div>
+
+</div>
+
+<div class="footnote">
+       <p><a name="footnote1">
+        
+        1 CeCILL est pour
+        Ce(a) C(nrs) I(nria) L(ogiciel) L(ibre)</a></p>
+</div>
+
+<div class="version">Version 2.0 du 2005-05-21.</div>
+
+</body></html>
\ No newline at end of file
diff --git a/HTML/PKG-INFO b/HTML/PKG-INFO
new file mode 100644 (file)
index 0000000..79c627c
--- /dev/null
@@ -0,0 +1,20 @@
+Metadata-Version: 1.0\r
+Name: HTML.py\r
+Version: 0.04\r
+Summary: A Python module to easily generate HTML code (tables, lists, ...).\r
+See http://www.decalage.info/python/html for more information.\r
+\r
+Home-page: http://www.decalage.info/python/html\r
+Author: Philippe Lagadec\r
+Author-email: decalage (a) laposte.net\r
+License: CeCILL (open-source GPL compatible)\r
+Download-URL: http://www.decalage.info/python/html\r
+Description: UNKNOWN\r
+Platform: UNKNOWN\r
+Classifier: Development Status :: 4 - Beta\r
+Classifier: Natural Language :: English\r
+Classifier: Intended Audience :: Developers\r
+Classifier: Topic :: Internet :: WWW/HTTP\r
+Classifier: Operating System :: OS Independent\r
+Classifier: Programming Language :: Python\r
+Classifier: Topic :: Software Development :: Libraries :: Python Modules\r
diff --git a/HTML/README.txt b/HTML/README.txt
new file mode 100644 (file)
index 0000000..7529225
--- /dev/null
@@ -0,0 +1,29 @@
+HTML.py\r
+\r
+This module provides a few classes to easily generate HTML tables and lists.\r
+\r
+Author: Philippe Lagadec\r
+\r
+Project website: http://www.decalage.info/python/html\r
+\r
+License: CeCILL (open-source GPL compatible), see source code for details.\r
+         http://www.cecill.info\r
+\r
+-------------------------------------------------------------------------------\r
+\r
+INSTALLATION:\r
+\r
+- on Windows, double-click on install.bat, or type "setup.py install" in a CMD\r
+  window.\r
+- on other systems, type "python setup.py install" in a shell.\r
+\r
+-------------------------------------------------------------------------------\r
+\r
+HOW TO USE THIS MODULE:\r
+\r
+First have a look at HTML_tutorial.py. It provides examples of how to use\r
+HTML.py.\r
+See http://www.decalage.info/python/html for additional information and updates.\r
+For complete reference see HTML.py.html, and also the source code of HTML.py.\r
+\r
+\r
diff --git a/HTML/setup.py b/HTML/setup.py
new file mode 100644 (file)
index 0000000..0c23afe
--- /dev/null
@@ -0,0 +1,41 @@
+"""\r
+Setup script for HTML.py\r
+"""\r
+\r
+import distutils.core\r
+import HTML\r
+\r
+DESCRIPTION = """A Python module to easily generate HTML code (tables, lists, ...).\r
+See http://www.decalage.info/python/html for more information.\r
+"""\r
+\r
+kw = {\r
+    'name': "HTML.py",\r
+    'version': HTML.__version__,\r
+    'description': DESCRIPTION,\r
+    'author': "Philippe Lagadec",\r
+    'author_email': "decalage (a) laposte.net",\r
+    'url': "http://www.decalage.info/python/html",\r
+    'license': "CeCILL (open-source GPL compatible)",\r
+    'py_modules': ['HTML']\r
+    }\r
+\r
+\r
+# If we're running Python 2.3+, add extra information\r
+if hasattr(distutils.core, 'setup_keywords'):\r
+    if 'classifiers' in distutils.core.setup_keywords:\r
+        kw['classifiers'] = [\r
+            'Development Status :: 4 - Beta',\r
+            #'License :: Freely Distributable',\r
+            'Natural Language :: English',\r
+            'Intended Audience :: Developers',\r
+            'Topic :: Internet :: WWW/HTTP',\r
+            'Operating System :: OS Independent',\r
+            'Programming Language :: Python',\r
+            'Topic :: Software Development :: Libraries :: Python Modules'\r
+          ]\r
+    if 'download_url' in distutils.core.setup_keywords:\r
+        kw['download_url'] = "http://www.decalage.info/python/html"\r
+\r
+\r
+distutils.core.setup(**kw)\r
diff --git a/INSTALL_WINDOWS b/INSTALL_WINDOWS
new file mode 100644 (file)
index 0000000..0b1052e
--- /dev/null
@@ -0,0 +1,22 @@
+dépendances :
+R 2.10.1
+http://cran.cict.fr/bin/windows/
+
+python 2.6
+http://www.python.org/
+
+Numpy
+http://surfnet.dl.sourceforge.net/sourceforge/numpy/
+
+wxpython
+http://surfnet.dl.sourceforge.net/sourceforge/wxpython/
+
+xlrd
+
+package de R :
+rgl
+ca
+gee
+ape
+igraph
+proxy
diff --git a/KeyFrame.py b/KeyFrame.py
new file mode 100755 (executable)
index 0000000..2c40909
--- /dev/null
@@ -0,0 +1,160 @@
+# -*- coding: utf-8 -*-
+#Author: Pierre Ratinaud
+#Copyright (c) 2008 Pierre Ratinaud
+#Lisense: GNU/GPL
+
+import wx
+from functions import sortedby
+
+# begin wxGlade: extracode
+# end wxGlade
+
+class AlcOptFrame(wx.Dialog):
+    def __init__(self,parent, *args, **kwds):
+        # begin wxGlade: AlcOptFrame.__init__
+        kwds["style"] = wx.DEFAULT_DIALOG_STYLE
+        wx.Dialog.__init__(self, *args, **kwds)
+        self.cle={
+        'adj_sup': [wx.NewId(),wx.NewId(),u"Adjectif supplémentaire"],
+        'art_ind': [wx.NewId(),wx.NewId(),u"Article indéfini"],
+        'adj_pos': [wx.NewId(),wx.NewId(),u"Adjectif possessif"],
+        'adv_sup': [wx.NewId(),wx.NewId(),u"Adverbe supplémentaire"],
+        'pro_dem': [wx.NewId(),wx.NewId(),u"Pronom démonstratif"],
+        'art_def': [wx.NewId(),wx.NewId(),u"Article défini"],
+        'con': [wx.NewId(),wx.NewId(),u"Conjonction"],
+        'pre': [wx.NewId(),wx.NewId(),u"Préposition"],
+        'ono': [wx.NewId(),wx.NewId(),u"Onomatopée"],
+        'adj_dem': [wx.NewId(),wx.NewId(),u"Adjectif démonstratif"],
+        'nom_sup': [wx.NewId(),wx.NewId(),u"Nom supplémentaire"],
+        'adv': [wx.NewId(),wx.NewId(),u"Adverbe"],
+        'pro_per': [wx.NewId(),wx.NewId(),u"Pronom personnel"],
+        'ver': [wx.NewId(),wx.NewId(),u"Verbe"],
+        'adj_num': [wx.NewId(),wx.NewId(),u"Adjectif numérique"],
+        'pro_rel': [wx.NewId(),wx.NewId(),u"Pronom relatif"],
+        'adj_ind': [wx.NewId(),wx.NewId(),u"Adjectif indéfini"],
+        'pro_ind': [wx.NewId(),wx.NewId(),u"Pronom indéfini"],
+        'pro_pos': [wx.NewId(),wx.NewId(),u"Pronom possessif"],
+        'aux': [wx.NewId(),wx.NewId(),u"Auxiliaire"],
+        'ver_sup': [wx.NewId(),wx.NewId(),u"Verbe supplémentaire"],
+        'adj': [wx.NewId(),wx.NewId(),u"Adjectif"],
+        'adj_int': [wx.NewId(),wx.NewId(),u"Adjectif interrogatif"],
+        'nom': [wx.NewId(),wx.NewId(),u"Nom commun"],
+        'num' : [wx.NewId(),wx.NewId(),u"Chiffre"],
+        'nr' : [wx.NewId(),wx.NewId(),u"Formes non reconnues"],
+        }
+        self.parent=parent
+        self.KeyConf=self.parent.KeyConf
+        self.listlabel=[]
+        self.listspin=[]
+        self.listbutton=[]
+        self.listcle=[]
+        self.listids=[]
+        self.listidb=[]
+        
+        self.label_1 = wx.StaticText(self, -1, u"        Choix des clés d'analyse\n0=éliminé ; 1=active ; 2=supplémentaire\n")
+        self.listcleori=[[cle]+self.cle[cle] for cle in self.cle]
+        self.listcleori=sortedby(self.listcleori,1,3)
+
+        for line in self.listcleori:
+            cle,ids,idb,label=line
+            self.listlabel.append(wx.StaticText(self, -1, label))
+            self.listspin.append(wx.SpinCtrl(self, ids,self.KeyConf.get('KEYS',cle), min=0, max=2))
+            #if cle != 'nr' and cle!= 'num' : 
+            self.listbutton.append(wx.Button(self, idb, u"voir liste"))
+            self.listids.append(ids)
+            self.listidb.append(idb)
+            self.listcle.append(cle)
+            
+
+        self.button_val = wx.Button(self,wx.ID_APPLY)
+        
+        for button in self.listbutton :
+            self.Bind(wx.EVT_BUTTON,self.OnShowList,button)
+        
+        self.Bind(wx.EVT_BUTTON, self.OnApply, self.button_val)
+        
+        self.dico=self.parent.parent.lexique#'dictionnaires/lexique.txt')
+
+        self.__set_properties()
+        self.__do_layout()
+        # end wxGlade
+
+    def __set_properties(self):
+        # begin wxGlade: AlcOptFrame.__set_properties
+        self.SetTitle(u"Clés d'analyse")
+        # end wxGlade
+
+    def __do_layout(self):
+        # begin wxGlade: AlcOptFrame.__do_layout
+        sizer_1 = wx.BoxSizer(wx.VERTICAL)
+        sizer_2 = wx.BoxSizer(wx.VERTICAL)
+        sizer_3 = wx.BoxSizer(wx.HORIZONTAL)
+        grid_sizer_1 = wx.GridSizer(14, 3, 0, 0)
+        grid_sizer_2 = wx.GridSizer(14, 3, 0, 0)
+        sizer_2.Add(self.label_1, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 0)
+        for i in range(0,14):
+            grid_sizer_1.Add(self.listlabel[i], 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 0)
+            grid_sizer_1.Add(self.listspin[i], 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 0)
+            grid_sizer_1.Add(self.listbutton[i], 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 0)
+        for i in range(13,len(self.listlabel)):
+            grid_sizer_2.Add(self.listlabel[i], 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 0)
+            grid_sizer_2.Add(self.listspin[i], 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 0)
+            grid_sizer_2.Add(self.listbutton[i], 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_CENTER_VERTICAL, 0)
+        sizer_3.Add(grid_sizer_1, 1, wx.EXPAND, 0)
+        sizer_3.Add(grid_sizer_2, 1, wx.EXPAND, 0)
+        sizer_2.Add(sizer_3, 1, wx.EXPAND, 8)
+        sizer_2.Add(self.button_val,0, wx.ALIGN_CENTER_HORIZONTAL, 0)
+        sizer_1.Add(sizer_2, 1, wx.EXPAND, 0)
+        self.SetSizer(sizer_1)
+        sizer_1.Fit(self)
+        self.Layout()
+        # end wxGlade
+
+    def OnShowList(self,evt):
+        id=evt.GetEventObject().GetId()
+        pos=self.listidb.index(id)
+        type=self.listcle[pos]
+        self.CreateList(type)
+        
+    def CreateList(self,type):
+        if type=='ver_sup' or type=='ver':
+            liste=[descr[0] for item,descr in self.dico.iteritems() if descr[1]==type]
+            liste=list(set(liste))
+        else:
+            liste=[item for item,descr in self.dico.iteritems() if descr[1]==type]
+        liste.sort()
+        txt=('\n').join(liste)
+        ListViewFrame=ListView(self.parent.parent)
+        ListViewFrame.text_ctrl_1.WriteText(txt)
+        ListViewFrame.text_ctrl_1.SetSelection(0,0)
+        ListViewFrame.text_ctrl_1.SetInsertionPoint(0)
+        ListViewFrame.CenterOnParent()
+        val=ListViewFrame.ShowModal()
+    
+    def OnApply(self,evt):
+        for i in range(0,len(self.listlabel)):
+            self.KeyConf.set('KEYS',self.listcle[i],`self.listspin[i].GetValue()`)
+        self.Destroy()
+
+
+class ListView(wx.Dialog):
+    def __init__(self, parent):
+        wx.Dialog.__init__(self, parent, size=wx.Size(200, 400),style=wx.DEFAULT_DIALOG_STYLE)
+        self.text_ctrl_1 = wx.TextCtrl(self, -1, "", style=wx.TE_MULTILINE|wx.TE_RICH2)
+        self.text_ctrl_1.SetMinSize(wx.Size(200, 400))
+        self.btn = wx.Button(self, wx.ID_OK)
+        self.SetMinSize(wx.Size(200, 400))
+        self.__set_properties()
+        self.__do_layout()
+
+    def __set_properties(self):
+        self.SetTitle("Liste")
+
+    def __do_layout(self):
+        sizer_1 = wx.BoxSizer(wx.VERTICAL)
+        sizer_1.Add(self.text_ctrl_1, 1, wx.EXPAND, 0)
+        sizer_1.Add(self.btn,0,wx.EXPAND,0)
+        self.SetSizer(sizer_1)
+        sizer_1.Fit(self)
+        self.Layout()
+
diff --git a/Liste.py b/Liste.py
new file mode 100644 (file)
index 0000000..86ec3bf
--- /dev/null
+++ b/Liste.py
@@ -0,0 +1,315 @@
+# -*- coding: utf-8 -*-
+
+#----------------------------------------------------------------------------
+# Name:         ListCtrl.py
+# Author:       Pierre Ratinaud
+# 
+
+#comes from ListCtrl.py from the demo tool of wxPython:
+# Author:       Robin Dunn & Gary Dumer
+#
+# Created:
+# Copyright:    (c) 1998 by Total Control Software
+# Licence:      wxWindows license
+#----------------------------------------------------------------------------
+
+import os
+import sys
+import  wx
+from dialog import SearchDial
+import wx.lib.mixins.listctrl as listmix 
+import cStringIO
+
+#---------------------------------------------------------------------------
+
+class List(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin):
+    def __init__(self, parent, ID, pos=wx.DefaultPosition,
+                 size=wx.DefaultSize, style=0):
+        wx.ListCtrl.__init__(self, parent, ID, pos, size, style)
+        listmix.ListCtrlAutoWidthMixin.__init__(self)
+
+
+class ListPanel(wx.Panel, listmix.ColumnSorterMixin):
+    def __init__(self, parent, gparent, dlist):
+        self.parent = parent
+        self.gparent = gparent
+        self.source = gparent
+        self.dlist = dlist
+        wx.Panel.__init__(self, parent, -1, style=wx.WANTS_CHARS)
+        
+        search_id = wx.NewId()
+        self.parent.Bind(wx.EVT_MENU, self.onsearch, id = search_id)
+        self.accel_tbl = wx.AcceleratorTable([(wx.ACCEL_CTRL, ord('F'), search_id)])
+        self.SetAcceleratorTable(self.accel_tbl)
+        
+        self.il = wx.ImageList(16, 16)
+        self.sm_up = self.il.Add(getSmallUpArrowBitmap())
+        self.sm_dn = self.il.Add(getSmallDnArrowBitmap())
+
+
+        tID = wx.NewId()
+
+        self.list = List(self, tID,
+                                 style=wx.LC_REPORT 
+                                 | wx.BORDER_NONE
+                                 | wx.LC_EDIT_LABELS
+                                 | wx.LC_SORT_ASCENDING
+                                 )
+        
+        
+        self.list.SetImageList(self.il, wx.IMAGE_LIST_SMALL)
+        self.PopulateList(dlist)
+
+        self.Bind(wx.EVT_SIZE, self.OnSize)
+
+        self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self.list)
+        self.Bind(wx.EVT_LIST_COL_CLICK, self.OnColClick, self.list)
+        # for wxMSW
+        self.list.Bind(wx.EVT_COMMAND_RIGHT_CLICK, self.OnRightClick)
+
+        # for wxGTK
+        self.list.Bind(wx.EVT_RIGHT_UP, self.OnRightClick)
+        self.itemDataMap = dlist
+
+        listmix.ColumnSorterMixin.__init__(self, 3)
+        self.SortListItems(1, False)
+        self.do_greyline()
+#-----------------------------------------------------------------------------------------    
+
+    def PopulateList(self, dlist):
+        
+        #self.list.InsertColumn(0,'id', wx.LIST_FORMAT_LEFT)
+#        i=1
+        self.list.InsertColumn(0, 'forme', wx.LIST_FORMAT_RIGHT)
+        self.list.InsertColumn(1, 'nb', wx.LIST_FORMAT_RIGHT)
+        self.list.InsertColumn(2, 'type', wx.LIST_FORMAT_RIGHT)
+        self.list.InsertColumn(3, '', wx.LIST_FORMAT_RIGHT)
+
+        ct = 0
+        for key, data in dlist.iteritems():
+            ct += 1
+            index = self.list.InsertStringItem(sys.maxint, data[0])
+            self.list.SetStringItem(index, 1, `data[1]`)
+            self.list.SetStringItem(index, 2, data[2])
+            self.list.SetStringItem(index, 3, '')
+            self.list.SetItemData(index, key)
+        
+        self.list.SetColumnWidth(0, 150)   
+        self.list.SetColumnWidth(1, 100)  
+        self.list.SetColumnWidth(2, 100)
+        self.list.SetColumnWidth(3, wx.LIST_AUTOSIZE)
+
+
+        self.currentItem = 0
+
+    def do_greyline(self):
+        for row in xrange(self.list.GetItemCount()):
+            if row % 2 :
+                self.list.SetItemBackgroundColour(row, (230, 230, 230))
+            else :
+                self.list.SetItemBackgroundColour(row, wx.WHITE)
+                
+    def OnColClick(self, event):
+        self.do_greyline()
+        
+    # Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py
+    def GetListCtrl(self):
+        return self.list
+
+    # Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py
+    def GetSortImages(self):
+        return (self.sm_dn, self.sm_up)
+
+
+    def OnRightDown(self, event):
+        x = event.GetX()
+        y = event.GetY()
+        item, flags = self.list.HitTest((x, y))
+
+        if flags & wx.LIST_HITTEST_ONITEM:
+            self.list.Select(item)
+
+        event.Skip()
+
+
+    def getColumnText(self, index, col):
+        item = self.list.GetItem(index, col)
+        return item.GetText()
+
+
+    def OnItemSelected(self, event):
+        self.currentItem = event.m_itemIndex
+        event.Skip()
+
+    def onsearch(self, evt) :
+        self.dial = SearchDial(self, self, 0, True)
+        self.dial.CenterOnParent()
+        self.dial.ShowModal()
+        self.dial.Destroy()
+
+    def OnRightClick(self, event):
+
+        # only do this part the first time so the events are only bound once
+        if not hasattr(self, "popupID1"):
+            self.popupID1 = wx.NewId()
+            self.popupID2 = wx.NewId()
+ #           self.popupID3 = wx.NewId()
+
+            self.Bind(wx.EVT_MENU, self.OnPopupOne, id=self.popupID1)
+            self.Bind(wx.EVT_MENU, self.OnPopupTwo, id=self.popupID2)
+#            self.Bind(wx.EVT_MENU, self.OnPopupThree, id=self.popupID3)
+
+        # make a menu
+        menu = wx.Menu()
+        # add some items
+        menu.Append(self.popupID1, u"Formes associées")
+        menu.Append(self.popupID2, u"Concordancier")
+#        menu.Append(self.popupID3, "recharger")
+
+        self.PopupMenu(menu)
+        menu.Destroy()
+
+
+    def OnPopupOne(self, event):
+        corpus = self.gparent.corpus
+        word = self.getColumnText(self.list.GetFirstSelected(), 0)
+        lems = corpus.getlems()
+        rep = []
+        for forme in lems[word].formes :
+             rep.append([corpus.getforme(forme).forme, corpus.getforme(forme).freq])
+        win = message(self, -1, u"Formes associées", size=(300, 200), style=wx.DEFAULT_FRAME_STYLE)
+        win.html = '<html>\n' + '<br>'.join([' : '.join([str(val) for val in forme]) for forme in rep]) + '\n</html>'
+        win.HtmlPage.SetPage(win.html)
+        win.Show(True)
+
+    def OnPopupTwo(self, event):
+        corpus = self.gparent.corpus
+        win = message(self, -1, u"Concordancier", size=(600, 200), style=wx.DEFAULT_FRAME_STYLE)
+        avap = 60
+        item = self.getColumnText(self.list.GetFirstSelected(), 0)
+        listmot = corpus.getlems()[item].formes
+        #uce_ok = [corpus.formes[corpus.idformes[forme].forme][1] for forme in listmot]
+        uce_ok = corpus.getlemuces(item)#list(set([tuple(val) for line in uce_ok for val in line]))
+        txt = '<h1>Concordancier</h1>'
+        res = corpus.getconcorde(uce_ok)
+        for uce in res :
+            ucetxt = ' '+uce[1]+' '
+            txt += ' '.join(corpus.ucis[corpus.getucefromid(uce[0]).uci].etoiles) + '<br>'
+            for forme in listmot :
+                forme = corpus.getforme(forme).forme
+                ucetxt = ucetxt.replace(' '+forme+' ', '<font color=red> ' + forme + ' </font>')
+            txt += ucetxt + '<br><br>'
+#        for uce in uce_ok:
+#            content = ' '+' '.join(corpus.ucis_paras_uces[uce[0]][uce[1]][uce[2]])+' '
+#            for form in listmot :
+#                sp = ''
+#                i = 0
+#                forme = ' ' + form + ' '
+#                while i < len(content):
+#                    coordword = content[i:].find(forme)
+#                    if coordword != -1 and i == 0:
+#                        txt += '<br><b>' + ' '.join(corpus.ucis[uce[0]][0]) + '</b><br>'
+#                        if coordword < avap:
+#                            sp = '&nbsp;' * (avap - coordword)
+#                            deb = i
+#                        else:
+#                            deb = i + coordword - avap
+#                        if len(content) < i + coordword + avap:
+#                            fin = len(content) - 1
+#                        else:
+#                            fin = i + coordword + avap
+#                        txt += '<TT>' + sp + content[deb:fin].replace(forme, '<font color=red>' + forme + '</font>') + '</TT><br>'
+#                        i += coordword + len(forme)
+#                        sp = ''
+#                    elif coordword != -1 and i != 0 :
+#                        if coordword < avap:
+#                            sp = '&nbsp;' * (avap - coordword)
+#                            deb = i
+#                        else:
+#                            deb = i + coordword - avap
+#                        if len(content) < i + coordword + avap:
+#                            fin = len(content) - 1
+#                        else:
+#                            fin = i + coordword + avap
+#                        txt += '<TT>' + sp + content[deb:fin].replace(forme, '<font color=red>' + forme + '</font>') + '</TT><br>'
+#                        i += coordword + len(forme)
+#                        sp = ''                   
+#                    else:
+#                        i = len(content)
+#                        sp = ''
+        win.HtmlPage.SetPage(txt) 
+        win.Show(True)
+        
+    def OnSize(self, event):
+        w, h = self.GetClientSizeTuple()
+        self.list.SetDimensions(0, 0, w, h)
+
+class message(wx.Frame):
+    def __init__(self, *args, **kwds):
+        # begin wxGlade: MyFrame.__init__
+        kwds["style"] = wx.DEFAULT_FRAME_STYLE
+        wx.Frame.__init__(self, *args, **kwds)
+        #self.text_ctrl_1 = wx.TextCtrl(self, -1, "", style=wx.TE_MULTILINE)
+        self.HtmlPage = wx.html.HtmlWindow(self, -1)
+        if "gtk2" in wx.PlatformInfo:
+            self.HtmlPage.SetStandardFonts()
+        self.HtmlPage.SetFonts('Courier', 'Courier')
+        
+        
+        self.button_1 = wx.Button(self, -1, "Fermer")
+        self.Bind(wx.EVT_BUTTON, self.OnCloseMe, self.button_1)
+        self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
+        self.__do_layout()
+        # end wxGlade
+
+    def __do_layout(self):
+        # begin wxGlade: MyFrame.__do_layout
+        sizer_1 = wx.BoxSizer(wx.VERTICAL)
+        sizer_2 = wx.BoxSizer(wx.VERTICAL)
+        sizer_2.Add(self.HtmlPage, 1, wx.EXPAND | wx.ADJUST_MINSIZE, 0)
+        sizer_2.Add(self.button_1, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ADJUST_MINSIZE, 0)
+        sizer_1.Add(sizer_2, 1, wx.EXPAND, 0)
+        self.SetAutoLayout(True)
+        self.SetSizer(sizer_1)
+        self.Layout()
+        # end wxGlade
+        
+    def OnCloseMe(self, event):
+        self.Close(True)
+
+    def OnCloseWindow(self, event):
+        self.Destroy()
+
+
+def getSmallUpArrowData():
+    return \
+'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
+\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
+\x00\x00<IDAT8\x8dcddbf\xa0\x040Q\xa4{h\x18\xf0\xff\xdf\xdf\xffd\x1b\x00\xd3\
+\x8c\xcf\x10\x9c\x06\xa0k\xc2e\x08m\xc2\x00\x97m\xd8\xc41\x0c \x14h\xe8\xf2\
+\x8c\xa3)q\x10\x18\x00\x00R\xd8#\xec\xb2\xcd\xc1Y\x00\x00\x00\x00IEND\xaeB`\
+\x82' 
+
+def getSmallUpArrowBitmap():
+    return wx.BitmapFromImage(getSmallUpArrowImage())
+
+def getSmallUpArrowImage():
+    stream = cStringIO.StringIO(getSmallUpArrowData())
+    return wx.ImageFromStream(stream)
+
+#----------------------------------------------------------------------
+def getSmallDnArrowData():
+    return \
+"\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
+\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
+\x00\x00HIDAT8\x8dcddbf\xa0\x040Q\xa4{\xd4\x00\x06\x06\x06\x06\x06\x16t\x81\
+\xff\xff\xfe\xfe'\xa4\x89\x91\x89\x99\x11\xa7\x0b\x90%\ti\xc6j\x00>C\xb0\x89\
+\xd3.\x10\xd1m\xc3\xe5*\xbc.\x80i\xc2\x17.\x8c\xa3y\x81\x01\x00\xa1\x0e\x04e\
+?\x84B\xef\x00\x00\x00\x00IEND\xaeB`\x82" 
+
+def getSmallDnArrowBitmap():
+    return wx.BitmapFromImage(getSmallDnArrowImage())
+
+def getSmallDnArrowImage():
+    stream = cStringIO.StringIO(getSmallDnArrowData())
+    return wx.ImageFromStream(stream)
diff --git a/OptionAlceste.py b/OptionAlceste.py
new file mode 100755 (executable)
index 0000000..ea3ba80
--- /dev/null
@@ -0,0 +1,306 @@
+# -*- coding: utf-8 -*-
+#Author: Pierre Ratinaud
+#Copyright (c) 2008-2009 Pierre Ratinaud
+#Lisense: GNU/GPL
+
+import wx
+import shutil
+from KeyFrame import AlcOptFrame
+from chemins import ConstructConfigPath
+from functions import DoConf
+
+
+
+class OptionAlc(wx.Dialog):
+    def __init__(self, parent, parametres, *args, **kwds):
+        kwds['style'] = wx.DEFAULT_DIALOG_STYLE
+        wx.Dialog.__init__(self, parent, *args, **kwds)
+        self.parent = parent
+        self.parametres = parametres
+        self.DictPath = parametres['pathout']
+        self.AlcesteConf = parametres
+        self.choose = False
+        
+        self.label_1 = wx.StaticText(self, -1, u"Lemmatisation")
+        self.radio_1 = wx.RadioBox(self, -1, u"", choices=['oui', 'non'], majorDimension=0, style=wx.RA_SPECIFY_ROWS)
+
+        self.label_12 = wx.StaticText(self, -1, u"Classification")
+        self.radio_box_2 = wx.RadioBox(self, -1, u"", choices=[u"double sur UC", u"simple sur UCE", u"simple sur UCI"], majorDimension=0, style=wx.RA_SPECIFY_ROWS) #, u"simple sur UCE (non implemente)"
+        self.label_2 = wx.StaticText(self, -1, u"taille uc 1")
+        self.spin_ctrl_1 = wx.SpinCtrl(self, -1, "formes actives",size = (100,30), min=0, max=100)
+        self.label_3 = wx.StaticText(self, -1, u"taille uc 2")
+        self.spin_ctrl_2 = wx.SpinCtrl(self, -1, "",size = (100,30), min=0, max=100)
+        self.lab_nbcl = wx.StaticText(self, -1, u"nombre de classes terminales de la phase 1")
+        self.spin_nbcl = wx.SpinCtrl(self, -1, "",size = (100,30), min=2, max=100)
+        txt = """Nombre minimum d'uce par classe
+(0 = automatique)"""
+        self.label_7 = wx.StaticText(self, -1, txt)
+        self.spin_ctrl_4 = wx.SpinCtrl(self, -1, "",size = (100,30), min=0, max=1000)       
+        txt = u"""Fréquence minimum d'une forme
+analysée (2 = automatique)"""
+        self.label_8 = wx.StaticText(self, -1, txt)
+        self.spin_ctrl_5 = wx.SpinCtrl(self, -1, "",size = (100,30), min=2, max=1000)
+        self.label_max_actives =  wx.StaticText(self, -1, u"Nombre maximum de formes analysées")
+        self.spin_max_actives = wx.SpinCtrl(self, -1, "",size = (100,30), min=20, max=10000)
+        self.label_4 = wx.StaticText(self, -1, u"Configuration \ndes clés d'analyse")
+        self.button_5 = wx.Button(self, wx.ID_PREFERENCES, "")
+        self.button_1 = wx.Button(self, wx.ID_CANCEL, "")
+        self.button_2 = wx.Button(self, wx.ID_DEFAULT, u"Valeurs par défaut")
+        self.button_4 = wx.Button(self, wx.ID_OK, "")
+        self.static_line_1 = wx.StaticLine(self, -1)
+
+        self.__set_properties()
+        self.__do_layout()
+
+        self.Bind(wx.EVT_BUTTON, self.OnKeyPref, self.button_5)
+        self.Bind(wx.EVT_BUTTON, self.OnDef, self.button_2)
+        
+    def __set_properties(self):
+        self.SetTitle("Options")
+        #lang = self.AlcesteConf.get('ALCESTE', 'lang')
+        #self.choice_dict.SetSelection(self.langues.index(lang))
+        DefaultLem = self.parametres['lem']
+        if DefaultLem :
+            self.radio_1.SetSelection(0)
+        else:
+            self.radio_1.SetSelection(1)
+        self.radio_box_2.SetSelection(int(self.parametres['classif_mode']))
+        self.spin_ctrl_1.SetValue(int(self.parametres['tailleuc1']))
+        self.spin_ctrl_2.SetValue(int(self.parametres['tailleuc2']))
+        self.spin_ctrl_4.SetValue(int(self.parametres['mincl']))
+        self.spin_ctrl_5.SetValue(int(self.parametres['minforme']))
+        self.spin_ctrl_5.Disable()
+        self.spin_max_actives.SetValue(int(self.parametres['max_actives']))
+        self.spin_nbcl.SetValue(int(self.parametres['nbcl_p1']))
+
+    def __do_layout(self):
+        sizer_1 = wx.BoxSizer(wx.VERTICAL)
+        sizer_2 = wx.BoxSizer(wx.VERTICAL)
+        grid_sizer2 = wx.FlexGridSizer(15, 2, 0, 0)
+        grid_button = wx.FlexGridSizer(1, 3, 0, 0)
+        
+        #grid_sizer2.Add(self.label_dict, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
+        #grid_sizer2.Add(self.choice_dict, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
+
+        grid_sizer2.Add(self.label_1, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
+        grid_sizer2.Add(self.radio_1, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
+        grid_sizer2.Add(wx.StaticLine(self), 0, wx.EXPAND | wx.ALL, 1)
+        grid_sizer2.Add(wx.StaticLine(self, -1), 0, wx.EXPAND | wx.ALL, 1)
+
+        grid_sizer2.Add(self.label_12, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
+        grid_sizer2.Add(self.radio_box_2, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
+        grid_sizer2.Add(wx.StaticLine(self), 0, wx.EXPAND | wx.ALL, 1)
+        grid_sizer2.Add(wx.StaticLine(self, -1), 0, wx.EXPAND | wx.ALL, 1)
+
+        grid_sizer2.Add(self.label_2, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
+        grid_sizer2.Add(self.spin_ctrl_1, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
+        grid_sizer2.Add(wx.StaticLine(self), 0, wx.EXPAND | wx.ALL, 1)
+        grid_sizer2.Add(wx.StaticLine(self, -1), 0, wx.EXPAND | wx.ALL, 1)
+
+        grid_sizer2.Add(self.label_3, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
+        grid_sizer2.Add(self.spin_ctrl_2, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
+        grid_sizer2.Add(wx.StaticLine(self), 0, wx.EXPAND | wx.ALL, 1)
+        grid_sizer2.Add(wx.StaticLine(self, -1), 0, wx.EXPAND | wx.ALL, 1)
+
+        grid_sizer2.Add(self.lab_nbcl, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
+        grid_sizer2.Add(self.spin_nbcl, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
+        grid_sizer2.Add(wx.StaticLine(self), 0, wx.EXPAND | wx.ALL, 1)
+        grid_sizer2.Add(wx.StaticLine(self, -1), 0, wx.EXPAND | wx.ALL, 1)
+
+        grid_sizer2.Add(self.label_7, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
+        grid_sizer2.Add(self.spin_ctrl_4, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
+        grid_sizer2.Add(wx.StaticLine(self), 0, wx.EXPAND | wx.ALL, 1)
+        grid_sizer2.Add(wx.StaticLine(self, -1), 0, wx.EXPAND | wx.ALL, 1)
+
+        grid_sizer2.Add(self.label_8, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
+        grid_sizer2.Add(self.spin_ctrl_5, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
+        grid_sizer2.Add(wx.StaticLine(self), 0, wx.EXPAND | wx.ALL, 1)
+        grid_sizer2.Add(wx.StaticLine(self, -1), 0, wx.EXPAND | wx.ALL, 1)
+
+        grid_sizer2.Add(self.label_max_actives, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
+        grid_sizer2.Add(self.spin_max_actives, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
+        grid_sizer2.Add(wx.StaticLine(self), 0, wx.EXPAND | wx.ALL, 1)
+        grid_sizer2.Add(wx.StaticLine(self, -1), 0, wx.EXPAND | wx.ALL, 1)
+       
+        grid_sizer2.Add(self.label_4, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
+        grid_sizer2.Add(self.button_5, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
+        grid_sizer2.Add(wx.StaticLine(self), 0, wx.EXPAND | wx.ALL, 1)
+        grid_sizer2.Add(wx.StaticLine(self, -1), 0, wx.EXPAND | wx.ALL, 1)
+        
+        grid_button.Add(self.button_1, 0, wx.ALIGN_CENTER_HORIZONTAL, 0)
+        grid_button.Add(self.button_2, 0, wx.ALIGN_CENTER_HORIZONTAL, 0)
+        grid_button.Add(self.button_4, 0, wx.ALIGN_CENTER_HORIZONTAL, 0)
+        sizer_2.Add(grid_sizer2, 3, wx.EXPAND, 0)
+        sizer_2.Add(grid_button, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
+        sizer_1.Add(sizer_2, 0, wx.EXPAND, 0)
+        self.SetSizer(sizer_1)
+        sizer_1.Fit(self)
+        self.Layout()
+
+    def OnKeyPref(self, event): 
+        self.choose = True
+        dial = AlcOptFrame(self.parent, self)
+        dial.CenterOnParent()
+        val = dial.ShowModal()
+    
+    def OnDef(self, event):
+        ConfOri = ConstructConfigPath(self.parent.AppliPath, user=False)
+        ConfUser = ConstructConfigPath(self.parent.UserConfigPath)
+        shutil.copyfile(ConfOri['alceste'], ConfUser['alceste'])
+        corpus = self.parametres['corpus']
+        pathout = self.parametres['pathout']
+        self.parametres = DoConf(self.parent.ConfigPath['alceste']).getoptions('ALCESTE')
+        self.parametres['corpus'] = corpus
+        self.parametres['pathout'] = pathout
+        self.__set_properties()
+        
+###################################################################################@
+
+class OptionPam(wx.Dialog):
+    def __init__(self, parent, *args, **kwds):
+        kwds['style'] = wx.DEFAULT_DIALOG_STYLE
+        wx.Dialog.__init__(self, *args, **kwds)
+        self.parent = parent
+        self.DictPath = parent.DictPath
+        self.pamconf = parent.pamconf
+        self.type = parent.type
+        self.choose = False
+        
+        self.label_1 = wx.StaticText(self, -1, u"Lemmatisation")
+        self.radio_1 = wx.RadioBox(self, -1, u"", choices=['oui', 'non'], majorDimension=0, style=wx.RA_SPECIFY_ROWS)
+        self.label_exp = wx.StaticText(self, -1, u"Utiliser le dict. des expressions")
+        self.radio_exp =  wx.RadioBox(self, -1, u"", choices=['oui', 'non'], majorDimension=0, style=wx.RA_SPECIFY_ROWS)
+        txt = u"""Methode de construction
+de la matrice des distances"""
+        self.label_12 = wx.StaticText(self, -1, txt)
+        self.distance = [u"binary", u"euclidean", u"maximum", u'manhattan', u'canberra', u'minkowski']
+        self.choice_1 =  wx.Choice(self, -1, (100,50), choices=self.distance)
+        self.label_13 = wx.StaticText(self, -1, u'Analyse')
+        self.cltype = [u'k-means (pam)', u'fuzzy (fanny)']
+        self.radio_box_3 = wx.RadioBox(self, -1, u"", choices=self.cltype, majorDimension=0, style=wx.RA_SPECIFY_ROWS)
+        self.label_classif = wx.StaticText(self, -1, u"Classification")
+        self.radio_box_classif = wx.RadioBox(self, -1, u"", choices=[u"sur UCE", u"sur UCI"], majorDimension=0, style=wx.RA_SPECIFY_ROWS) 
+        #self.label_2 = wx.StaticText(self, -1, "taille uc")
+        #self.spin_ctrl_1 = wx.SpinCtrl(self, -1, "formes actives", min=0, max=100)
+        self.label_max_actives =  wx.StaticText(self, -1, u"Nombre maximum de formes analysées")
+        self.spin_max_actives = wx.SpinCtrl(self, -1, "",size = (100,30), min=20, max=10000)
+        txt = """Nombre de formes par uce
+(0 = automatique)"""
+        self.label_6 = wx.StaticText(self, -1, txt)
+        self.spin_ctrl_3 = wx.SpinCtrl(self, -1, "", size = (100,30), min=0, max=100000)
+        txt = "Nombre de classes"
+        self.label_7 = wx.StaticText(self, -1, txt)
+        self.spin_ctrl_4 = wx.SpinCtrl(self, -1, "", size = (100,30), min=0, max=1000)        
+        self.label_4 = wx.StaticText(self, -1, u"Configuration \ndes clés d'analyse")
+        self.button_5 = wx.Button(self, wx.ID_PREFERENCES, "")
+        self.button_1 = wx.Button(self, wx.ID_CANCEL, "")
+        self.button_2 = wx.Button(self, wx.ID_DEFAULT, u"Valeurs par défaut")
+        self.button_4 = wx.Button(self, wx.ID_OK, "")
+        self.static_line_1 = wx.StaticLine(self, -1)
+
+        self.__set_properties()
+        self.__do_layout()
+
+        self.Bind(wx.EVT_BUTTON, self.OnKeyPref, self.button_5)
+        self.Bind(wx.EVT_BUTTON, self.OnDef, self.button_2)
+
+    def __set_properties(self):
+        self.SetTitle("Options")
+        DefaultLem = self.pamconf.getboolean('pam', 'lem')
+        if DefaultLem :
+            self.radio_1.SetSelection(0)
+        else:
+            self.radio_1.SetSelection(1)
+        expressions = self.pamconf.getboolean('pam', 'expressions')
+        if expressions :
+            self.radio_exp.SetSelection(0)
+        else :
+            self.radio_exp.SetSelection(1)
+        self.choice_1.SetSelection(self.distance.index(self.pamconf.get('pam', 'method')))
+        if self.pamconf.get('pam', 'cluster_type') == u'pam' :
+            self.radio_box_3.SetSelection(0)
+        else :
+            self.radio_box_3.SetSelection(1)
+        self.radio_box_classif.SetSelection(int(self.pamconf.get('pam','type')))
+        self.spin_max_actives.SetValue(int(self.pamconf.get('pam','max_actives')))
+        self.spin_ctrl_3.SetValue(int(self.pamconf.get('pam', 'nbforme_uce')))
+        cle = 'nbcl'
+        self.spin_ctrl_4.SetValue(int(self.pamconf.get('pam', cle)))
+
+    def __do_layout(self):
+        sizer_1 = wx.BoxSizer(wx.VERTICAL)
+        sizer_2 = wx.BoxSizer(wx.VERTICAL)
+        grid_sizer2 = wx.FlexGridSizer(11, 2, 2, 2)
+        grid_button = wx.FlexGridSizer(1, 3, 1, 1)
+        grid_sizer2.Add(self.label_1, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
+        grid_sizer2.Add(self.radio_1, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
+        grid_sizer2.Add(wx.StaticLine(self), 0, wx.EXPAND | wx.ALL, 1)
+        grid_sizer2.Add(wx.StaticLine(self, -1), 0, wx.EXPAND | wx.ALL, 1)
+       
+        grid_sizer2.Add(self.label_exp, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
+        grid_sizer2.Add(self.radio_exp, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
+        grid_sizer2.Add(wx.StaticLine(self), 0, wx.EXPAND | wx.ALL, 1)
+        grid_sizer2.Add(wx.StaticLine(self, -1), 0, wx.EXPAND | wx.ALL, 1)
+
+        grid_sizer2.Add(self.label_12, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
+        grid_sizer2.Add(self.choice_1, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
+        grid_sizer2.Add(wx.StaticLine(self), 0, wx.EXPAND | wx.ALL, 1)
+        grid_sizer2.Add(wx.StaticLine(self, -1), 0, wx.EXPAND | wx.ALL, 1)
+
+        grid_sizer2.Add(self.label_13, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
+        grid_sizer2.Add(self.radio_box_3, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
+        grid_sizer2.Add(wx.StaticLine(self), 0, wx.EXPAND | wx.ALL, 1)
+        grid_sizer2.Add(wx.StaticLine(self, -1), 0, wx.EXPAND | wx.ALL, 1)
+
+        grid_sizer2.Add(self.label_classif, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
+        grid_sizer2.Add(self.radio_box_classif, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
+        grid_sizer2.Add(wx.StaticLine(self), 0, wx.EXPAND | wx.ALL, 1)
+        grid_sizer2.Add(wx.StaticLine(self, -1), 0, wx.EXPAND | wx.ALL, 1)
+        
+        #grid_sizer2.Add(self.label_2, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
+        #grid_sizer2.Add(self.spin_ctrl_1, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
+        #grid_sizer2.Add(wx.StaticLine(self), 0, wx.EXPAND | wx.ALL, 1)
+        #grid_sizer2.Add(wx.StaticLine(self, -1), 0, wx.EXPAND | wx.ALL, 1)
+        
+        grid_sizer2.Add(self.label_max_actives, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
+        grid_sizer2.Add(self.spin_max_actives, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0) 
+        grid_sizer2.Add(wx.StaticLine(self), 0, wx.EXPAND | wx.ALL, 1)
+        grid_sizer2.Add(wx.StaticLine(self, -1), 0, wx.EXPAND | wx.ALL, 1)
+
+        grid_sizer2.Add(self.label_6, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
+        grid_sizer2.Add(self.spin_ctrl_3, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0) 
+        grid_sizer2.Add(wx.StaticLine(self), 0, wx.EXPAND | wx.ALL, 1)
+        grid_sizer2.Add(wx.StaticLine(self, -1), 0, wx.EXPAND | wx.ALL, 1)
+        
+        grid_sizer2.Add(self.label_7, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
+        grid_sizer2.Add(self.spin_ctrl_4, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
+        grid_sizer2.Add(wx.StaticLine(self), 0, wx.EXPAND | wx.ALL, 1)
+        grid_sizer2.Add(wx.StaticLine(self, -1), 0, wx.EXPAND | wx.ALL, 1)
+        
+        grid_sizer2.Add(self.label_4, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
+        grid_sizer2.Add(self.button_5, 0, wx.ALIGN_LEFT | wx.ALIGN_CENTER_VERTICAL, 0)
+        grid_sizer2.Add(wx.StaticLine(self), 0, wx.EXPAND | wx.ALL, 1)
+        grid_sizer2.Add(wx.StaticLine(self, -1), 0, wx.EXPAND | wx.ALL, 1)
+        
+        grid_button.Add(self.button_1, 0, wx.ALIGN_CENTER_HORIZONTAL, 0)
+        grid_button.Add(self.button_2, 0, wx.ALIGN_CENTER_HORIZONTAL, 0)
+        grid_button.Add(self.button_4, 0, wx.ALIGN_CENTER_HORIZONTAL, 0)
+        sizer_2.Add(grid_sizer2, 3, wx.EXPAND, 0)
+        sizer_2.Add(grid_button, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALIGN_CENTER_VERTICAL, 0)
+        sizer_1.Add(sizer_2, 0, wx.EXPAND, 0)
+        self.SetSizer(sizer_1)
+        sizer_1.Fit(self)
+        self.Layout()
+
+    def OnKeyPref(self, event):
+        self.choose = True
+        dial = AlcOptFrame(self.parent, self)
+        dial.CenterOnParent()
+        val = dial.ShowModal()
+    
+    def OnDef(self, event):
+        ConfOri = ConstructConfigPath(self.parent.parent.AppliPath, user=False)
+        ConfUser = ConstructConfigPath(self.parent.parent.UserConfigPath)
+        shutil.copyfile(ConfOri['pam'], ConfUser['pam'])
+        self.parent.pamconf.read(self.parent.ConfigPath['pam'])
+        self.__set_properties()
diff --git a/PrintRScript.py b/PrintRScript.py
new file mode 100644 (file)
index 0000000..4d0fb40
--- /dev/null
@@ -0,0 +1,622 @@
+# -*- coding: utf-8 -*-
+#Author: Pierre Ratinaud
+#Copyright (c) 2008-2011 Pierre Ratinaud
+#Lisense: GNU/GPL
+
+import tempfile
+from chemins import ffr
+import os
+import locale
+from datetime import datetime
+import logging
+
+log = logging.getLogger('iramuteq.printRscript')
+
+class PrintRScript :
+    def __init__ (self, analyse):
+        log.info('Rscript')
+        self.pathout = analyse.pathout
+        self.analyse = analyse
+        self.scriptout = self.pathout['temp']
+        self.script =  u"#Script genere par IRaMuTeQ - %s" % datetime.now().ctime()
+    
+    def add(self, txt) :
+        self.script = '\n'.join([self.script, txt])
+    
+    def defvar(self, name, value) :
+        self.add(' <- '.join([name, value]))
+
+    def defvars(self, lvars) :
+        for val in lvars :
+            self.defvar(val[0],val[1])
+
+    def sources(self, lsources) :
+        for source in lsources :
+            self.add('source("%s")' % source)
+
+    def load(self, l) :
+        for val in l :
+            self.add('load("%s")' % val)
+
+    def write(self) :
+        with open(self.scriptout, 'w') as f :
+            f.write(self.script)
+
+
+class chdtxt(PrintRScript) :
+    pass
+
+
+class Alceste2(PrintRScript) :
+    def doscript(self) :
+        self.sources(['chdfunct'])
+        self.load(['Rdata'])
+        lvars = [['clnb', `self.analyse.clnb`], 
+                ['Contout', '"%s"' % self.pathout['Contout']],
+                ['ContSupOut', '"%s"' % self.pathout['ContSupOut']],
+                ['ContEtOut', '"%s"' % self.pathout['ContEtOut']],
+                ['profileout', '"%s"' % self.pathout['profils.csv']],
+                ['antiout', '"%s"' % self.pathout['antiprofils.csv']],
+                ['chisqtable', '"%s"' % self.pathout['chisqtable.csv']],
+                ['ptable', '"%s"' % self.pathout['ptable.csv']]]
+       
+        self.defvars(lvars) 
+
+
+
+#    txt = "clnb<-%i\n" % clnb
+#    txt += """
+#source("%s")
+#load("%s")
+#""" % (RscriptsPath['chdfunct'], DictChdTxtOut['RData'])
+#    txt += """
+#dataact<-read.csv2("%s", header = FALSE, sep = ';',quote = '\"', row.names = 1, na.strings = 'NA')
+#datasup<-read.csv2("%s", header = FALSE, sep = ';',quote = '\"', row.names = 1, na.strings = 'NA')
+#dataet<-read.csv2("%s", header = FALSE, sep = ';',quote = '\"', row.names = 1, na.strings = 'NA')
+#""" % (DictChdTxtOut['Contout'], DictChdTxtOut['ContSupOut'], DictChdTxtOut['ContEtOut'])
+#    txt += """
+#tablesqrpact<-BuildProf(as.matrix(dataact),n1,clnb)
+#tablesqrpsup<-BuildProf(as.matrix(datasup),n1,clnb)
+#tablesqrpet<-BuildProf(as.matrix(dataet),n1,clnb)
+#"""
+#    txt += """
+#PrintProfile(n1,tablesqrpact[4],tablesqrpet[4],tablesqrpact[5],tablesqrpet[5],clnb,"%s","%s",tablesqrpsup[4],tablesqrpsup[5])
+#""" % (DictChdTxtOut['PROFILE_OUT'], DictChdTxtOut['ANTIPRO_OUT'])
+#    txt += """
+#colnames(tablesqrpact[[2]])<-paste('classe',1:clnb,sep=' ')
+#colnames(tablesqrpact[[1]])<-paste('classe',1:clnb,sep=' ')
+#colnames(tablesqrpsup[[2]])<-paste('classe',1:clnb,sep=' ')
+#colnames(tablesqrpsup[[1]])<-paste('classe',1:clnb,sep=' ')
+#colnames(tablesqrpet[[2]])<-paste('classe',1:clnb,sep=' ')
+#colnames(tablesqrpet[[1]])<-paste('classe',1:clnb,sep=' ')
+#chistabletot<-rbind(tablesqrpact[2][[1]],tablesqrpsup[2][[1]])
+#chistabletot<-rbind(chistabletot,tablesqrpet[2][[1]])
+#ptabletot<-rbind(tablesqrpact[1][[1]],tablesqrpet[1][[1]])
+#"""
+#    txt += """
+#write.csv2(chistabletot,file="%s")
+#write.csv2(ptabletot,file="%s")
+#gbcluster<-n1
+#write.csv2(gbcluster,file="%s")
+#""" % (DictChdTxtOut['chisqtable'], DictChdTxtOut['ptable'], DictChdTxtOut['SbyClasseOut'])
+#
+
+
+def RchdTxt(DicoPath, RscriptPath, mincl, classif_mode, nbt = 9, libsvdc = False, libsvdc_path = None, R_max_mem = False):
+    txt = """
+    source("%s")
+    source("%s")
+    source("%s")
+    source("%s")
+    """ % (RscriptPath['CHD'], RscriptPath['chdtxt'], RscriptPath['anacor'], RscriptPath['Rgraph'])
+    if R_max_mem :
+        txt += """
+    memory.limit(%i)
+        """ % R_max_mem
+
+    txt += """
+    nbt <- %i
+    """ % nbt
+    if libsvdc :
+        txt += """
+        libsvdc <- TRUE
+        libsvdc.path <- "%s"
+        """ % ffr(libsvdc_path)
+    else :
+        txt += """
+        libsvdc <- FALSE
+        libsvdc.path <- NULL
+        """
+
+    txt +="""
+    library(Matrix)
+    data1 <- readMM("%s")
+    data1 <- as(data1, "dgCMatrix")
+    row.names(data1) <- 1:nrow(data1)
+    """ % DicoPath['TableUc1']
+    
+    if classif_mode == 0:
+        txt += """
+        data2 <- readMM("%s")
+        data2 <- as(data2, "dgCMatrix")
+        row.names(data2) <- 1:nrow(data2)
+        """ % DicoPath['TableUc2']
+    txt += """
+    chd1<-CHD(data1, x = nbt, libsvdc = libsvdc, libsvdc.path = libsvdc.path)
+    """
+    
+    if classif_mode == 0:
+        txt += """
+    chd2<-CHD(data2, x = nbt, libsvdc = libsvdc, libsvdc.path = libsvdc.path)
+    """
+    else:
+        txt += """
+    chd2<-chd1
+    """    
+    
+    txt += """
+    #lecture des uce
+    listuce1<-read.csv2("%s")
+    """ % DicoPath['listeuce1']
+    
+    if classif_mode == 0:
+        txt += """
+        listuce2<-read.csv2("%s")
+        """ % DicoPath['listeuce2']
+        
+    txt += """
+#    rm(data1)
+    """
+    
+    if classif_mode == 0:
+        txt += """
+#        rm(data2)
+        """
+    txt += """
+    chd.result <- Rchdtxt("%s",mincl=%i,classif_mode=%i, nbt = nbt)
+    n1 <- chd.result$n1
+    classeuce1 <- chd.result$cuce1
+    classeuce2 <- chd.result$cuce2
+    """ % (DicoPath['uce'], mincl, classif_mode)
+    
+    txt += """
+    tree.tot1 <- make_tree_tot(chd1)
+#    open_file_graph("%s", widt = 600, height=400)
+#    plot(tree.tot1$tree.cl)
+#    dev.off()
+    """%DicoPath['arbre1']
+    
+    if classif_mode == 0:
+        txt += """
+        tree.tot2 <- make_tree_tot(chd2)
+#        open_file_graph("%s", width = 600, height=400)
+#        plot(tree.tot2$tree.cl)
+#        dev.off()
+        """ % DicoPath['arbre2']  
+              
+    txt += """
+    tree.cut1 <- make_dendro_cut_tuple(tree.tot1$dendro_tuple, chd.result$coord_ok, classeuce1, 1, nbt)
+    save(tree.cut1, file="%s")
+    classes<-n1[,ncol(n1)]
+    open_file_graph("%s", width = 600, height=400)
+    plot.dendropr(tree.cut1$tree.cl,classes)
+    open_file_graph("%s", width = 600, height=400)
+    plot(tree.cut1$dendro_tot_cl)
+    dev.off()
+    """ % (DicoPath['Rdendro'], DicoPath['dendro1'], DicoPath['arbre1'])
+    
+    if classif_mode == 0:
+        txt += """
+        tree.cut2 <- make_dendro_cut_tuple(tree.tot2$dendro_tuple, chd.result$coord_ok, classeuce2, 2, nbt)
+        open_file_graph("%s", width = 600, height=400)
+        plot(tree.cut2$tree.cl)
+        dev.off()
+        open_file_graph("%s", width = 600, height=400)
+        plot(tree.cut1$dendro_tot_cl)
+        dev.off()
+        """ % (DicoPath['dendro2'], DicoPath['arbre2'])
+        
+    txt += """
+    save.image(file="%s")
+    """ % DicoPath['RData']
+    fileout = open(DicoPath['Rchdtxt'], 'w')
+    fileout.write(txt)
+    fileout.close()
+
+def RPamTxt(corpus, RscriptPath):
+    DicoPath = corpus.dictpathout
+    param = corpus.parametre
+    print param
+    txt = """
+    source("%s")
+    """ % (RscriptPath['pamtxt'])
+    txt += """
+    source("%s")
+    """ % (RscriptPath['Rgraph'])
+    txt += """
+    result <- pamtxt("%s", "%s", "%s", method = "%s", clust_type = "%s", clnb = %i)
+    n1 <- result$uce
+    """ % (DicoPath['TableUc1'], DicoPath['listeuce1'], DicoPath['uce'], param['method'], param['cluster_type'], param['nbcl'] )
+    txt += """
+    open_file_graph("%s", width=400, height=400)
+    plot(result$cl)
+    dev.off()
+    """ % (DicoPath['arbre1'])
+    txt += """
+    save.image(file="%s")
+    """ % DicoPath['RData']
+    fileout = open(DicoPath['Rchdtxt'], 'w')
+    fileout.write(txt)
+    fileout.close()
+    
+
+def RchdQuest(DicoPath, RscriptPath, nbcl = 10, mincl = 10):
+    txt = """
+    source("%s")
+    source("%s")
+    source("%s")
+    source("%s")
+    """ % (RscriptPath['CHD'], RscriptPath['chdquest'], RscriptPath['anacor'],RscriptPath['Rgraph'])
+
+    txt += """
+    nbt <- %i - 1
+    mincl <- %i
+    """ % (nbcl, mincl)
+
+    txt += """
+    chd.result<-Rchdquest("%s","%s","%s", nbt = nbt, mincl = mincl)
+    n1 <- chd.result$n1
+    classeuce1 <- chd.result$cuce1
+    """ % (DicoPath['Act01'], DicoPath['listeuce1'], DicoPath['uce'])
+    
+    txt += """
+    tree_tot1 <- make_tree_tot(chd.result$chd)
+    open_file_graph("%s", width = 600, height=400)
+    plot(tree_tot1$tree.cl)
+    dev.off()
+    """%DicoPath['arbre1']
+    
+    txt += """
+    tree_cut1 <- make_dendro_cut_tuple(tree_tot1$dendro_tuple, chd.result$coord_ok, classeuce1, 1, nbt)
+    tree.cut1 <- tree_cut1
+    save(tree.cut1, file="%s")
+    open_file_graph("%s", width = 600, height=400)
+    classes<-n1[,ncol(n1)]
+    plot.dendropr(tree_cut1$tree.cl,classes)
+    """ % (DicoPath['Rdendro'],DicoPath['dendro1'])
+    
+    txt += """
+    save.image(file="%s")
+    """ % DicoPath['RData']
+    fileout = open(DicoPath['Rchdquest'], 'w')
+    fileout.write(txt)
+    fileout.close()
+    
+def AlcesteTxtProf(DictChdTxtOut, RscriptsPath, clnb, taillecar):
+    txt = "clnb<-%i\n" % clnb
+    txt += """
+source("%s")
+load("%s")
+""" % (RscriptsPath['chdfunct'], DictChdTxtOut['RData'])
+    txt += """
+dataact<-read.csv2("%s", header = FALSE, sep = ';',quote = '\"', row.names = 1, na.strings = 'NA')
+datasup<-read.csv2("%s", header = FALSE, sep = ';',quote = '\"', row.names = 1, na.strings = 'NA')
+dataet<-read.csv2("%s", header = FALSE, sep = ';',quote = '\"', row.names = 1, na.strings = 'NA')
+""" % (DictChdTxtOut['Contout'], DictChdTxtOut['ContSupOut'], DictChdTxtOut['ContEtOut'])
+    txt += """
+tablesqrpact<-BuildProf(as.matrix(dataact),n1,clnb)
+tablesqrpsup<-BuildProf(as.matrix(datasup),n1,clnb)
+tablesqrpet<-BuildProf(as.matrix(dataet),n1,clnb)
+"""
+    txt += """
+PrintProfile(n1,tablesqrpact[4],tablesqrpet[4],tablesqrpact[5],tablesqrpet[5],clnb,"%s","%s",tablesqrpsup[4],tablesqrpsup[5])
+""" % (DictChdTxtOut['PROFILE_OUT'], DictChdTxtOut['ANTIPRO_OUT'])
+    txt += """
+colnames(tablesqrpact[[2]])<-paste('classe',1:clnb,sep=' ')
+colnames(tablesqrpact[[1]])<-paste('classe',1:clnb,sep=' ')
+colnames(tablesqrpsup[[2]])<-paste('classe',1:clnb,sep=' ')
+colnames(tablesqrpsup[[1]])<-paste('classe',1:clnb,sep=' ')
+colnames(tablesqrpet[[2]])<-paste('classe',1:clnb,sep=' ')
+colnames(tablesqrpet[[1]])<-paste('classe',1:clnb,sep=' ')
+chistabletot<-rbind(tablesqrpact[2][[1]],tablesqrpsup[2][[1]])
+chistabletot<-rbind(chistabletot,tablesqrpet[2][[1]])
+ptabletot<-rbind(tablesqrpact[1][[1]],tablesqrpet[1][[1]])
+"""
+    txt += """
+write.csv2(chistabletot,file="%s")
+write.csv2(ptabletot,file="%s")
+gbcluster<-n1
+write.csv2(gbcluster,file="%s")
+""" % (DictChdTxtOut['chisqtable'], DictChdTxtOut['ptable'], DictChdTxtOut['SbyClasseOut'])
+    if clnb > 2 :
+        txt += """
+    library(ca)
+    colnames(dataact)<-paste('classe',1:clnb,sep=' ')
+    colnames(datasup)<-paste('classe',1:clnb,sep=' ')
+    colnames(dataet)<-paste('classe',1:clnb,sep=' ')
+    rowtot<-nrow(dataact)+nrow(dataet)+nrow(datasup)
+    afctable<-rbind(as.matrix(dataact),as.matrix(datasup))
+    afctable<-rbind(afctable,as.matrix(dataet))
+    colnames(afctable)<-paste('classe',1:clnb,sep=' ')
+    afc<-ca(afctable,suprow=((nrow(dataact)+1):rowtot),nd=(ncol(afctable)-1))
+    debsup<-nrow(dataact)+1
+    debet<-nrow(dataact)+nrow(datasup)+1
+    fin<-rowtot
+    afc<-AddCorrelationOk(afc)
+    """
+    #FIXME : split this!!!
+        txt += """
+    source("%s")
+    """ % RscriptsPath['Rgraph']
+    
+        txt += """
+        afc <- summary.ca.dm(afc)
+        afc_table <- create_afc_table(afc)
+        write.csv2(afc_table$facteur, file = "%s")
+        write.csv2(afc_table$colonne, file = "%s")
+        write.csv2(afc_table$ligne, file = "%s")
+        """ % (DictChdTxtOut['afc_facteur'], DictChdTxtOut['afc_col'], DictChdTxtOut['afc_row'])
+    
+        txt += """
+        xlab <- paste('facteur 1 - ', round(afc$facteur[1,2],2), sep = '')
+        ylab <- paste('facteur 2 - ', round(afc$facteur[2,2],2), sep = '')
+        xlab <- paste(xlab, ' %', sep = '')
+        ylab <- paste(ylab, ' %', sep = '')
+        """
+    
+        txt += """
+    PARCEX<-%s
+    """ % taillecar
+        txt += """
+    PlotAfc2dCoul(afc, as.data.frame(chistabletot), "%s", what='coord', deb=1, fin=(debsup-1), xlab = xlab, ylab = ylab)
+    """ % (DictChdTxtOut['AFC2DL_OUT'])
+        txt += """
+    PlotAfc2dCoul(afc, as.data.frame(chistabletot), "%s", what='coord', deb=debsup, fin=(debet-1), xlab = xlab, ylab = ylab)
+    """ % (DictChdTxtOut['AFC2DSL_OUT'])
+        txt += """
+    PlotAfc2dCoul(afc, as.data.frame(chistabletot), "%s", what='coord', deb=debet, fin=fin, xlab = xlab, ylab = ylab)
+    """ % (DictChdTxtOut['AFC2DEL_OUT'])
+        txt += """
+    PlotAfc2dCoul(afc, as.data.frame(chistabletot), "%s", col=TRUE, what='coord', xlab = xlab, ylab = ylab)
+    """ % (DictChdTxtOut['AFC2DCL_OUT'])
+        txt += """
+    PlotAfc2dCoul(afc, as.data.frame(chistabletot), "%s", what='crl', deb=1, fin=(debsup-1), xlab = xlab, ylab = ylab)
+    PlotAfc2dCoul(afc, as.data.frame(chistabletot), "%s", what='crl', deb=debsup, fin=(debet-1), xlab = xlab, ylab = ylab)
+    PlotAfc2dCoul(afc, as.data.frame(chistabletot), "%s", what='crl', deb=debet, fin=fin, xlab = xlab, ylab = ylab)
+    PlotAfc2dCoul(afc, as.data.frame(chistabletot), "%s", col=TRUE, what='crl', xlab = xlab, ylab = ylab)
+    """ % (DictChdTxtOut['AFC2DCoul'], DictChdTxtOut['AFC2DCoulSup'], DictChdTxtOut['AFC2DCoulEt'], DictChdTxtOut['AFC2DCoulCl'])
+       
+    txt += """
+#rm(dataact)
+#rm(datasup)
+#rm(dataet)
+rm(tablesqrpact)
+rm(tablesqrpsup)
+rm(tablesqrpet)
+save.image(file="%s")
+""" % DictChdTxtOut['RData']
+    file = open(DictChdTxtOut['RTxtProfGraph'], 'w')
+    file.write(txt)
+    file.close()
+
+
+def write_afc_graph(self):
+    if self.param['over'] : over = 'TRUE'
+    else : over = 'FALSE'
+
+    if self.param['do_select_nb'] : do_select_nb = 'TRUE'
+    else : do_select_nb = 'FALSE'
+
+    if self.param['do_select_chi'] : do_select_chi = 'TRUE'
+    else : do_select_chi = 'FALSE'
+
+    if self.param['cex_txt'] : cex_txt = 'TRUE'
+    else : cex_txt = 'FALSE'
+
+    if self.param['tchi'] : tchi = 'TRUE'
+    else : tchi = 'FALSE'
+
+    with open(self.RscriptsPath['afc_graph'], 'r') as f:
+        txt = f.read()
+
+#    self.DictPathOut['RData'], \
+    scripts = txt % (self.RscriptsPath['Rgraph'],\
+    self.param['typegraph'], \
+    self.param['what'], \
+    self.param['facteur'][0],\
+    self.param['facteur'][1], \
+    self.param['facteur'][2], \
+    self.param['qui'], \
+    over,  do_select_nb, \
+    self.param['select_nb'],  \
+    do_select_chi, \
+    self.param['select_chi'], \
+    cex_txt, \
+    self.param['txt_min'], \
+    self.param['txt_max'], \
+    self.fileout, \
+    self.param['width'], \
+    self.param['height'],\
+    self.param['taillecar'], \
+    self.param['alpha'], \
+    self.param['film'], \
+    tchi,\
+    self.param['tchi_min'],\
+    self.param['tchi_max'],\
+    ffr(os.path.dirname(self.fileout)))
+    return scripts
+        
+def print_simi3d(self):
+    simi3d = self.parent.simi3dpanel
+    txt = '#Fichier genere par Iramuteq'
+    if simi3d.movie.GetValue() :
+        movie = "'" + ffr(os.path.dirname(self.DictPathOut['RData'])) + "'"
+    else :
+        movie = 'NULL'
+    if self.section == 'chd_dist_quest' :
+        header = 'TRUE'
+    else :
+        header = 'FALSE'
+    txt += """
+    dm<-read.csv2("%s",row.names=1,header = %s)
+    load("%s")
+    """ % (self.DictPathOut['Contout'], header, self.DictPathOut['RData'])
+    
+    txt += """
+    source("%s")
+    """ % self.parent.RscriptsPath['Rgraph']
+
+
+    txt += """
+    make.simi.afc(dm,chistabletot, lim=%i, alpha = %.2f, movie = %s)
+    """ % (simi3d.spin_1.GetValue(), float(simi3d.slider_1.GetValue())/100, movie)
+    tmpfile = tempfile.mktemp(dir=self.parent.TEMPDIR)
+    tmp = open(tmpfile,'w')
+    tmp.write(txt)
+    tmp.close()
+    return tmpfile
+
+def dendroandbarplot(table, rownames, colnames, rgraph, tmpgraph, intxt = False, dendro=False) :
+    if not intxt :
+        txttable = 'c(' + ','.join([','.join(line) for line in table]) + ')'
+    rownb = len(rownames)
+    rownames = 'c("' + '","'.join(rownames) + '")'
+    colnames = 'c("' + '","'.join(colnames) + '")'
+    if not intxt :
+        #FIXME
+        txt = """
+            di <- matrix(data=%s, nrow=%i, byrow = TRUE)
+            rownames(di)<- %s
+            colnames(di) <- %s
+        """ % (txttable, rownb, rownames, colnames)
+    else :
+        txt = intxt
+    txt += """
+        load("%s")
+        library(ape)
+        source("%s")
+        height <- (30*ncol(di)) + (15*nrow(di))
+        height <- ifelse(height <= 400, 400, height)
+        width <- 500
+        open_file_graph("%s", width=width, height=height)
+        plot.dendro.lex(tree.cut1$tree.cl, di)
+        """ % (ffr(dendro),ffr(rgraph),  ffr(tmpgraph))
+    return txt
+
+def barplot(table, rownames, colnames, rgraph, tmpgraph, intxt = False) :
+    if not intxt :
+        txttable = 'c(' + ','.join([','.join(line) for line in table]) + ')'
+    #width = 100 + (15 * len(rownames)) + (100 * len(colnames))
+    #height =  len(rownames) * 15
+    rownb = len(rownames)
+    #if height < 400 :
+    #    height = 400
+    rownames = 'c("' + '","'.join(rownames) + '")'
+    colnames = 'c("' + '","'.join(colnames) + '")'
+    if not intxt :
+        #FIXME
+        txt = """
+            inf <- NA
+            di <- matrix(data=%s, nrow=%i, byrow = TRUE)
+            di[is.na(di)] <- max(di, na.rm=TRUE) + 2
+            rownames(di)<- %s
+            colnames(di) <- %s
+        """ % (txttable, rownb, rownames, colnames)
+    else :
+        txt = intxt
+    txt += """
+        source("%s")
+        color = rainbow(nrow(di))
+        width <- 100 + (20*length(rownames(di))) + (100 * length(colnames(di)))
+        height <- nrow(di) * 15
+        if (height < 400) { height <- 400}
+        open_file_graph("%s",width = width, height = height)
+       par(mar=c(0,0,0,0))
+           layout(matrix(c(1,2),1,2, byrow=TRUE),widths=c(3,lcm(7)))
+        par(mar=c(2,2,1,0))
+        coord <- barplot(as.matrix(di), beside = TRUE, col = color, space = c(0.1,0.6))
+        c <- colMeans(coord)
+        c1 <- c[-1]
+        c2 <- c[-length(c)]
+        cc <- cbind(c1,c2)
+        lcoord <- apply(cc, 1, mean)
+        abline(v=lcoord)
+        if (min(di) < 0) {
+            amp <- abs(max(di) - min(di))
+        } else {
+            amp <- max(di)
+        }
+        if (amp < 10) {
+            d <- 2
+        } else {
+            d <- signif(amp%%/%%10,1)
+        }
+        mn <- round(min(di))
+        mx <- round(max(di))
+        for (i in mn:mx) {
+            if ((i/d) == (i%%/%%d)) { 
+                abline(h=i,lty=3)
+            }
+        }
+        par(mar=c(0,0,0,0))
+        plot(0, axes = FALSE, pch = '')
+        legend(x = 'center' , rownames(di), fill = color)
+        dev.off()
+        """ % (rgraph, ffr(tmpgraph))    
+    return txt
+
+#def RAfcUci(DictAfcUciOut, nd=2, RscriptsPath='', PARCEX='0.8'):
+#    txt = """
+#    library(ca)
+#    nd<-%i
+#    """ % nd
+#    txt += """
+#    dataact<-read.csv2("%s")
+#    """ % (DictAfcUciOut['TableCont'])#, encoding)
+#    txt += """
+#    datasup<-read.csv2("%s")
+#    """ % (DictAfcUciOut['TableSup'])#, encoding)
+#    txt += """
+#    dataet<-read.csv2("%s")
+#    """ % (DictAfcUciOut['TableEt'])#, encoding)
+#    txt += """
+#    datatotsup<-cbind(dataact,datasup)
+#    datatotet<-cbind(dataact,dataet)
+#    afcact<-ca(dataact,nd=nd)
+#    afcsup<-ca(datatotsup,supcol=((ncol(dataact)+1):ncol(datatotsup)),nd=nd)
+#    afcet<-ca(datatotet,supcol=((ncol(dataact)+1):ncol(datatotet)),nd=nd)
+#    afctot<-afcsup$colcoord
+#    rownames(afctot)<-afcsup$colnames
+#    colnames(afctot)<-paste('coord. facteur',1:nd,sep=' ')
+#    afctot<-cbind(afctot,mass=afcsup$colmass)
+#    afctot<-cbind(afctot,distance=afcsup$coldist)
+#    afctot<-cbind(afctot,intertie=afcsup$colinertia)
+#    rcolet<-afcet$colsup
+#    afctmp<-afcet$colcoord[rcolet,]
+#    rownames(afctmp)<-afcet$colnames[rcolet]
+#    afctmp<-cbind(afctmp,afcet$colmass[rcolet])
+#    afctmp<-cbind(afctmp,afcet$coldist[rcolet])
+#    afctmp<-cbind(afctmp,afcet$colinertia[rcolet])
+#    afctot<-rbind(afctot,afctmp)
+#    write.csv2(afctot,file = "%s")
+#    source("%s")
+#    """ % (DictAfcUciOut['afc_row'], RscriptsPath['Rgraph'])
+#    txt += """
+#    PARCEX=%s
+#    """ % PARCEX
+#    #FIXME
+#    txt += """
+#    PlotAfc(afcet,filename="%s",toplot=c%s, PARCEX=PARCEX)
+#    """ % (DictAfcUciOut['AfcColAct'], "('none','active')")
+#    txt += """
+#    PlotAfc(afcsup,filename="%s",toplot=c%s, PARCEX=PARCEX)
+#    """ % (DictAfcUciOut['AfcColSup'], "('none','passive')")
+#    txt += """PlotAfc(afcet,filename="%s", toplot=c%s, PARCEX=PARCEX)
+#    """ % (DictAfcUciOut['AfcColEt'], "('none','passive')")
+#    txt += """
+#    PlotAfc(afcet,filename="%s", toplot=c%s, PARCEX=PARCEX)
+#    """ % (DictAfcUciOut['AfcRow'], "('all','none')")
+#    f = open(DictAfcUciOut['Rafcuci'], 'w')
+#    f.write(txt)
+#    f.close()
+
diff --git a/ProfList.py b/ProfList.py
new file mode 100644 (file)
index 0000000..db1dbd1
--- /dev/null
@@ -0,0 +1,875 @@
+# -*- coding: utf-8 -*-
+
+#----------------------------------------------------------------------------
+# Name:         ListCtrl.py
+# Author:       Pierre Ratinaud
+# 
+
+#comes from ListCtrl.py from the demo tool of wxPython:
+# Author:       Robin Dunn & Gary Dumer
+#
+# Created:
+# Copyright:    (c) 1998 by Total Control Software
+# Licence:      wxWindows license
+#----------------------------------------------------------------------------
+
+import os
+import sys
+import  wx
+import  wx.lib.mixins.listctrl  as  listmix
+from tabsimi import DoSimi
+from listlex import ListForSpec
+from chemins import ConstructPathOut, ffr
+from dialog import PrefExport, PrefUCECarac, SearchDial
+from tableau import Tableau
+from search_tools import SearchFrame
+import webbrowser
+import cStringIO
+import tempfile
+import codecs
+from functions import exec_rcode, MessageImage, progressbar, treat_var_mod
+from PrintRScript import barplot
+from textclassechd import ClasseCHD
+from shutil import copyfile
+
+#---------------------------------------------------------------------------
+
+class ProfListctrl(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin):
+    def __init__(self, parent, ID, pos=wx.DefaultPosition,
+                 size=wx.DefaultSize, style=0):
+        wx.ListCtrl.__init__(self, parent, ID, pos, size, style)
+        listmix.ListCtrlAutoWidthMixin.__init__(self)
+
+
+class ProfListctrlPanel(wx.Panel, listmix.ColumnSorterMixin):
+    def __init__(self, parent, gparent, ProfClasse, Alceste=False, cl=0):
+        self.parent = parent
+        classe = ProfClasse
+        self.cl = cl
+        self.Source = gparent
+        if 'tableau' in dir(self.Source):
+            self.tableau = self.Source.tableau
+        self.Alceste = Alceste
+        self.var_mod = {}
+        
+
+        wx.Panel.__init__(self, parent, -1, style=wx.WANTS_CHARS)
+        
+        search_id = wx.NewId()
+        searchall_id = wx.NewId()
+        self.parent.Bind(wx.EVT_MENU, self.onsearch, id = search_id)
+        self.parent.Bind(wx.EVT_MENU, self.onsearchall, id = searchall_id)
+        self.accel_tbl = wx.AcceleratorTable([(wx.ACCEL_CTRL, ord('F'), search_id),
+                                              (wx.ACCEL_CTRL|wx.ACCEL_SHIFT, ord('F'), searchall_id)])
+        self.SetAcceleratorTable(self.accel_tbl)
+       
+        self.il = wx.ImageList(16, 16)
+#        self.idx1 = self.il.Add(images.getSmilesBitmap())
+        self.sm_up = self.il.Add(getSmallUpArrowBitmap())
+        self.sm_dn = self.il.Add(getSmallDnArrowBitmap())
+        tID = wx.NewId()
+
+        self.list = ProfListctrl(self, tID,
+                                 style=wx.LC_REPORT 
+                                 | wx.BORDER_NONE
+                                 | wx.LC_EDIT_LABELS
+                                 | wx.LC_SORT_ASCENDING
+                                 )
+        line1 = classe[0]
+        limit = 0
+        limitsup = 0
+        i = 0
+        dictdata = {}
+        limit = [i for i,b in enumerate(classe[1:]) if b[0] == '*']
+        if limit != [] :
+            limit = limit[0] - 1
+        limitsup = [i for i,b in enumerate(classe[1:]) if b[0] == '*****'] 
+        if limitsup == [] :
+            limitsup = 0
+        else :
+            limitsup = limitsup[0]
+        classen = [line for line in classe[1:] if line[0] != '*' and line[0] != '*****']
+        if limit == [] :
+            limit = len(classen) - 1
+        dictdata = dict(zip([i for i in range(0,len(classen))], classen))
+        #if not self.Alceste :
+        #    limit = limit + 1
+        self.list.SetImageList(self.il, wx.IMAGE_LIST_SMALL)
+        
+        self.PopulateList(dictdata, limit, limitsup, Alceste)
+
+        self.Bind(wx.EVT_SIZE, self.OnSize)
+        self.Bind(wx.EVT_LIST_COL_CLICK, self.OnColClick)
+        self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.OnItemSelected, self.list)
+
+        # for wxMSW
+        self.list.Bind(wx.EVT_COMMAND_RIGHT_CLICK, self.OnRightClick)
+
+        # for wxGTK
+        self.list.Bind(wx.EVT_RIGHT_UP, self.OnRightClick)
+        self.itemDataMap = dictdata
+        listmix.ColumnSorterMixin.__init__(self, 8)
+        self.do_greyline()
+#-----------------------------------------------------------------------------------------    
+
+    def PopulateList(self, dictdata, limit, limitsup, Alceste):
+        
+        
+            # for normal, simple columns, you can add them like this:
+        self.list.InsertColumn(0, "num", wx.LIST_FORMAT_RIGHT)
+        self.list.InsertColumn(1, "eff. uce", wx.LIST_FORMAT_RIGHT)
+        self.list.InsertColumn(2, "eff. total", wx.LIST_FORMAT_RIGHT)
+        self.list.InsertColumn(3, "pourcentage", wx.LIST_FORMAT_RIGHT)
+        self.list.InsertColumn(4, "chi2", wx.LIST_FORMAT_RIGHT)
+        self.list.InsertColumn(5, "Type", wx.LIST_FORMAT_RIGHT)
+        self.list.InsertColumn(6, "forme", wx.LIST_FORMAT_RIGHT)
+        self.list.InsertColumn(7, "p", wx.LIST_FORMAT_RIGHT)
+        
+        for key in dictdata : #.iteritems():
+                index = self.list.InsertStringItem(sys.maxint, '%4i' % key)
+                i = 1
+                for val in dictdata[key][1:]:
+                    self.list.SetStringItem(index, i, str(dictdata[key][i]))
+                    i += 1
+                self.list.SetItemData(index, key)
+
+        self.list.SetColumnWidth(0, 60)
+        self.list.SetColumnWidth(1, 70)
+        self.list.SetColumnWidth(2, 80)
+        self.list.SetColumnWidth(3, 100)
+        self.list.SetColumnWidth(4, 70)
+        self.list.SetColumnWidth(5, wx.LIST_AUTOSIZE)
+        self.list.SetColumnWidth(6, wx.LIST_AUTOSIZE)
+        self.list.SetColumnWidth(7, wx.LIST_AUTOSIZE)
+
+        # show how to change the colour of a couple items
+        if limitsup != 0 :
+            for i in range(limitsup, limit):
+                   item = self.list.GetItem(i)
+                   item.SetTextColour(wx.RED) 
+                   self.list.SetItem(item)
+        else :           
+            limit=limit+1
+        
+        for i in range(limit, len(dictdata)):
+            item = self.list.GetItem(i)
+            item.SetTextColour(wx.BLUE)
+            self.list.SetItem(item)          
+
+        if limitsup != 0 :
+            self.la = [self.getColumnText(i,6) for i in range(0, limitsup-1)]
+            self.lchi = [float(self.getColumnText(i,4)) for i in range(0, limitsup-1)]
+            self.lfreq = [int(self.getColumnText(i,1)) for i in range(0, limitsup-1)]
+        else :
+            self.la = [self.getColumnText(i,6) for i in range(0, limit)]
+            self.lfreq = [int(self.getColumnText(i,1)) for i in range(0, limit)]
+            self.lchi = [float(self.getColumnText(i,4)) for i in range(0, limit)]
+                
+    def do_greyline(self):
+        for row in xrange(self.list.GetItemCount()):
+            if row % 2 :
+                self.list.SetItemBackgroundColour(row, (230, 230, 230))
+            else :
+                self.list.SetItemBackgroundColour(row, wx.WHITE)
+
+
+    # Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py
+    def GetListCtrl(self):
+        return self.list
+
+    # Used by the ColumnSorterMixin, see wx/lib/mixins/listctrl.py
+    def GetSortImages(self):
+        return (self.sm_dn, self.sm_up)
+
+
+    def OnRightDown(self, event):
+        x = event.GetX()
+        y = event.GetY()
+        item, flags = self.list.HitTest((x, y))
+
+        if flags & wx.LIST_HITTEST_ONITEM:
+            self.list.Select(item)
+
+        event.Skip()
+
+
+    def getColumnText(self, index, col):
+        item = self.list.GetItem(index, col)
+        return item.GetText()
+
+
+    def OnItemSelected(self, event):
+        self.currentItem = event.m_itemIndex
+        event.Skip()
+
+    def onsearch(self, evt) :
+        self.dial = SearchDial(self, self, 6, True)
+        self.dial.CenterOnParent()
+        self.dial.ShowModal()
+        self.dial.Destroy()
+
+    def onsearchall(self, evt) :
+        if 'FrameSearch' not in dir(self.Source) :
+            self.Source.FrameSearch = SearchFrame(self.parent, -1, u"Rechercher...", self.Source.corpus)
+        self.dial = SearchDial(self, self.Source.FrameSearch.liste, 1, False)
+        self.dial.CenterOnParent()
+        self.dial.ShowModal()
+        self.dial.Destroy()
+
+    def OnRightClick(self, event):
+
+        # only do this part the first time so the events are only bound once
+        if self.Alceste:
+            if not hasattr(self, "popupID1"):
+                self.popupID1 = wx.NewId()
+                self.popupID2 = wx.NewId()
+                self.popupID3 = wx.NewId()
+                self.popupID4 = wx.NewId()
+                self.popupID5 = wx.NewId()
+                self.popupID6 = wx.NewId()
+                self.popupID7 = wx.NewId()
+                self.popupID8 = wx.NewId()
+                self.popupID9 = wx.NewId()
+                #self.popupID10 = wx.NewId()
+                self.popupIDgraph = wx.NewId()
+                self.idseg = wx.NewId()
+                self.iducecarac = wx.NewId()
+                self.idtablex = wx.NewId()
+                self.idchimod = wx.NewId()
+                self.idwordgraph = wx.NewId()
+                self.popup_proxe = wx.NewId()
+                self.idlexdendro = wx.NewId()
+                self.idexport = wx.NewId()
+            #    self.export_classes = wx.NewId()
+   
+                self.Bind(wx.EVT_MENU, self.OnPopupOne, id=self.popupID1)
+                self.Bind(wx.EVT_MENU, self.OnPopupTwo, id=self.popupID2)
+                self.Bind(wx.EVT_MENU, self.OnPopupThree, id=self.popupID3)
+                self.Bind(wx.EVT_MENU, self.OnPopupFour, id=self.popupID4)
+                self.Bind(wx.EVT_MENU, self.OnPopupFive, id=self.popupID5)
+                self.Bind(wx.EVT_MENU, self.OnPopupSix, id=self.popupID6)
+                self.Bind(wx.EVT_MENU, self.OnPopupSeven, id=self.popupID7)
+                self.Bind(wx.EVT_MENU, self.OnPopupHeight, id=self.popupID8)
+                self.Bind(wx.EVT_MENU, self.OnPopupNine, id=self.popupID9)
+                #self.Bind(wx.EVT_MENU, self.OnPopupSpec, id=self.popupID10)
+                self.Bind(wx.EVT_MENU, self.on_graph, id=self.popupIDgraph)
+                self.Bind(wx.EVT_MENU, self.on_segments, id=self.idseg)
+                self.Bind(wx.EVT_MENU, self.on_uce_carac, id = self.iducecarac)
+                self.Bind(wx.EVT_MENU, self.on_tablex, id = self.idtablex)
+                self.Bind(wx.EVT_MENU, self.quest_var_mod, id = self.idchimod)
+                self.Bind(wx.EVT_MENU, self.onwordgraph, id = self.idwordgraph)
+                self.Bind(wx.EVT_MENU, self.onproxe, id = self.popup_proxe)
+                self.Bind(wx.EVT_MENU, self.onlexdendro, id = self.idlexdendro)
+                self.Bind(wx.EVT_MENU, self.onexport, id = self.idexport)
+              #  self.Bind(wx.EVT_MENU, self.on_export_classes, id = self.export_classes)
+    #            self.Bind(wx.EVT_MENU, self.OnPopupThree, id=self.popupID3)
+    
+            # make a menu
+            menu = wx.Menu()
+            menu.Append(self.popupID1, u"Formes associées")
+            menu.Append(self.idtablex, u"Chi2 par classe")
+            menu.Append(self.idlexdendro, u"Chi2 par classe + dendro")
+            menu.Append(self.idchimod, u"Chi2 modalités de la variable")
+            menu.Append(self.idwordgraph, u"Graphe du mot")
+            #menu.Append(self.export_classes, u"Exporter le corpus...") 
+            
+            #menu.Append(self.popupID10, u"Spécificités")
+
+            menu_conc = wx.Menu()
+            menu_conc.Append(self.popupID2, u"dans les uce de la classe")
+            menu_conc.Append(self.popupID3, u"dans les uce classées")
+            menu_conc.Append(self.popupID4, u"dans toutes les uce")
+            menu.AppendMenu(-1, u"Concordancier", menu_conc) 
+            menu_cnrtl = wx.Menu()      
+            menu_cnrtl.Append(self.popupID5, u"Définition")
+            menu_cnrtl.Append(self.popupID6, u"Etymologie")
+            menu_cnrtl.Append(self.popupID7, u"Synonymie")
+            menu_cnrtl.Append(self.popupID8, u"Antonymie")
+            menu_cnrtl.Append(self.popupID9, u"Morphologie")
+            menu_cnrtl.Append(self.popup_proxe, u"Proxémie")
+            menu.AppendMenu(-1, u"Outils du CNRTL", menu_cnrtl)
+            menu.AppendSeparator()
+            menu.Append(self.popupIDgraph, u"Graphe de la classe")
+            menu.Append(self.idseg, u"Segments répétés")
+            menu.Append(self.iducecarac, u"UCE caractéristiques")
+            menu.Append(self.idexport, 'Partitionner...')
+            #menu.Append(self.popupID2, u"Concordancier")
+    #        menu.Append(self.popupID3, "recharger")
+    
+            self.PopupMenu(menu)
+            menu.Destroy()
+        elif 'tableau' in dir(self.Source) :
+            if not hasattr(self, "pop1"):
+                self.pop1 = wx.NewId()
+                self.pop2 = wx.NewId()
+                self.pop3 = wx.NewId()
+                self.Bind(wx.EVT_MENU, self.quest_simi, id=self.pop1)
+                self.Bind(wx.EVT_MENU, self.on_tablex, id=self.pop2)
+                self.Bind(wx.EVT_MENU, self.quest_var_mod, id=self.pop3)
+
+            menu = wx.Menu()
+            menu.Append(self.pop2, u"Chi2 par classe")
+            menu.Append(self.pop3, u"Chi2 modalités de la variable")
+            menu.AppendSeparator()
+            menu.Append(self.pop1, u"Graph de la classe")
+            self.PopupMenu(menu)
+            menu.Destroy()
+
+    def onexport(self, evt) :
+        if 'corpus' in dir(self.Source):
+            corpus = self.Source.corpus
+        ClasseCHD(self.parent, corpus, self.cl)
+
+    def quest_var_mod(self, evt) :
+        if 'corpus' in dir(self.Source):
+            corpus = self.Source.corpus
+            if self.var_mod == {} :
+                self.var_mod = treat_var_mod([val for val in corpus.make_etoiles()])
+        else :
+            corpus = self.Source.tableau
+            if self.var_mod == {} :
+                self.var_mod = treat_var_mod([val for val in corpus.actives] + [val for val in corpus.sups])
+        with codecs.open(self.Source.pathout['chisqtable'], 'r', corpus.parametres['syscoding']) as f :
+            chistable = [line.replace('\n','').replace('\r','').replace('"','').replace(',','.').split(';') for line in f]
+        title = chistable[0]
+        title.pop(0)
+        chistable.pop(0)
+        vchistable = [line[1:] for line in chistable]
+        fchistable = [line[0] for line in chistable]
+        word = self.getColumnText(self.list.GetFirstSelected(), 6)
+        if len(word.split('_')) > 1 :
+            var = word.split('_')[0]
+            words = [word for word in self.var_mod[var]]
+            words.sort()
+            tableout = []
+            kwords = []
+            for word in words :
+                if word in fchistable :
+                    tableout.append(vchistable[fchistable.index(word)])
+                    kwords.append(word)
+            tmpgraph = tempfile.mktemp(dir=self.Source.parent.TEMPDIR)
+            txt = barplot(tableout, kwords, title, self.Source.parent.RscriptsPath['Rgraph'], tmpgraph)
+            tmpscript = tempfile.mktemp(dir=self.Source.parent.TEMPDIR)
+            file = open(tmpscript,'w')
+            file.write(txt)
+            file.close()
+            exec_rcode(self.Source.parent.RPath, tmpscript, wait = True)
+            win = MessageImage(self, -1, u"Graphique", size=(700, 500),style = wx.DEFAULT_FRAME_STYLE)
+            win.addsaveimage(tmpgraph)
+            txt = "<img src='%s'>" % tmpgraph
+            win.HtmlPage.SetPage(txt)
+            win.Show(True)
+        else :
+            dial = wx.MessageDialog(self, u"Ce n'est pas une forme du type variable_modalité", u"Problème", wx.OK | wx.ICON_WARNING)
+            dial.CenterOnParent()
+            dial.ShowModal()
+            dial.Destroy()
+
+    def quest_simi(self, evt) :
+        tableau = self.Source.tableau
+        tab = tableau.make_table_from_classe(self.cl, self.la)
+        pathout = ConstructPathOut(self.Source.pathout+'/', 'simi_classe_%i' %self.cl)
+        self.filename = os.path.join(pathout,'mat01.csv')
+        tableau.printtable(self.filename, tab)
+        del tab
+        paramsimi = {'coeff' : 0,
+                          'layout' : 2,
+                          'type' : 1,
+                          'arbremax' : 1,
+                          'coeff_tv' : 1,
+                          'coeff_tv_nb' : 0,
+                          'tvprop' : 0,
+                          'tvmin' : 5,
+                          'tvmax' : 30,
+                          'coeff_te' : 1,
+                          'coeff_temin' : 1,
+                          'coeff_temax' : 10,
+                          'label_v': 1,
+                          'label_e': 1,
+                          'vcex' : 0,
+                          'vcexmin' : 10,
+                          'vcexmax' : 25,
+                          'cex' : 10,
+                          'cexfromchi' : True,
+                          'sfromchi': False,
+                          'seuil_ok' : 0,
+                          'seuil' : 1,
+                          'cols' : (255,0,0),
+                          'cola' : (200,200,200),
+                          'width' : 1000,
+                          'height' : 1000,
+                          'first' : True,
+                          'keep_coord' : True,
+                          'alpha' : 20,
+                          'film': False,
+                          }
+#        self.tableau.actives = {}
+#        self.tableau.lchi = self.lchi
+#        self.tableau.chi = {}
+#        for i, val in enumerate(self.la) :
+#            self.tableau.actives[val] = [self.lfreq[i]]
+#            self.tableau.chi[val] = [self.lchi[i]]
+                          
+        act = {}
+        self.tableau.chi = {}
+        self.tableau.lchi = self.lchi
+        self.tableau.parametre['fromprof'] = True
+        for i, val in enumerate(self.la) :
+            act[val] = [self.lfreq[i]]
+            self.tableau.chi[val] = [self.lchi[i]]
+        DoSimi(self, param = paramsimi, fromprof = ffr(self.filename), pathout = pathout, listactives = self.la, actives = act)
+
+    def onwordgraph(self, evt):
+        word = self.getColumnText(self.list.GetFirstSelected(), 6)
+        dlg = progressbar(self, 2)
+        corpus = self.Source.corpus
+        uces = corpus.lc[self.cl-1]
+        dlg.Update(1, u'Tableau...')
+        #tab = corpus.make_table_with_classe(uces, self.la)
+        pathout = ConstructPathOut(self.Source.pathout.dirout + '/' , 'simi_%s' % word)
+        self.filename = os.path.join(pathout,'mat01.csv')
+        dlg.Update(2, u'Ecriture...')
+        #corpus.write_tab(tab, self.filename)
+        #del tab
+        corpus.make_and_write_sparse_matrix_from_classe(self.la, uces, self.filename)
+        dlg.Destroy()
+        paramsimi = {'coeff' : 0,
+                          'layout' : 2,
+                          'type' : 1,
+                          'arbremax' : 0,
+                          'coeff_tv' : 1,
+                          'coeff_tv_nb' : 0,
+                          'tvprop' : 0,
+                          'tvmin' : 5,
+                          'tvmax' : 30,
+                          'coeff_te' : 1,
+                          'coeff_temin' : 1,
+                          'coeff_temax' : 10,
+                          'label_v': 1,
+                          'label_e': 0,
+                          'vcex' : 1,
+                          'vcexmin' : 10,
+                          'vcexmax' : 25, 
+                          'cex' : 10,
+                          'seuil_ok' : 1,
+                          'seuil' : 1,
+                          'cols' : (255,0,0),
+                          'cola' : (200,200,200),
+                          'width' : 600,
+                          'height' : 600,
+                          'first' : True,
+                          'keep_coord' : True,
+                          'alpha' : 20,
+                          'film': False,
+                          }
+        self.tableau = Tableau(self.parent, '')
+        self.tableau.listactives = self.la
+        self.tableau.actives = {}
+        for i, val in enumerate(self.la) :
+            self.tableau.actives[val] = [self.lfreq[i]]
+        DoSimi(self, param = paramsimi, fromprof = ffr(self.filename), pathout = pathout, wordgraph = word)
+
+
+    def OnPopupOne(self, event):
+        corpus = self.Source.corpus
+        #print 'ATTENTION PRINT ET TABLE'
+        #corpus.make_et_table()
+        word = self.getColumnText(self.list.GetFirstSelected(), 6)
+        lems = corpus.getlems()
+        uces = corpus.lc[self.cl-1]
+        rep = []
+        #FIXME : donner aussi eff reel a la place de nb uce
+        for forme in lems[word].formes :
+            ucef = list(set(corpus.getworduces(forme)).intersection(uces))
+            #ucef = [uce for uce in corpus.formes[forme][1] if uce in uces]
+            if ucef != [] :
+                nb = len(ucef)
+                rep.append([corpus.getforme(forme).forme, nb])
+        win = message(self, -1, u"Formes associées", size=(300, 200), style=wx.DEFAULT_FRAME_STYLE)
+        win.html = '<html>\n' + '<br>'.join([' : '.join([str(val) for val in forme]) for forme in rep]) + '\n</html>'
+        win.HtmlPage.SetPage(win.html)
+        win.Show(True)
+
+    def on_graph(self, evt):
+        dlg = progressbar(self, 2)
+        corpus = self.Source.corpus
+        uces = corpus.lc[self.cl-1]
+        dlg.Update(1, u'Tableau...')
+        #tab = corpus.make_table_with_classe(uces, self.la)
+        pathout = ConstructPathOut(self.Source.pathout.dirout+'/', 'simi_classe_%i' %self.cl)
+        self.filename = os.path.join(pathout,'mat01.csv')
+        dlg.Update(2, u'Ecriture...')
+        #corpus.write_tab(tab, self.filename)
+        #del tab
+        corpus.make_and_write_sparse_matrix_from_classe(self.la, uces, self.filename)
+        dlg.Destroy()
+        paramsimi = {'coeff' : 0,
+                          'layout' : 2,
+                          'type' : 1,
+                          'arbremax' : 1,
+                          'coeff_tv' : 1,
+                          'coeff_tv_nb' : 0,
+                          'tvprop' : 0,
+                          'tvmin' : 5,
+                          'tvmax' : 30,
+                          'coeff_te' : 1,
+                          'coeff_temin' : 1,
+                          'coeff_temax' : 10,
+                          'label_v': 1,
+                          'label_e': 0,
+                          'vcex' : 0,
+                          'vcexmin' : 10,
+                          'vcexmax' : 25,
+                          'cex' : 10,
+                          'cexfromchi' : True,
+                          'sfromchi': False,
+                          'seuil_ok' : 0,
+                          'seuil' : 1,
+                          'cols' : (255,0,0),
+                          'cola' : (200,200,200),
+                          'width' : 1000,
+                          'height' : 1000,
+                          'first' : True,
+                          'keep_coord' : True,
+                          'alpha' : 20,
+                          'film': False,
+                          }
+        self.tableau = Tableau(self.parent, '')
+        self.tableau.listactives = self.la
+        self.tableau.actives = {}
+        self.tableau.lchi = self.lchi
+        self.tableau.chi = {}
+        self.tableau.parametre['fromprof'] = True
+        for i, val in enumerate(self.la) :
+            self.tableau.actives[val] = [self.lfreq[i]]
+            self.tableau.chi[val] = [self.lchi[i]]
+        DoSimi(self, param = paramsimi, fromprof = ffr(self.filename), pathout = pathout)
+
+    def on_segments(self,evt) :
+        dlg = progressbar(self, 2)
+        corpus = self.Source.corpus
+        uces = corpus.lc[self.cl-1]
+        l = []
+        dlg.Update(1, u'Segments...')
+        for i in range(2,10) :
+            li = corpus.find_segments_in_classe(uces, i, 1000)
+            if li == [] :
+                break
+            else :
+                l += li
+        l.sort(reverse = True)
+        d = {}
+        dlg.Update(2, 'Tri...')
+        for i, line in enumerate(l) :
+            d[i] = [line[1],line[0], line[2]]
+        first = ['','','']
+        para={'dico': d,'fline':first}
+        dlg.Destroy()
+        win = wliste(self, -1, u"Segments répétés - Classe %i" % self.cl, d, first, size=(600, 500))
+        win.Show(True)
+
+    def on_uce_carac(self,evt) :
+        dial = PrefUCECarac(self, self.parent)
+        dial.CenterOnParent()
+        if dial.ShowModal() == wx.ID_OK :
+            limite = dial.spin_eff.GetValue()
+            atype = dial.radio_type.GetSelection()
+            dlg = progressbar(self,maxi = 4)
+            corpus = self.Source.corpus
+            uces = corpus.lc[self.cl-1]
+            tab = corpus.make_table_with_classe(uces, self.la)
+            tab.pop(0)
+            dlg.Update(2, u'score...')
+            if atype == 0 :
+                ntab = [round(sum([self.lchi[i] for i, word in enumerate(line) if word == 1]),2) for line in tab]
+            else :
+                ntab = [round(sum([self.lchi[i] for i, word in enumerate(line) if word == 1])/float(sum(line)),2) if sum(line)!=0 else 0 for line in tab]
+            ntab2 = [[ntab[i], uces[i]] for i, val in enumerate(ntab)]
+            del ntab
+            ntab2.sort(reverse = True)
+            ntab2 = ntab2[:limite]
+            dlg.Update(3, u'concordancier...')
+            ucestxt = [corpus.ucis_paras_uces[val[1][0]][val[1][1]][val[1][2]] for val in ntab2]
+            ucestxt = [corpus.make_concord(self.la, ' '.join(uce), 'red') for uce in ucestxt]
+            dlg.Update(4, u'texte...')
+            ucis_txt = [' '.join(corpus.ucis[val[1][0]][0]) for val in ntab2]
+            win = message(self, -1, u"UCE caractéristiques - Classe %i" % self.cl, size=(600, 500), style=wx.DEFAULT_FRAME_STYLE)
+            win.html = '<html>\n' + '<br><br>'.join(['<br>'.join([ucis_txt[i], 'score : ' + str(ntab2[i][0]), ucestxt[i]]) for i in range(0,len(ucestxt))]) + '\n</html>'
+            win.HtmlPage.SetPage(win.html)
+            dlg.Destroy()
+            win.Show(True)
+    
+    def on_tablex(self, evt):
+        if 'corpus' in dir(self.Source):
+            corpus = self.Source.corpus
+        else :
+            corpus = self.Source.tableau
+        with codecs.open(self.Source.pathout['chisqtable'], 'r', corpus.parametres['syscoding']) as f :
+            chistable = [line.replace('\n','').replace('\r','').replace('"','').replace(',','.').split(';') for line in f]
+        title = chistable[0]
+        title.pop(0)
+        chistable.pop(0)
+        vchistable = [line[1:] for line in chistable]
+        fchistable = [line[0] for line in chistable]
+        words = [self.getColumnText(self.list.GetFirstSelected(), 6)]
+        tableout = [vchistable[fchistable.index(words[0])]]
+        last = self.list.GetFirstSelected()
+        while self.list.GetNextSelected(last) != -1:
+            last = self.list.GetNextSelected(last)
+            word = self.getColumnText(last, 6)
+            words.append(word)
+            tableout.append(vchistable[fchistable.index(word)])
+        tmpgraph = tempfile.mktemp(dir=self.Source.parent.TEMPDIR)
+        nbcl = len(title)
+        txt = barplot(tableout, words, title, self.Source.parent.RscriptsPath['Rgraph'], tmpgraph)
+        tmpscript = tempfile.mktemp(dir=self.Source.parent.TEMPDIR)
+        file = open(tmpscript,'w')
+        file.write(txt)
+        file.close()
+        
+        exec_rcode(self.Source.parent.RPath, tmpscript, wait = True)
+        win = MessageImage(self, -1, u"Graphique", size=(700, 500),style = wx.DEFAULT_FRAME_STYLE)
+        win.addsaveimage(tmpgraph)
+        txt = "<img src='%s'>" % tmpgraph
+        win.HtmlPage.SetPage(txt)
+        win.Show(True)
+
+    def onlexdendro(self, evt):
+        if 'corpus' in dir(self.Source):
+            corpus = self.Source.corpus
+        else :
+            corpus = self.Source.tableau
+        with codecs.open(self.Source.pathout['chisqtable'], 'r', corpus.parametres['syscoding']) as f :
+            chistable = [line.replace('\n','').replace('\r','').replace('"','').replace(',','.').split(';') for line in f]
+        title = chistable[0]
+        title.pop(0)
+        chistable.pop(0)
+        vchistable = [line[1:] for line in chistable]
+        fchistable = [line[0] for line in chistable]
+        words = [self.getColumnText(self.list.GetFirstSelected(), 6)]
+        tableout = [vchistable[fchistable.index(words[0])]]
+        last = self.list.GetFirstSelected()
+        while self.list.GetNextSelected(last) != -1:
+            last = self.list.GetNextSelected(last)
+            word = self.getColumnText(last, 6)
+            words.append(word)
+            tableout.append(vchistable[fchistable.index(word)])
+        tmpgraph = tempfile.mktemp(dir=self.Source.parent.TEMPDIR)
+        txttable = 'c(' + ','.join([','.join(line) for line in tableout]) + ')'
+        rownames = 'c("' + '","'.join(words) + '")'
+        colnames = 'c("' + '","'.join(title) + '")'
+        nbcl = len(title)
+        rownb = len(words)
+        txt = """
+        load("%s")
+        di <- matrix(data=%s, nrow=%i, byrow = TRUE)
+        rownames(di)<- %s
+        colnames(di) <- %s
+        library(ape)
+        source("%s")
+        height <- (30*ncol(di)) + (15*nrow(di))
+        height <- ifelse(height <= 400, 400, height)
+        width <- 500
+        open_file_graph("%s", width=width, height=height)
+        plot.dendro.lex(tree.cut1$tree.cl, di)
+        """ % (self.Source.pathout['Rdendro'], txttable, rownb, rownames, colnames, self.Source.parent.RscriptsPath['Rgraph'], ffr(tmpgraph))
+        tmpscript = tempfile.mktemp(dir=self.Source.parent.TEMPDIR)
+        file = open(tmpscript,'w')
+        file.write(txt)
+        file.close()
+        exec_rcode(self.Source.parent.RPath, tmpscript, wait = True)
+        win = MessageImage(self, -1, u"Graphique", size=(700, 500),style = wx.DEFAULT_FRAME_STYLE)
+        win.addsaveimage(tmpgraph)
+        txt = "<img src='%s'>" % tmpgraph
+        win.HtmlPage.SetPage(txt)
+        win.Show(True)
+
+
+    def make_concord(self, uces, title, color = 'red') :
+        corpus = self.Source.corpus
+        ListWord = [self.getColumnText(self.list.GetFirstSelected(), 6)]
+        last = self.list.GetFirstSelected()
+        while self.list.GetNextSelected(last) != -1:
+            last = self.list.GetNextSelected(last)
+            ListWord.append(self.getColumnText(last, 6))
+        listmot = [forme for item in ListWord for forme in corpus.getlems()[item].formes]
+        win = message(self, -1, title, size=(600, 500), style=wx.DEFAULT_FRAME_STYLE)
+        toshow = ['<html>\n<H1>Concordancier</H1>\n']
+        toshow.append('<h3><font color=%s>' % color + ' '.join(ListWord) + '</font></h3><br>')
+        duce = {}
+        ucef = []
+        for word in ListWord : 
+            ucef += list(set(corpus.getlemuces(word)).intersection(uces))
+        ucef = list(set(ucef))
+        ucef.sort()
+        res = corpus.getconcorde(ucef)
+        txt = '<br>'.join(toshow) +'<br><br>'
+        for uce in res :
+            ucetxt = ' '+uce[1]+' '
+            txt += ' '.join(corpus.ucis[corpus.getucefromid(uce[0]).uci].etoiles) + '<br>'
+            for forme in listmot:
+                forme = corpus.getforme(forme).forme
+                ucetxt = ucetxt.replace(' '+forme+' ', '<font color=red> ' + forme + ' </font>')
+            txt += ucetxt + '<br><br>'
+        win.HtmlPage.SetPage(txt)
+        return win
+
+    def OnPopupTwo(self, event):
+        corpus = self.Source.corpus
+        uces = corpus.lc[self.cl-1]
+        win = self.make_concord(uces, "Concordancier - Classe %i" % self.cl)
+        win.Show(True)
+    
+    def OnPopupThree(self, event):
+        corpus = self.Source.corpus
+        uces = [classe[i] for classe in corpus.lc for i in range(0,len(classe))]
+        win = self.make_concord(uces, "Concordancier - UCE classées")
+        win.Show(True)
+        
+    def OnPopupFour(self, event):
+        corpus = self.Source.corpus
+        uces = [classe[i] for classe in corpus.lc for i in range(0,len(classe))] + corpus.lc0
+        win = self.make_concord(uces, "Concordancier - Toutes les UCE")
+        win.Show(True)
+
+    def OnPopupFive(self, event):
+        word = self.getColumnText(self.list.GetFirstSelected(), 6)
+        lk = "http://www.cnrtl.fr/definition/" + word
+        webbrowser.open(lk)
+
+    def OnPopupSix(self, event):  
+        word = self.getColumnText(self.list.GetFirstSelected(), 6)
+        lk = "http://www.cnrtl.fr/etymologie/" + word
+        webbrowser.open(lk)
+        
+    def OnPopupSeven(self, event):        
+        word = self.getColumnText(self.list.GetFirstSelected(), 6)
+        lk = "http://www.cnrtl.fr/synonymie/" + word
+        webbrowser.open(lk)
+        
+    def OnPopupHeight(self, event):  
+        word = self.getColumnText(self.list.GetFirstSelected(), 6)
+        lk = "http://www.cnrtl.fr/antonymie/" + word
+        webbrowser.open(lk)
+        
+    def OnPopupNine(self, event):            
+        word = self.getColumnText(self.list.GetFirstSelected(), 6)
+        lk = "http://www.cnrtl.fr/morphologie/" + word
+        webbrowser.open(lk)
+
+    def onproxe(self, evt) :
+        word = self.getColumnText(self.list.GetFirstSelected(), 6)
+        lk = "http://www.cnrtl.fr/proxemie/" + word
+        webbrowser.open(lk)
+
+    def OnSize(self, event):
+        w, h = self.GetClientSizeTuple()
+        self.list.SetDimensions(0, 0, w, h)
+        
+    def OnColClick(self, event):
+        self.do_greyline()
+
+
+class wliste(wx.Frame):
+    def __init__(self, parent, id, title, d, fline, size=(600, 500)):
+        wx.Frame.__init__(self, parent, id)
+        self.liste = ListForSpec(self, parent, d, fline)
+        self.button_1 = wx.Button(self, -1, "Fermer")
+        self.Bind(wx.EVT_BUTTON, self.OnCloseMe, self.button_1)
+        self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
+        self.__do_layout()
+
+    def __do_layout(self):
+        sizer_1 = wx.BoxSizer(wx.VERTICAL)
+        sizer_2 = wx.BoxSizer(wx.VERTICAL)
+        sizer_2.Add(self.liste, 1, wx.EXPAND | wx.ADJUST_MINSIZE, 0)
+        sizer_2.Add(self.button_1, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ADJUST_MINSIZE, 0)
+        sizer_1.Add(sizer_2, 1, wx.EXPAND, 0)
+        self.SetAutoLayout(True)
+        self.SetSizer(sizer_1)
+        self.Layout()
+        
+    def OnCloseMe(self, event):
+        self.Close(True)
+
+    def OnCloseWindow(self, event):
+        self.Destroy()
+
+class message(wx.Frame):
+    def __init__(self, *args, **kwds):
+        kwds["style"] = wx.DEFAULT_FRAME_STYLE
+        wx.Frame.__init__(self, *args, **kwds)
+        self.html = ""
+        self.HtmlPage=wx.html.HtmlWindow(self, -1)
+        if "gtk2" in wx.PlatformInfo:
+            self.HtmlPage.SetStandardFonts()
+        self.HtmlPage.SetFonts('Courier','Courier')
+        self.button_1 = wx.Button(self, -1, "Fermer")
+        self.button_2 = wx.Button(self, -1, u"Enregistrer...")
+
+        self.Bind(wx.EVT_BUTTON, self.OnSavePage, self.button_2)
+        self.Bind(wx.EVT_BUTTON, self.OnCloseMe, self.button_1)
+        self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
+        self.__do_layout()
+
+    def __do_layout(self):
+        sizer_1 = wx.BoxSizer(wx.VERTICAL)
+        sizer_2 = wx.BoxSizer(wx.VERTICAL)
+        sizer_2.Add(self.HtmlPage, 1, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
+        sizer_2.Add(self.button_1, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ADJUST_MINSIZE, 0)
+        sizer_2.Add(self.button_2, 0, wx.ALIGN_CENTER_HORIZONTAL|wx.ADJUST_MINSIZE, 0)
+        sizer_1.Add(sizer_2, 1, wx.EXPAND, 0)
+        self.SetAutoLayout(True)
+        self.SetSizer(sizer_1)
+        self.Layout()
+
+    def OnSavePage(self, evt) :
+        dlg = wx.FileDialog(
+            self, message="Enregistrer sous...", defaultDir=os.getcwd(),
+            defaultFile="concordancier.html", wildcard="html|*.html", style=wx.SAVE | wx.OVERWRITE_PROMPT
+            )
+        dlg.SetFilterIndex(2)
+        dlg.CenterOnParent()
+        if dlg.ShowModal() == wx.ID_OK:
+            path = dlg.GetPath()
+            with open(path, 'w') as f :
+                f.write(self.html)
+
+    def OnCloseMe(self, event):
+        self.Close(True)
+
+    def OnCloseWindow(self, event):
+        self.Destroy()
+
+def getSmallUpArrowData():
+    return \
+'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
+\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
+\x00\x00<IDAT8\x8dcddbf\xa0\x040Q\xa4{h\x18\xf0\xff\xdf\xdf\xffd\x1b\x00\xd3\
+\x8c\xcf\x10\x9c\x06\xa0k\xc2e\x08m\xc2\x00\x97m\xd8\xc41\x0c \x14h\xe8\xf2\
+\x8c\xa3)q\x10\x18\x00\x00R\xd8#\xec\xb2\xcd\xc1Y\x00\x00\x00\x00IEND\xaeB`\
+\x82' 
+
+def getSmallUpArrowBitmap():
+    return wx.BitmapFromImage(getSmallUpArrowImage())
+
+def getSmallUpArrowImage():
+    stream = cStringIO.StringIO(getSmallUpArrowData())
+    return wx.ImageFromStream(stream)
+
+#----------------------------------------------------------------------
+def getSmallDnArrowData():
+    return \
+"\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
+\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
+\x00\x00HIDAT8\x8dcddbf\xa0\x040Q\xa4{\xd4\x00\x06\x06\x06\x06\x06\x16t\x81\
+\xff\xff\xfe\xfe'\xa4\x89\x91\x89\x99\x11\xa7\x0b\x90%\ti\xc6j\x00>C\xb0\x89\
+\xd3.\x10\xd1m\xc3\xe5*\xbc.\x80i\xc2\x17.\x8c\xa3y\x81\x01\x00\xa1\x0e\x04e\
+?\x84B\xef\x00\x00\x00\x00IEND\xaeB`\x82" 
+
+def getSmallDnArrowBitmap():
+    return wx.BitmapFromImage(getSmallDnArrowImage())
+
+def getSmallDnArrowImage():
+    stream = cStringIO.StringIO(getSmallDnArrowData())
+    return wx.ImageFromStream(stream)
diff --git a/Rscripts/CHD.R b/Rscripts/CHD.R
new file mode 100644 (file)
index 0000000..fcec03f
--- /dev/null
@@ -0,0 +1,389 @@
+#Author: Pierre Ratinaud
+#Copyright (c) 2008-2011 Pierre Ratinaud
+#Lisense: GNU/GPL
+
+pp<-function(txt,val) {
+       d<-paste(txt,' : ')
+       print(paste(d,val))
+}
+MyChiSq<-function(x,sc,n){
+       sr<-rowSums(x)
+       E <- outer(sr, sc, "*")/n
+       STAT<-sum(((x - E)^2)/E)
+       STAT
+}
+
+MySpeedChi <- function(x,sc) {
+    sr <-rowSums(x)
+    E <- outer(sr, sc, "*")
+       STAT<-sum((x - E)^2/E)
+       STAT
+}
+
+find.max <- function(dtable, chitable, compte, rmax, maxinter, sc, TT) {
+    ln <- which(dtable==1, arr.ind=TRUE)
+    lo <- list()
+    lo[1:nrow(dtable)] <- 0
+    for (k in 1:nrow(ln)) {lo[[ln[k,1]]]<-append(lo[[ln[k,1]]],ln[k,2])}
+    for (k in 1:nrow(dtable)) {lo[[k]] <- lo[[k]][-1]}
+    lo<-lo[-c(1,length(lo))]
+    for (l in lo) {
+        compte <- compte + 1 
+        chitable[1,l]<-chitable[1,l]+1
+        chitable[2,l]<-chitable[2,l]-1
+        chi<-MyChiSq(chitable,sc,TT)
+        if (chi>maxinter) {
+            maxinter<-chi
+            rmax<-compte
+        }   
+    }
+    res <- list(maxinter=maxinter, rmax=rmax)
+    res
+}  
+
+CHD<-function(data.in, x=9, libsvdc=FALSE, libsvdc.path=NULL){
+#      sink('/home/pierre/workspace/iramuteq/dev/findchi2.txt')
+       dataori <- data.in
+    row.names(dataori) <- rownames(data.in)
+       dtable <- data.in
+       colnames(dtable) <- 1:ncol(dtable)
+    dout <- NULL
+       rowelim<-NULL
+       pp('ncol entree : ',ncol(dtable))
+       pp('nrow entree',nrow(dtable))
+       listcol <- list()
+       listmere <- list()
+       list_fille <- list()
+       print('vire colonnes vides en entree')#FIXME : il ne doit pas y avoir de colonnes vides en entree !!
+       sdt<-colSums(dtable)
+       if (min(sdt)==0)
+               dtable<-dtable[,-which(sdt==0)]
+    print('vire lignes vides en entree')
+    sdt<-rowSums(dtable)
+       if (min(sdt)==0) {
+        rowelim<-as.integer(rownames(dtable)[which(sdt==0)])
+        print('&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&')
+        print(rowelim)
+        print('&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&')
+               dtable<-dtable[-which(sdt==0),]
+       }
+       mere<-1
+       for (i in 1:x) {
+               clnb<-(i*2)
+               listmere[[clnb]]<-mere
+               listmere[[clnb+1]]<-mere
+               list_fille[[mere]] <- c(clnb,clnb+1)
+               listcol[[clnb]]<-vector()
+               listcol[[clnb+1]]<-vector()
+               #extraction du premier facteur de l'afc
+               print('afc')
+               pp('taille dtable dans boucle (col/row)',c(ncol(dtable),nrow(dtable)))
+               afc<-boostana(dtable, nd=1, libsvdc=libsvdc, libsvdc.path=libsvdc.path)
+               pp('SV',afc$singular.values)
+               pp('V.P.', afc$eigen.values)
+               coordrow <- as.matrix(afc$row.scores[,1])
+               coordrowori<-coordrow
+               row.names(coordrow)<-rownames(dtable)
+        coordrow <- cbind(coordrow,1:nrow(dtable))
+               print('deb recherche meilleur partition')
+        ordert <- as.matrix(coordrow[order(coordrow[,1]),])
+        ordert <- cbind(ordert, 1:nrow(ordert))
+        ordert <- ordert[order(ordert[,2]),]
+
+               listinter<-vector()
+               listlim<-vector()
+        dtable <- dtable[order(ordert[,3]),]
+        sc <- colSums(dtable)
+        TT <- sum(sc)
+        sc1 <- dtable[1,]
+        sc2 <- colSums(dtable) - sc1 
+        chitable <- rbind(sc1, sc2)
+        compte <- 1
+        maxinter <- 0
+        rmax <- NULL
+
+        inert <- find.max(dtable, chitable, compte, rmax, maxinter, sc, TT)
+               print('@@@@@@@@@@@@@@@@@@@@@@@@@@@@')
+               pp('max inter phase 1', inert$maxinter/TT)#max(listinter))
+               print('@@@@@@@@@@@@@@@@@@@@@@@@@@@@')
+        ordert <- ordert[order(ordert[,3]),]
+               listclasse<-ifelse(coordrowori<=ordert[(inert$rmax),1],clnb,clnb+1)
+           dtable <- dtable[order(ordert[,2]),]
+               cl<-listclasse
+               pp('TT',TT)
+               #dtable<-cbind(dtable,'cl'= as.vector(cl))
+
+               N1<-length(listclasse[listclasse==clnb])
+               N2<-length(listclasse[listclasse==clnb+1])
+               pp('N1',N1)
+               pp('N2',N2)
+###################################################################
+#                  reclassement des individus                     #
+###################################################################
+               malcl<-1000000000000
+               it<-0
+               listsub<-list()
+               #in boucle
+        ln <- which(dtable==1, arr.ind=TRUE)
+        lnz <- list()
+        lnz[1:nrow(dtable)] <- 0
+
+        for (k in 1:nrow(ln)) {lnz[[ln[k,1]]]<-append(lnz[[ln[k,1]]],ln[k,2])}
+        for (k in 1:nrow(dtable)) {lnz[[k]] <- lnz[[k]][-1]}
+               TT<-sum(dtable)
+
+               while (malcl!=0 & N1>=5 & N2>=5) {
+                       it<-it+1
+                       listsub[[it]]<-vector()
+            txt <- paste('nombre iteration', it)
+                       #pp('nombre iteration',it)
+                       vdelta<-vector()
+                       #dtable[,'cl']<-cl
+                       t1<-dtable[which(cl[,1]==clnb),]#[,-ncol(dtable)]
+                       t2<-dtable[which(cl[,1]==clnb+1),]#[,-ncol(dtable)]
+                       ncolt<-ncol(t1)
+                       #pp('ncolt',ncolt)
+
+            if (N1 != 1) {
+                sc1<-colSums(t1)
+            } else {
+                sc1 <- t1
+            }
+            if (N2 != 1) {
+                           sc2<-colSums(t2)
+            } else {
+                sc2 <- t2
+            }
+                       
+            sc<-sc1+sc2
+                       chtableori<-rbind(sc1,sc2)
+                       chtable<-chtableori
+                       interori<-MyChiSq(chtableori,sc,TT)/TT#chisq.test(chtableori)$statistic#/TT
+                       txt <- paste(txt, ' - interori : ',interori)
+            #pp('interori',interori)
+
+                       N1<-nrow(t1)
+                       N2<-nrow(t2)
+
+                       #pp('N1',N1)
+                       #pp('N2',N2)
+                       txt <- paste(txt, 'N1:', N1,'-N2:',N2)
+            print(txt)
+            compte <- 0
+                       for (l in lnz){
+                    chi.in<-chtable
+                    compte <- compte + 1
+                                       if(cl[compte]==clnb){
+                                               chtable[1,l]<-chtable[1,l]-1
+                                               chtable[2,l]<-chtable[2,l]+1
+                                       }else{
+                                               chtable[1,l]<-chtable[1,l]+1
+                                               chtable[2,l]<-chtable[2,l]-1
+                                       }
+                                       interswitch<-MyChiSq(chtable,sc,TT)/TT#chisq.test(chtable)$statistic/TT
+                                       ws<-interori-interswitch
+
+                                       if (ws<0){
+                                               interori<-interswitch
+                                               if(cl[compte]==clnb){
+                                                       #sc1<-chtable[1,]
+                                                       #sc2<-chtable[2,]
+                                                       cl[compte]<-clnb+1
+                                                       listsub[[it]]<-append(listsub[[it]],compte)
+                                               } else {
+                                                       #sc1<-chtable[1,]
+                                                       #sc2<-chtable[2,]
+                                                       cl[compte]<-clnb
+                                                       listsub[[it]]<-append(listsub[[it]],compte)
+                                               }
+                                               vdelta<-append(vdelta,compte)
+                    } else {
+                        chtable<-chi.in
+                                       }
+               }
+#                      for (val in vdelta) {
+#                              if (cl[val]==clnb) {
+#                                      cl[val]<-clnb+1
+#                                      listsub[[it]]<-append(listsub[[it]],val)
+#                                      }else {
+#                                      cl[val]<-clnb
+#                                      listsub[[it]]<-append(listsub[[it]],val)
+#                              }
+#                      }
+                       print('###################################')
+                       print('longueur < 0')
+                       malcl<-length(vdelta)
+                       if ((it>1)&&(!is.logical(listsub[[it]]))&&(!is.logical(listsub[[it-1]]))){
+                               if (listsub[[it]]==listsub[[(it-1)]]){
+                                       malcl<-0
+                               }
+                       }
+                       print(malcl)
+                       print('###################################')
+               }
+               #dtable<-cbind(dtable,'cl'=as.vector(cl))
+        #dtable[,'cl'] <-as.vector(cl)
+#######################################################################
+#                 Fin reclassement des individus                      #
+#######################################################################
+#              if (!(length(cl[cl==clnb])==1 || length(cl[cl==clnb+1])==1)) {
+                       #t1<-dtable[dtable[,'cl']==clnb,][,-ncol(dtable)]
+                       #t2<-dtable[dtable[,'cl']==clnb+1,][,-ncol(dtable)]
+                   t1<-dtable[which(cl[,1]==clnb),]#[,-ncol(dtable)]
+                       t2<-dtable[which(cl[,1]==clnb+1),]#[,-ncol(dtable)]
+            if (class(t1)=='numeric') {
+                sc1 <- as.vector(t1)
+                nrowt1 <- 1
+            } else {
+                sc1 <- colSums(t1)
+                nrowt1 <- nrow(t1)
+            }
+            if (class(t2)=='numeric') {
+                sc2 <- as.vector(t2)
+                nrowt2 <- 1
+            } else {
+                sc2 <- colSums(t2)
+                nrowt2 <- nrow(t2)
+            }
+            chtable<-rbind(sc1,sc2)
+                       inter<-chisq.test(chtable)$statistic/TT
+                       pp('last inter',inter)
+                       print('=====================')
+                       #calcul de la specificite des colonnes
+                       mint<-min(nrowt1,nrowt2)
+                       maxt<-max(nrowt1,nrowt2)
+                       seuil<-round((1.9*(maxt/mint))+1.9,digit=6)
+                       #sink('/home/pierre/workspace/iramuteq/dev/findchi2.txt')
+#                      print('ATTENTION SEUIL 3,84')
+#                      seuil<-3.84
+                       pp('seuil',seuil)
+                       sominf<-0
+                       nv<-0
+                       nz<-0
+                       ncclnb<-0
+                       ncclnbp<-0
+            NN1<-0
+            NN2<-0
+            maxchip<-0
+            nbzeroun<-0
+            res1<-0
+            res2<-0
+            nbseuil<-0
+            nbexe<-0
+            nbcontrib<-0
+                       cn<-colnames(dtable)
+            #another try#########################################
+            one <- cbind(sc1,sc2)
+            cols <- c(length(which(cl==clnb)), length(which(cl==clnb+1))) 
+            print(cols)
+            colss <- matrix(rep(cols,ncol(dtable)), ncol=2, byrow=TRUE)
+            zero <- colss - one
+            rows <- cbind(rowSums(zero), rowSums(one))
+            n <- sum(cols)
+            for (m in 1:nrow(rows)) {
+                obs <- t(matrix(c(zero[m,],one[m,]),2,2))
+                E <- outer(rows[m,],cols,'*')/n
+                if ((min(obs[2,])==0) & (min(obs[1,])!=0)) {
+                    chi <- seuil + 1
+                } else if ((min(obs[1,])==0) & (min(obs[2,])!=0)) {
+                    chi <- seuil - 1
+                } else if (any(obs < 10)) {
+                    chi <- sum((abs(obs - E) - 0.5)^2 / E)
+                } else {
+                    chi <- sum(((obs - E)^2)/E)
+                }
+                if (is.na(chi)) {
+                    chi <- 0
+                }
+                if (chi > seuil) {
+                    if (obs[2,1] < E[2,1]) {
+                        listcol[[clnb]]<-append(listcol[[clnb]],cn[m])
+                        ncclnb<-ncclnb+1
+                    } else if (obs[2,2] < E[2,2]) {
+                                               listcol[[clnb+1]]<-append(listcol[[clnb+1]],cn[m])
+                                               ncclnbp<-ncclnbp+1
+                    }
+                }
+            }
+            ######################################################
+                       print('resultats elim item')
+                       pp(clnb+1,length(listcol[[clnb+1]]))
+                       pp(clnb,length(listcol[[clnb]]))
+                       pp('ncclnb',ncclnb)
+                       pp('ncclnbp',ncclnbp)
+                       listrownamedtable<-rownames(dtable)
+                       listrownamedtable<-as.integer(listrownamedtable)
+                       newcol<-vector(length=nrow(dataori))
+                       #remplissage de la nouvelle colonne avec les nouvelles classes
+                       print('remplissage')
+#                      num<-0
+            newcol[listrownamedtable] <- cl[,1]
+                       #recuperation de la classe precedante pour les cases vides
+                       print('recuperation classes precedentes')
+            if (i!=1) {
+                newcol[which(newcol==0)] <- dout[,ncol(dout)][which(newcol==0)]
+            }
+            if(!is.null(rowelim)) {
+                newcol[rowelim] <- 0
+            }
+                       tailleclasse<-as.matrix(summary(as.factor(as.character(newcol))))
+                       print('tailleclasse')
+                       print(tailleclasse)
+                       tailleclasse<-as.matrix(tailleclasse[!(rownames(tailleclasse)==0),])
+                       plusgrand<-which.max(tailleclasse)
+                       #???????????????????????????????????
+                       #Si 2 classes ont des effectifs egaux, on prend la premiere de la liste...
+                       if (length(plusgrand)>1) {
+                               plusgrand<-plusgrand[1]
+                       }
+                       #????????????????????????????????????
+                       
+                       #constuction du prochain tableau a analyser
+                       print('construction tableau suivant')
+            dout<-cbind(dout,newcol)
+                       classe<-as.integer(rownames(tailleclasse)[plusgrand])
+                       dtable<-dataori[which(newcol==classe),]
+                       row.names(dtable)<-rownames(dataori)[which(newcol==classe)]
+            colnames(dtable) <- 1:ncol(dtable)
+                       mere<-classe
+                       listcolelim<-listcol[[as.integer(classe)]]
+                       mother<-listmere[[as.integer(classe)]]
+                       while (mother!=1) {
+                               listcolelim<-append(listcolelim,listcol[[mother]])
+                               mother<-listmere[[mother]]
+                       }
+                       
+                       listcolelim<-sort(unique(listcolelim))
+                       pp('avant',ncol(dtable))
+                       if (!is.logical(listcolelim)){
+                               print('elimination colonne')
+                               #dtable<-dtable[,-listcolelim]
+                dtable<-dtable[,!(colnames(dtable) %in% listcolelim)]
+                       }
+                       pp('apres',ncol(dtable))
+                       #elimination des colonnes ne contenant que des 0
+                       print('vire colonne inf 3 dans boucle')
+                       sdt<-colSums(dtable)
+                       if (min(sdt)<=3)
+                               dtable<-dtable[,-which(sdt<=3)]
+       
+                       #elimination des lignes ne contenant que des 0
+                       print('vire ligne vide dans boucle')
+                       if (ncol(dtable)==1) {
+                               sdt<-dtable[,1]
+                       } else {
+                               sdt<-rowSums(dtable)
+                       }
+                       if (min(sdt)==0) {
+                               rowelim<-as.integer(rownames(dtable)[which(sdt==0)])
+                               print('&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&')
+                               print(rowelim)
+                               print('&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&')
+                               dtable<-dtable[-which(sdt==0),]
+                       }
+#              }
+       }
+#      sink()
+       res <- list(n1 = dout, list_mere = listmere, list_fille = list_fille)
+       res
+}
diff --git a/Rscripts/CHD.R.old b/Rscripts/CHD.R.old
new file mode 100644 (file)
index 0000000..f81e346
--- /dev/null
@@ -0,0 +1,245 @@
+#library(ca)
+#library(MASS)
+#source('/home/pierre/workspace/iramuteq/Rscripts/afc.R')
+#data<-read.table('output/corpus_bin.csv',header=TRUE,sep='\t')
+source('/home/pierre/workspace/iramuteq/Rscripts/anacor.R')
+
+CHD<-function(data,x=9){
+       dataori=data
+       dtable=data
+       listcol<-list()
+       listmere<-list()
+       a<-0
+       print('vire colonnes vides en entree')#FIXME : il ne doit pas y avoir de colonnes vides en entree !!
+       for (m in 1:length(dtable)) {
+           if (sum(dtable[m-a])==0) {
+               print('colonne vide')
+                       dtable<-dtable[,-(m-a)]
+                       a<-a+1
+           }
+    }
+       for (i in 1:x) {
+               clnb<-(i*2)
+               listmere[[clnb]]<-i
+               listmere[[clnb+1]]<-i
+               listcol[[clnb]]<-vector()
+               listcol[[clnb+1]]<-vector()
+               #extraction du premier facteur de l'afc
+               print('afc')
+               #afc<-ca(dtable,nd=1)
+               #afc<-corresp(dtable,nd=1)
+               #afc<-fca(dtable)
+               afc<-boostana(dtable,nd=1)
+               #coordonnees des colonnes sur le premier facteur
+               #coordrow=afc$rowcoord
+               #coordrow=as.matrix(afc$rscore)
+               #coordrow<-as.matrix(afc$rproj[,1])
+               coordrow<-as.matrix(afc$row.scores)
+               #row.names(coordrow)<-afc$rownames
+               row.names(coordrow)<-rownames(dtable)
+               #classement en fonction de la position sur le premier facteur
+               #listclasse<-ifelse(coordrow<0,paste('CLASSE',clnb,sep=''),paste('CLASSE',clnb+1,sep=''))
+
+               print('deb recherche meilleur partition')
+               coordrow<-as.matrix(coordrow[order(coordrow[,1]),])
+               #print(rownames(coordrow))
+               zeropoint<-which.min(abs(coordrow))
+               print(zeropoint)
+               g<-length(coordrow[coordrow[,1]<coordrow[zeropoint]])
+               d<-length(coordrow[coordrow[,1]>coordrow[zeropoint]])
+               prct<-1
+               g<-round(g*prct)
+               d<-round(d*prct)
+               print(g)
+               print(d)
+               temptable<-as.matrix(coordrow[(zeropoint-g):(zeropoint+d)])
+               row.names(temptable)<-rownames(coordrow)[(zeropoint-g):(zeropoint+d)]
+               #print(temptable)
+               missing<-zeropoint-g
+               listchi<-vector()
+               chtable<-matrix(0,2,(ncol(dtable)))
+               totforme<-chtable[1,]
+               for (forme in 1:(ncol(dtable))) {
+                       totforme[forme]<-sum(dtable[,forme])
+               }               
+               chtable[2,]<-totforme
+               for (l in 1:length(temptable)) {
+               #       print(rownames(temptable)[l])
+                       linetoswitch=as.matrix(dtable[rownames(temptable)[l],])
+               #       print(linetoswitch)
+                       chtable[1,]<-chtable[1,]+linetoswitch
+                       chtable[2,]<-chtable[2,]-linetoswitch
+                       valchi<-chisq.test(chtable)$statistic
+                       if (is.na(valchi)){
+                               valchi<-0
+                       }
+                       listchi<-append(listchi,valchi)
+               }
+               #listchi<-listchi[!is.na(listchi)]
+               maxchi<-which(listchi==max(listchi))
+               print(max(listchi))
+               print(maxchi)
+               maxchi<-maxchi+missing
+               #print(listchi)
+               #listclasse
+               print('liste classe')
+               print(coordrow[(maxchi)])
+               listclasse<-ifelse(coordrow<=coordrow[(maxchi)],clnb,clnb+1)
+#              listclasse<-ifelse(coordrow<0,clnb,clnb+1)
+               listchi<-as.matrix(listchi)
+               listchi<-cbind(listchi,temptable)
+               filename<-paste('graphechi',as.character(i))
+               filename<-paste(filename,'.jpeg')
+               jpeg(filename)
+               plot(listchi[,1]~listchi[,2])
+               abline(v=0)
+               print(coordrow[zeropoint-g])
+               abline(v=coordrow[zeropoint-g])
+               abline(v=coordrow[zeropoint+d])
+               abline(v=coordrow[(maxchi)])
+               dev.off()
+               
+               #ajout du classement au tableau
+               dtable<-transform(dtable,cl1=listclasse)
+               
+               #calcul de la specificite des colonnes
+               t1<-dtable[dtable$cl1==clnb,]
+               t2<-dtable[dtable$cl1==clnb+1,]
+               
+               for (k in 1:(ncol(dtable)-1)) {
+                       t<-matrix(0,2,2)
+                       t[1,1]<-sum(t1[,k])
+                       t[1,2]<-sum(t2[,k])
+                       t[2,1]<-nrow(t1)-t[1,1]
+                       t[2,2]<-nrow(t2)-t[1,2]
+                       chi<-chisq.test(t)
+                       if (chi$statistic>6){#FIXME : valeur a mettre en option base :2.7
+                               if (chi$expected[1,1]<t[1,1]){
+                                       listcol[[clnb+1]]<-append(listcol[[clnb+1]],k)
+                               } else {
+                                       listcol[[clnb]]<-append(listcol[[clnb]],k)
+                               }
+                       }
+               }
+               
+               #lignes concernees
+               listrownamedtable<-rownames(dtable)
+               listrownamedtable<-as.integer(listrownamedtable)
+        newcol<-vector(length=nrow(dataori))
+               #remplissage de la nouvelle colonne avec les nouvelles classes
+               print('remplissage')
+               num<-0
+               for (ligne in listrownamedtable) {
+                       num<-num+1
+                       newcol[ligne]<-as.vector(dtable$cl1[num])[1]
+               }
+               #recuperation de la classe precedante pour les cases vides
+               print('recuperation classes precedentes')
+               matori<-as.matrix(dataori)
+        if (i!=1) {
+        #    options(warn=-1)
+            for (ligne in 1:length(newcol)) {
+         #       print(newcol[ligne])
+                if (newcol[ligne]==0) { # ce test renvoie un warning
+                    newcol[ligne]<-matori[ligne,length(matori[1,])]
+                }
+            }
+         #   options(warn=0)
+        }
+               #???????????????????????????????????
+               #je ne comprends pas : j'ai vraiment besoin de faire ces deux actions  pour ajouter la nouvelle colonne aux donnees ?
+               #si je ne le fais pas, ca plante...
+               dataori<-cbind(dataori,newcol)
+               dataori<-transform(dataori,newcol=newcol)
+               #???????????????????????????????????
+               
+               #liste des noms de colonne
+               #colname<-colnames(dataori)
+               #nom de la derniere colonne
+               #colname<-colname[length(dataori)]
+               #la derniere colonne
+               colclasse<-as.character(dataori[,ncol(dataori)])
+               #print(colclasse)
+        #les modalites de la derniere colonne
+               classes<-levels(as.factor(colclasse))
+               print(classes)
+               #determination de la classe la plus grande
+               tailleclasse<-paste(NULL,1:length(classes))
+               b<-0
+               for (classe in classes) {
+                  b<-b+1
+                  dtable<-dataori[dataori[length(dataori)]==classe,]
+                  tailleclasse[b]<-length(dtable[,1])
+               }
+               tailleclasse<-as.integer(tailleclasse)
+               print(tailleclasse)
+               plusgrand<-which(tailleclasse==max(tailleclasse))
+               
+               #???????????????????????????????????
+               #Si 2 classes ont des effectifs egaux, on prend la premiere de la liste...
+               if (length(plusgrand)>1) {
+                       plusgrand<-plusgrand[1]
+               }
+               #????????????????????????????????????
+               
+               #constuction du prochain tableau a analyser
+               print('construction tableau suivant')
+               classe<-classes[plusgrand]
+               dtable<-dataori[dataori[length(dataori)]==classe,]
+               dtable<-dtable[,1:(length(dtable)-i)]
+               
+               
+               listcolelim<-listcol[[as.integer(classe)]]
+               mother<-listmere[[as.integer(classe)]]
+               while (mother!=1) {
+                       listcolelim<-append(listcolelim,listcol[[mother]])
+                       print(listcolelim)
+                       mother<-listmere[[mother]]
+               }
+               
+               listcolelim<-sort(unique(listcolelim))
+               print(listcolelim)
+               print('avant')
+               print(ncol(dtable))
+               if (!is.logical(listcolelim)){
+                       print('elimination colonne')
+                       a<-0
+                       for (col in listcolelim){
+                               dtable<-dtable[,-(col-a)]
+                               a<-a+1
+                       }
+               }
+               print('apres')
+               print(ncol(dtable))
+               #elimination des colonnes ne contenant que des 0
+               print('vire colonne vide dans boucle')
+               a<-0
+               for (m in 1:ncol(dtable)) {
+                       if (sum(dtable[,m-a])==0) {
+                               dtable<-dtable[,-(m-a)]
+                               a<-a+1
+                       }
+               }
+               #elimination des lignes ne contenant que des 0
+#              print('vire ligne vide dans boucle')
+#              a<-0
+#              for (m in 1:nrow(dtable)) {
+#                      if (sum(dtable[m-a,])==0) {
+#                              print('ligne vide')
+#                              dtable<-dtable[-(m-a),]
+#                              a<-a+1
+#                      }
+#              }
+       }
+       dataori[(length(dataori)-x+1):length(dataori)]
+}
+
+#dataout<-CHD(data,9)
+
+#library(cluster)
+#dissmat<-daisy(dataout, metric = 'gower', stand = FALSE)
+#chd<-diana(dissmat,diss=TRUE,)
+
+
+#pour tester le type, passer chaque colonne en matice et faire mode(colonne)
+#for (i in 1:13) {tmp<-as.matrix(data[i]);print(mode(tmp))}
diff --git a/Rscripts/CHDKmeans.R b/Rscripts/CHDKmeans.R
new file mode 100644 (file)
index 0000000..c0a0d01
--- /dev/null
@@ -0,0 +1,471 @@
+#Author: Pierre Ratinaud
+#Copyright (c) 2008 Pierre Ratinaud
+#Lisense: GNU/GPL
+
+
+
+#library(ca)
+#library(MASS)
+#source('/home/pierre/workspace/iramuteq/Rscripts/afc.R')
+#data<-read.table('output/corpus_bin.csv',header=TRUE,sep='\t')
+#source('/home/pierre/workspace/iramuteq/Rscripts/anacor.R')
+#library(ade4)
+pp<-function(txt,val) {
+       d<-paste(txt,' : ')
+       print(paste(d,val))
+}
+MyChiSq<-function(x,sc,n){
+       sr<-rowSums(x)
+       E <- outer(sr, sc, "*")/n
+       STAT<-sum((abs(x - E))^2/E)
+       STAT
+}
+
+CHD<-function(data,x=9){
+#      sink('/home/pierre/workspace/iramuteq/dev/findchi2.txt')
+       dataori=as.matrix(data)
+       row.names(dataori)=rownames(data)
+       dtable=as.matrix(data)
+       row.names(dtable)=rownames(data)
+       rowelim<-NULL
+       pp('ncol entree : ',ncol(dtable))
+       pp('nrow entree',nrow(dtable))
+       listcol <- list()
+       listmere <- list()
+       list_fille <- list()
+       print('vire colonnes vides en entree')#FIXME : il ne doit pas y avoir de colonnes vides en entree !!
+       sdt<-colSums(dtable)
+       if (min(sdt)==0)
+               dtable<-dtable[,-which(sdt==0)]
+       mere<-1
+       for (i in 1:x) {
+               clnb<-(i*2)
+               listmere[[clnb]]<-mere
+               listmere[[clnb+1]]<-mere
+               list_fille[[mere]] <- c(clnb,clnb+1)
+               listcol[[clnb]]<-vector()
+               listcol[[clnb+1]]<-vector()
+               #extraction du premier facteur de l'afc
+               print('afc')
+               #afc<-ca(dtable,nd=1)
+               #afc<-corresp(dtable,nd=1)
+               #afc<-fca(dtable)
+               pp('taille dtable dans boucle (col/row)',c(ncol(dtable),nrow(dtable)))
+#              afc<-boostana(dtable,nd=1)
+#              #afc<-dudi.coa(dtable,scannf=FALSE,nf=1)
+#              pp('SV',afc$singular.values)
+#              pp('V.P.', afc$eigen.values)
+#              #pp('V.P.',afc$eig[1])
+#              #pp('V.P.',afc$factexpl[1])
+#              #print(afc$chisq)
+#              afcchi<-chisq.test(dtable)
+#              Tinert<-afcchi$statistic/sum(dtable)
+#              pp('inertie totale',Tinert)
+#              #coordonnees des colonnes sur le premier facteur
+#              #coordrow=afc$rowcoord
+#              coordrow=as.matrix(afc$row.scores)
+#              #coordrow<-as.matrix(afc$rproj[,1])
+#              #coordrow<-as.matrix(afc$li)
+#              coordrowori<-coordrow
+#              #row.names(coordrow)<-afc$rownames
+#              row.names(coordrow)<-rownames(dtable)
+#              #classement en fonction de la position sur le premier facteur
+#              print('deb recherche meilleur partition')
+#              ordertable<-cbind(dtable,coordrow)
+#              coordrow<-as.matrix(coordrow[order(coordrow[,1]),])
+#              ordertable<-ordertable[order(ordertable[,ncol(ordertable)]),][,-ncol(ordertable)]
+#              listinter<-vector()
+#              listlim<-vector()
+               TT=sum(dtable)
+#              sc<-colSums(dtable)
+#              sc1<-ordertable[1,]
+#              sc2<-colSums(dtable)-ordertable[1,]
+#              chitable<-rbind(sc1,sc2)
+#              #listinter<-vector()
+#              maxinter<-0
+#              rmax<-NULL
+##################################################################
+#              for (l in 2:(nrow(dtable)-2)){
+#                      chitable[1,]<-chitable[1,]+ordertable[l,]
+#                      chitable[2,]<-chitable[2,]-ordertable[l,]
+##                     sc1<-sc1+ordertable[l,]
+##                     sc2<-sc2-ordertable[l,]
+##                     chitable<-rbind(sc1,sc2)
+#                      chi<-MyChiSq(chitable,sc,TT)
+#                      if (chi>maxinter) {
+#                              maxinter<-chi
+#                              rmax<-l
+#                      }
+#              #       listinter<-append(listinter,MyChiSq(chitable,sc,TT))#,chisq.test(chitable)$statistic/TT)
+#              }
+#              #plot(listinter)
+#              print('@@@@@@@@@@@@@@@@@@@@@@@@@@@@')
+#              pp('max inter phase 1', maxinter/TT)#max(listinter))
+#              print('@@@@@@@@@@@@@@@@@@@@@@@@@@@@')
+#              #maxinter<-which.max(listinter)+1
+#
+#              listclasse<-ifelse(coordrowori<=coordrow[(rmax),1],clnb,clnb+1)
+#              
+#              cl<-listclasse
+#
+#              pp('TT',TT)
+#              #dtable<-cbind(dtable,'cl'= as.vector(cl))
+#
+#              N1<-length(listclasse[listclasse==clnb])
+#              N2<-length(listclasse[listclasse==clnb+1])
+#              pp('N1',N1)
+#              pp('N2',N2)
+####################################################################
+##                  reclassement des individus                     #
+####################################################################
+#              malcl<-1000000000000
+#              it<-0
+#              listsub<-list()
+#              #in boucle
+#
+#              while (malcl!=0 & N1>=5 & N2>=5) {
+#                      it<-it+1
+#                      listsub[[it]]<-vector()
+#                      pp('nombre iteration',it)
+#                      vdelta<-vector()
+#                      #dtable[,'cl']<-cl
+#                      t1<-dtable[cl==clnb,]#[,-ncol(dtable)]
+#                      t2<-dtable[cl==clnb+1,]#[,-ncol(dtable)]
+#                      ncolt<-ncol(t1)
+#                      pp('ncolt',ncolt)
+#                      sc1<-colSums(t1)
+#                      sc2<-colSums(t2)
+#                      sc<-sc1+sc2
+#                      TT<-sum(dtable)
+#                      chtableori<-rbind(sc1,sc2)
+#                      interori<-MyChiSq(chtableori,sc,TT)/TT#chisq.test(chtableori)$statistic#/TT
+#                      chtable<-chtableori
+#                      pp('interori',interori)
+#                      N1<-nrow(t1)
+#                      N2<-nrow(t2)
+#                      pp('N1',N1)
+#                      pp('N2',N2)
+#                      
+#                      for (l in 1:nrow(dtable)){
+#                                      if(cl[l]==clnb){
+#                                              chtable[1,]<-sc1-dtable[l,]
+#                                              chtable[2,]<-sc2+dtable[l,]
+#                                      }else{
+#                                              chtable[1,]<-sc1+dtable[l,]
+#                                              chtable[2,]<-sc2-dtable[l,]
+#                                      }
+#                                      interswitch<-MyChiSq(chtable,sc,TT)/TT#chisq.test(chtable)$statistic/TT
+#                                      ws<-interori-interswitch
+#
+#                                      if (ws<0){
+#                                              interori<-interswitch
+#                                              if(cl[l]==clnb){
+#                                                      sc1<-chtable[1,]
+#                                                      sc2<-chtable[2,]
+#                                                      cl[l]<-clnb+1
+#                                                      listsub[[it]]<-append(listsub[[it]],l)
+#                                              }else{
+#                                                      sc1<-chtable[1,]
+#                                                      sc2<-chtable[2,]
+#                                                      cl[l]<-clnb
+#                                                      listsub[[it]]<-append(listsub[[it]],l)
+#                                              }
+#                                              vdelta<-append(vdelta,l)
+#                                      }
+#                              }
+##                     for (val in vdelta) {
+##                             if (cl[val]==clnb) {
+##                                     cl[val]<-clnb+1
+##                                     listsub[[it]]<-append(listsub[[it]],val)
+##                                     }else {
+##                                     cl[val]<-clnb
+##                                     listsub[[it]]<-append(listsub[[it]],val)
+##                             }
+##                     }
+#                      print('###################################')
+#                      print('longueur < 0')
+#                      malcl<-length(vdelta)
+#                      if ((it>1)&&(!is.logical(listsub[[it]]))){
+#                              if (listsub[[it]]==listsub[[(it-1)]]){
+#                                      malcl<-0
+#                              }
+#                      }
+#                      print(malcl)
+#                      print('###################################')
+#              }
+##########################################################################
+# kmeans
+#        clori<-kmeans(dtable,2)$cluster
+#        cl<-ifelse(clori==1,clnb,clnb+1)
+#pam
+        library(cluster)
+        clori<-pam(dist(dtable,method='binary'),2,diss=TRUE)$cluster
+        cl<-ifelse(clori==1,clnb,clnb+1)
+        
+            dtable<-cbind(dtable,'cl'=as.vector(cl))
+
+#######################################################################
+#                 Fin reclassement des individus                      #
+#######################################################################
+#              if (!(length(cl[cl==clnb])==1 || length(cl[cl==clnb+1])==1)) {
+                       t1<-dtable[dtable[,'cl']==clnb,][,-ncol(dtable)]
+                       t2<-dtable[dtable[,'cl']==clnb+1,][,-ncol(dtable)]
+               
+                       chtable<-rbind(colSums(t1),colSums(t2))
+                       inter<-chisq.test(chtable)$statistic/TT
+                       pp('last inter',inter)
+                       print('=====================')
+                       
+                       #calcul de la specificite des colonnes
+                       mint<-min(nrow(t1),nrow(t2))
+                       maxt<-max(nrow(t1),nrow(t2))
+                       seuil<-round((1.9*(maxt/mint))+1.9,digit=6)
+                       #sink('/home/pierre/workspace/iramuteq/dev/findchi2.txt')
+#                      print('ATTENTION SEUIL 3,84')
+#                      seuil<-3.84
+                       pp('seuil',seuil)
+                       sominf<-0
+                       nv<-0
+                       nz<-0
+                       ncclnb<-0
+                       ncclnbp<-0
+            NN1<-0
+            NN2<-0
+            maxchip<-0
+            nbzeroun<-0
+            res1<-0
+            res2<-0
+            nbseuil<-0
+            nbexe<-0
+            nbcontrib<-0
+                       cn<-colnames(dtable)[1:(ncol(dtable)-1)]
+                       for (k in 1:(ncol(dtable)-1)) {
+                               #print(k)
+                               tab<-table(dtable[,k],dtable[,ncol(dtable)])
+                               #print(cn[k])
+                               #print (tab)
+                               #chidemoi<-(sum(t)*(((t[1,1]*t[2,2])-(t[1,2]*t[2,1]))^2))/((rowSums(t)[1])*(rowSums(t)[2])*(colSums(t)[1])*(colSums(t)[2]))
+                               if (rownames(tab)[1]==1 & nrow(tab)==1) {
+                                       tab<-rbind(c(0,0),tab[1])
+                                       print('tableau vide dessus')
+                               }
+                               if (min(tab)<=10){
+                                       chi<-chisq.test(tab,correct=TRUE)
+                               }else{
+                                       chi<-chisq.test(tab,correct=FALSE)
+                               }
+                               if ((min(tab[2,])==1) & (min(tab[1,])!=0)){
+                                       chi$statistic<-seuil+1
+                               #    print('min tab 2 == 0')    
+                               }
+#                if(((tab[2,1]>tab[1,1]) & (tab[2,2]>tab[1,2]))){
+#                                      nz<-nz+1
+#                                      chi$statistic<-seuil-1
+#                                      sominf<-sominf-1
+#                              }
+                if ((min(tab[1,])==0) & (min(tab[2,])!=0)){
+                                       chi$statistic<-seuil-1
+                #    print('min tab 1 == 0')
+                               }
+                               if (is.na(chi$statistic)) {
+                                       chi$statistic<-0
+                                       print('NA dans chi$statistic')
+                               }
+#                              print('#####################')
+                               if (chi$statistic>seuil){
+                               i#      print('sup seuil')
+                                       if (tab[2,1]<chi$expected[2,1]){
+                                               listcol[[clnb]]<-append(listcol[[clnb]],cn[k])
+                                               ncclnb<-ncclnb+1
+#                                              print('@@@@@@@@specifique de la classe@@@@@@')
+#                                              print(clnb)
+                                       } else if (tab[2,2]<chi$expected[2,2]){
+                                               listcol[[clnb+1]]<-append(listcol[[clnb+1]],cn[k])
+                                               ncclnbp<-ncclnbp+1
+#                                              print('@@@@@@@@specifique de la classe@@@@@@')
+#                                              print(clnb+1)
+                                       }
+                               }
+#                              if (chi$statistic<seuil){
+#                                      print('inf seuil')
+#                                      print(tab)
+#                                      print(chi$expected)
+#                                      print(chi$statistic)
+#                                      sominf<-sominf+1
+#                              }
+                               
+#                              print('tableau')
+#                              print(tab)
+#                              chi<-chisq.test(tab,correct=FALSE)
+#                              print('sans correction')
+#                              print(chi$statistic)
+#                              print(chi$expected)
+#                              print(chi$residuals)
+#                chit<-((tab-chi$expected)^2)/chi$expected
+#                print(mean(chi$residuals))
+#                print(sd(as.vector(chi$residuals)))
+                #print(chi$residuals/sd(as.vector(chi$residuals)))
+                #print(abs(chi$residuals/sd(as.vector(chi$residuals))))
+                #print(qnorm(abs(chi$residuals/sd(as.vector(chi$residuals)))))
+#                difftab<-tab-chi$expected
+ #               print('contribution')
+                #print((difftab-mean(difftab))/sd(as.vector(difftab)))
+                #print(abs((chit-mean(chit))/sd(as.vector(chit))))
+#                tabin1<-matrix(1,2,2)
+#                tabin1<-tabin1-(colSums(tab)/sum(tab))
+#                tabin2<-matrix(1,2,2)
+#                tabin2<-(tabin2-(rowSums(tab)/sum(tab)))
+#                tabinv<-tabin1*tabin2
+#                CS<-colSums(tab)
+#                RS<-rowSums(tab)
+#                GT<-sum(tab)
+#                print(tabinv)
+#                contrib<-(tab-chi$expected)/sqrt(chi$expected * ((1 - RS/GT) %*% t(1 - CS/GT)))
+#                print(chit)
+#                print('TTTTTTTTTTTTTTTTTTTTTTTTTTTTTT')
+#                print(contrib)
+#                if (((which.max(chit)==2) || (which.max(chit)==4)) & chi$statistic>=seuil) {
+#                    if (which.max(chit)==2) NN1<-NN1+1
+#                    if (which.max(chit)==4) NN2<-NN2+1
+#                }
+#                if (max(abs(contrib[2,])>=1.96)) {
+#                    nbcontrib<-nbcontrib+1
+#                }
+#                if (max(chit[2,]>=seuil)) maxchip<-maxchip+1
+#                if (chi$statistic >=seuil) nbseuil<-nbseuil+1
+#                if ((min(tab[2,])==0) & (chi$statistic<seuil)) nbzeroun<-nbzeroun+1
+#                if ((((which.max(chi$residual)==2) || (which.max(chi$residual)==4) || (which.min(chi$residual)==2) || (which.min(chi$residual)==4))) & chi$statistic>=seuil) {
+#                    if ((which.max(chi$residual)==2) || (which.min(chi$residual)==4)) res1<-res1+1
+#                    if ((which.max(chi$residual)==4) || (which.min(chi$residual)==2)) res2<-res2+1
+#                } else if (!((which.max(chi$residual)==2) || (which.max(chi$residual)==4) || (which.min(chi$residual)==2) || (which.min(chi$residual)==4)) & chi$statistic>=seuil) {
+#                    print('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA')
+#                    print('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA')
+#                }
+#                if (length(unique(as.vector(chi$residual)))==2) {
+#                    nbexe<-nbexe+1
+#                }
+
+#                              print('avec correction')
+#                if (min(tab)<5) chi<-chisq.test(tab,correct=TRUE)
+#                              print(chi$statistic)
+#                #if (chi$statistic >=seuil) nbseuil<-nbseuil+1
+#                              print(chi$expected)
+#                              print(chi$residuals)
+#                chit<-((abs(tab-chi$expected)-0.5)^2)/chi$expected
+#                print(chit)
+#                              print('#####################')
+                       }
+#            pp('NN1',NN1)
+#            pp('NN2',NN2)
+#            pp('maxchip',maxchip)
+#            pp('nbzeroun',nbzeroun)
+#            pp('res1',res1)
+#            pp('res2',res2)
+#            pp('nbseuil',nbseuil)
+#            pp('nbexe',nbexe)
+#            pp('nbcontrib', nbcontrib)
+                       print('resultats elim item')
+                       pp(clnb+1,length(listcol[[clnb+1]]))
+                       pp(clnb,length(listcol[[clnb]]))
+#                      pp('inf seuil',sominf)
+#                      pp('nv',nv)
+                       pp('ncclnb',ncclnb)
+                       pp('ncclnbp',ncclnbp)
+#                      pp('nz',nz)
+                       #sink()
+                       #lignes concernees
+                       listrownamedtable<-rownames(dtable)
+                       listrownamedtable<-as.integer(listrownamedtable)
+                       newcol<-vector(length=nrow(dataori))
+                       #remplissage de la nouvelle colonne avec les nouvelles classes
+                       print('remplissage')
+                       num<-0
+                       for (ligne in listrownamedtable) {
+                               num<-num+1
+                               newcol[ligne]<-as.integer(as.vector(dtable[,'cl'][num])[1])
+                       }
+                       #recuperation de la classe precedante pour les cases vides
+                       print('recuperation classes precedentes')
+                       matori<-as.matrix(dataori)
+                       if (i!=1) {
+                               #    options(warn=-1)
+                               for (ligne in 1:length(newcol)) {
+                                       #       print(newcol[ligne])
+                                       if (newcol[ligne]==0) { # ce test renvoie un warning
+                                               if (ligne %in% rowelim){
+                                                       newcol[ligne]<-0
+                                               } else {
+                                                       newcol[ligne]<-matori[ligne,length(matori[1,])]
+                                               }
+                                               
+                                       }
+                               }
+                               #   options(warn=0)
+                       }
+                       dataori<-cbind(dataori,newcol)
+                       
+                       tailleclasse<-as.matrix(summary(as.factor(as.character(dataori[,ncol(dataori)]))))
+                       #tailleclasse<-as.integer(tailleclasse)
+                       print('tailleclasse')
+                       print(tailleclasse)
+                       tailleclasse<-as.matrix(tailleclasse[!(rownames(tailleclasse)==0),])
+                       plusgrand<-which.max(tailleclasse)
+                       #???????????????????????????????????
+                       #Si 2 classes ont des effectifs egaux, on prend la premiere de la liste...
+                       if (length(plusgrand)>1) {
+                               plusgrand<-plusgrand[1]
+                       }
+                       #????????????????????????????????????
+                       
+                       #constuction du prochain tableau a analyser
+                       print('construction tableau suivant')
+                       classe<-as.integer(rownames(tailleclasse)[plusgrand])
+                       dtable<-dataori[dataori[,ncol(dataori)]==classe,]
+                       row.names(dtable)<-rownames(dataori[dataori[,ncol(dataori)]==classe,])
+                       dtable<-dtable[,1:(ncol(dtable)-i)]
+                       mere<-classe
+                       listcolelim<-listcol[[as.integer(classe)]]
+                       mother<-listmere[[as.integer(classe)]]
+                       while (mother!=1) {
+                               listcolelim<-append(listcolelim,listcol[[mother]])
+                               mother<-listmere[[mother]]
+                       }
+                       
+                       listcolelim<-sort(unique(listcolelim))
+                       pp('avant',ncol(dtable))
+                       if (!is.logical(listcolelim)){
+                               print('elimination colonne')
+                               #dtable<-dtable[,-listcolelim]
+&n