[doc] use sphinx-quickstart to make doc configuration modern
authorLaurent Peuch <cortex@worlddomination.be>
Fri, 13 Dec 2019 05:54:11 +0100
changeset 879 ad238b4d3e9a
parent 878 a55f15c5693b
child 880 f153b0b4e67c
[doc] use sphinx-quickstart to make doc configuration modern
docs/.static/logilab.png
docs/.static/sphinx-default.css
docs/.templates/layout.html
docs/Makefile
docs/canonisation.rst
docs/canonisation.txt
docs/conf.py
docs/index.rst
docs/index.txt
docs/make.bat
docs/rql.rst
docs/rql_windows.rst
docs/rql_windows.txt
docs/specifications_en.rst
docs/specifications_en.txt
docs/specifications_fr.rst
docs/specifications_fr.txt
docs/tutorial_en.rst
docs/tutorial_en.txt
docs/tutoriel_fr.rst
docs/tutoriel_fr.txt
Binary file docs/.static/logilab.png has changed
--- a/docs/.static/sphinx-default.css	Fri Dec 13 05:36:22 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,860 +0,0 @@
-/**
- * Sphinx Doc Design
- */
-
-html, body {
-    background: white;	
-}
-
-body {
-    font-family: Verdana, sans-serif;
-    font-size: 100%;
-    background-color: white;
-    color: black;
-    margin: 0;
-    padding: 0;
-}
-
-/* :::: LAYOUT :::: */
-
-div.logilablogo {
-    padding: 10px 10px 10px 10px;
-    height:75;
-}
-
-
-div.document {
-    background-color: white;
-}
-
-div.documentwrapper {
-    float: left;
-    width: 100%;
-}
-
-div.bodywrapper {
-    margin: 0 0 0 230px;
-}
-
-div.body {
-    background-color: white;
-    padding: 0 20px 30px 20px;
-    border-left:solid;
-    border-left-color:#e2e2e2;
-    border-left-width:thin;
-}
-
-div.sphinxsidebarwrapper {
-    padding: 10px 5px 0 10px;
-}
-
-div.sphinxsidebar {
-    float: left;
-    width: 230px;
-    margin-left: -100%;
-    font-size: 90%;
-}
-
-div.clearer {
-    clear: both;
-}
-
-div.footer {
-    color: #ff4500;
-    width: 100%;
-    padding: 9px 0 9px 0;
-    text-align: center;
-    font-size: 75%;
-}
-
-div.footer a {
-    color: #ff4500;
-    text-decoration: underline;
-}
-
-div.related {
-    background-color: #ff7700;
-    color: white;
-    width: 100%;
-    height: 30px;
-    line-height: 30px;
-    font-size: 90%;
-}
-
-div.related h3 {
-    display: none;
-}
-
-div.related ul {
-    margin: 0;
-    padding: 0 0 0 10px;
-    list-style: none;
-}
-
-div.related li {
-    display: inline;
-}
-
-div.related li.right {
-    float: right;
-    margin-right: 5px;
-}
-
-div.related a {
-    color: white;
-    font-weight:bold;
-}
-
-/* ::: TOC :::: */
-
-div.sphinxsidebar {
-    border-style:solid;
-    border-color: white;
-/*    background-color:#e2e2e2;*/
-    padding-bottom:5px;
-}
-
-div.sphinxsidebar h3 {
-    font-family: 'Verdanda', sans-serif;
-    color: black;
-    font-size: 1.2em;
-    font-weight: normal;
-    margin: 0;
-    padding: 0;
-    font-weight:bold;
-    font-style:italic;
-}
-
-div.sphinxsidebar h4 {
-    font-family: 'Verdana', sans-serif;
-    color: black;
-    font-size: 1.1em;
-    font-weight: normal;
-    margin: 5px 0 0 0;
-    padding: 0;
-    font-weight:bold;
-    font-style:italic;
-}
-
-div.sphinxsidebar p {
-    color: black;
-}
-
-div.sphinxsidebar p.topless {
-    margin: 5px 10px 10px 10px;
-}
-
-div.sphinxsidebar ul {
-    margin: 10px;
-    padding: 0;
-    list-style: none;
-    color: black;
-}
-
-div.sphinxsidebar ul ul,
-div.sphinxsidebar ul.want-points {
-    margin-left: 20px;
-    list-style: square;
-}
-
-div.sphinxsidebar ul ul {
-    margin-top: 0;
-    margin-bottom: 0;
-}
-
-div.sphinxsidebar a {
-    color: black;
-}
-
-div.sphinxsidebar form {
-    margin-top: 10px;
-}
-
-div.sphinxsidebar input {
-    border: 1px solid #e2e2e2;
-    font-family: sans-serif;
-    font-size: 1em;
-    padding-bottom: 5px;
-}
-
-/* :::: MODULE CLOUD :::: */
-div.modulecloud {
-    margin: -5px 10px 5px 10px;
-    padding: 10px;
-    line-height: 160%;
-    border: 1px solid #cbe7e5;
-    background-color: #f2fbfd;
-}
-
-div.modulecloud a {
-    padding: 0 5px 0 5px;
-}
-
-/* :::: SEARCH :::: */
-ul.search {
-    margin: 10px 0 0 20px;
-    padding: 0;
-}
-
-ul.search li {
-    padding: 5px 0 5px 20px;
-    background-image: url(file.png);
-    background-repeat: no-repeat;
-    background-position: 0 7px;
-}
-
-ul.search li a {
-    font-weight: bold;
-}
-
-ul.search li div.context {
-    color: #888;
-    margin: 2px 0 0 30px;
-    text-align: left;
-}
-
-ul.keywordmatches li.goodmatch a {
-    font-weight: bold;
-}
-
-/* :::: COMMON FORM STYLES :::: */
-
-div.actions {
-    padding: 5px 10px 5px 10px;
-    border-top: 1px solid #cbe7e5;
-    border-bottom: 1px solid #cbe7e5;
-    background-color: #e0f6f4;
-}
-
-form dl {
-    color: #333;
-}
-
-form dt {
-    clear: both;
-    float: left;
-    min-width: 110px;
-    margin-right: 10px;
-    padding-top: 2px;
-}
-
-input#homepage {
-    display: none;
-}
-
-div.error {
-    margin: 5px 20px 0 0;
-    padding: 5px;
-    border: 1px solid #d00;
-    font-weight: bold;
-}
-
-/* :::: INLINE COMMENTS :::: */
-
-div.inlinecomments {
-    position: absolute;
-    right: 20px;
-}
-
-div.inlinecomments a.bubble {
-    display: block;
-    float: right;
-    background-image: url(style/comment.png);
-    background-repeat: no-repeat;
-    width: 25px;
-    height: 25px;
-    text-align: center;
-    padding-top: 3px;
-    font-size: 0.9em;
-    line-height: 14px;
-    font-weight: bold;
-    color: black;
-}
-
-div.inlinecomments a.bubble span {
-    display: none;
-}
-
-div.inlinecomments a.emptybubble {
-    background-image: url(style/nocomment.png);
-}
-
-div.inlinecomments a.bubble:hover {
-    background-image: url(style/hovercomment.png);
-    text-decoration: none;
-    color: #3ca0a4;
-}
-
-div.inlinecomments div.comments {
-    float: right;
-    margin: 25px 5px 0 0;
-    max-width: 50em;
-    min-width: 30em;
-    border: 1px solid #2eabb0;
-    background-color: #f2fbfd;
-    z-index: 150;
-}
-
-div#comments {
-    border: 1px solid #2eabb0;
-    margin-top: 20px;
-}
-
-div#comments div.nocomments {
-    padding: 10px;
-    font-weight: bold;
-}
-
-div.inlinecomments div.comments h3,
-div#comments h3 {
-    margin: 0;
-    padding: 0;
-    background-color: #2eabb0;
-    color: white;
-    border: none;
-    padding: 3px;
-}
-
-div.inlinecomments div.comments div.actions {
-    padding: 4px;
-    margin: 0;
-    border-top: none;
-}
-
-div#comments div.comment {
-    margin: 10px;
-    border: 1px solid #2eabb0;
-}
-
-div.inlinecomments div.comment h4,
-div.commentwindow div.comment h4,
-div#comments div.comment h4 {
-    margin: 10px 0 0 0;
-    background-color: #2eabb0;
-    color: white;
-    border: none;
-    padding: 1px 4px 1px 4px;
-}
-
-div#comments div.comment h4 {
-    margin: 0;
-}
-
-div#comments div.comment h4 a {
-    color: #d5f4f4;
-}
-
-div.inlinecomments div.comment div.text,
-div.commentwindow div.comment div.text,
-div#comments div.comment div.text {
-    margin: -5px 0 -5px 0;
-    padding: 0 10px 0 10px;
-}
-
-div.inlinecomments div.comment div.meta,
-div.commentwindow div.comment div.meta,
-div#comments div.comment div.meta {
-    text-align: right;
-    padding: 2px 10px 2px 0;
-    font-size: 95%;
-    color: #538893;
-    border-top: 1px solid #cbe7e5;
-    background-color: #e0f6f4;
-}
-
-div.commentwindow {
-    position: absolute;
-    width: 500px;
-    border: 1px solid #cbe7e5;
-    background-color: #f2fbfd;
-    display: none;
-    z-index: 130;
-}
-
-div.commentwindow h3 {
-    margin: 0;
-    background-color: #2eabb0;
-    color: white;
-    border: none;
-    padding: 5px;
-    font-size: 1.5em;
-    cursor: pointer;
-}
-
-div.commentwindow div.actions {
-    margin: 10px -10px 0 -10px;
-    padding: 4px 10px 4px 10px;
-    color: #538893;
-}
-
-div.commentwindow div.actions input {
-    border: 1px solid #2eabb0;
-    background-color: white;
-    color: #135355;
-    cursor: pointer;
-}
-
-div.commentwindow div.form {
-    padding: 0 10px 0 10px;
-}
-
-div.commentwindow div.form input,
-div.commentwindow div.form textarea {
-    border: 1px solid #3c9ea2;
-    background-color: white;
-    color: black;
-}
-
-div.commentwindow div.error {
-    margin: 10px 5px 10px 5px;
-    background-color: #fbe5dc;
-    display: none;
-}
-
-div.commentwindow div.form textarea {
-    width: 99%;
-}
-
-div.commentwindow div.preview {
-    margin: 10px 0 10px 0;
-    background-color: #70d0d4;
-    padding: 0 1px 1px 25px;
-}
-
-div.commentwindow div.preview h4 {
-    margin: 0 0 -5px -20px;
-    padding: 4px 0 0 4px;
-    color: white;
-    font-size: 1.3em;
-}
-
-div.commentwindow div.preview div.comment {
-    background-color: #f2fbfd;
-}
-
-div.commentwindow div.preview div.comment h4 {
-    margin: 10px 0 0 0!important;
-    padding: 1px 4px 1px 4px!important;
-    font-size: 1.2em;
-}
-
-/* :::: SUGGEST CHANGES :::: */
-div#suggest-changes-box input, div#suggest-changes-box textarea {
-    border: 1px solid #ccc;
-    background-color: white;
-    color: black;
-}
-
-div#suggest-changes-box textarea {
-    width: 99%;
-    height: 400px;
-}
-
-
-/* :::: PREVIEW :::: */
-div.preview {
-    background-image: url(style/preview.png);
-    padding: 0 20px 20px 20px;
-    margin-bottom: 30px;
-}
-
-
-/* :::: INDEX PAGE :::: */
-
-table.contentstable {
-    width: 90%;
-}
-
-table.contentstable p.biglink {
-    line-height: 150%;
-}
-
-a.biglink {
-    font-size: 1.3em;
-}
-
-span.linkdescr {
-    font-style: italic;
-    padding-top: 5px;
-    font-size: 90%;
-}
-
-/* :::: INDEX STYLES :::: */
-
-table.indextable td {
-    text-align: left;
-    vertical-align: top;
-}
-
-table.indextable dl, table.indextable dd {
-    margin-top: 0;
-    margin-bottom: 0;
-}
-
-table.indextable tr.pcap {
-    height: 10px;
-}
-
-table.indextable tr.cap {
-    margin-top: 10px;
-    background-color: #f2f2f2;
-}
-
-img.toggler {
-    margin-right: 3px;
-    margin-top: 3px;
-    cursor: pointer;
-}
-
-form.pfform {
-    margin: 10px 0 20px 0;
-}
-
-/* :::: GLOBAL STYLES :::: */
-
-.docwarning {
-    background-color: #ffe4e4;
-    padding: 10px;
-    margin: 0 -20px 0 -20px;
-    border-bottom: 1px solid #f66;
-}
-
-p.subhead {
-    font-weight: bold;
-    margin-top: 20px;
-}
-
-a {
-    color: black;
-    text-decoration: none;
-}
-
-a:hover {
-    text-decoration: underline;
-}
-
-div.body h1,
-div.body h2,
-div.body h3,
-div.body h4,
-div.body h5,
-div.body h6 {
-    font-family: 'Verdana', sans-serif;
-    background-color: white;
-    font-weight: bold;
-    color: black;
-    border-bottom: 1px solid #ccc;
-    margin: 20px -20px 10px -20px;
-    padding: 3px 0 3px 10px;
-}
-
-div.body h1 { margin-top: 0; font-size: 200%; }
-div.body h2 { font-size: 160%; }
-div.body h3 { font-size: 120%; }
-div.body h4 { font-size: 100%; }
-div.body h5 { font-size: 90%; }
-div.body h6 { font-size: 70%; }
-
-a.headerlink {
-    color: #c60f0f;
-    font-size: 0.8em;
-    padding: 0 4px 0 4px;
-    text-decoration: none;
-    visibility: hidden;
-}
-
-h1:hover > a.headerlink,
-h2:hover > a.headerlink,
-h3:hover > a.headerlink,
-h4:hover > a.headerlink,
-h5:hover > a.headerlink,
-h6:hover > a.headerlink,
-dt:hover > a.headerlink {
-    visibility: visible;
-}
-
-a.headerlink:hover {
-    background-color: #c60f0f;
-    color: white;
-}
-
-div.body p, div.body dd, div.body li {
-    text-align: justify;
-    line-height: 130%;
-}
-
-div.body p.caption {
-    text-align: inherit;
-}
-
-div.body td {
-    text-align: left;
-}
-
-ul.fakelist {
-    list-style: none;
-    margin: 10px 0 10px 20px;
-    padding: 0;
-}
-
-.field-list ul {
-    padding-left: 1em;
-}
-
-.first {
-    margin-top: 0 !important;
-}
-
-/* "Footnotes" heading */
-p.rubric {
-    margin-top: 30px;
-    font-weight: bold;
-}
-
-/* "Topics" */
-
-div.topic {
-    background-color: #eee;
-    border: 1px solid #ccc;
-    padding: 0 7px 0 7px;
-    margin: 10px 0 10px 0;
-}
-
-p.topic-title {
-    font-size: 1.1em;
-    font-weight: bold;
-    margin-top: 10px;
-}
-
-/* Admonitions */
-
-div.admonition {
-    margin-top: 10px;
-    margin-bottom: 10px;
-    padding: 7px;
-}
-
-div.admonition dt {
-    font-weight: bold;
-}
-
-div.admonition dl {
-    margin-bottom: 0;
-}
-
-div.admonition p {
-    display: inline;
-}
-
-div.seealso {
-    background-color: #ffc;
-    border: 1px solid #ff6;
-}
-
-div.warning {
-    background-color: #ffe4e4;
-    border: 1px solid #f66;
-}
-
-div.note {
-    background-color: #eee;
-    border: 1px solid #ccc;
-}
-
-p.admonition-title {
-    margin: 0px 10px 5px 0px;
-    font-weight: bold;
-    display: inline;
-}
-
-p.admonition-title:after {
-    content: ":";
-}
-
-div.body p.centered {
-    text-align: center;
-    margin-top: 25px;
-}
-
-table.docutils {
-    border: 0;
-}
-
-table.docutils td, table.docutils th {
-    padding: 1px 8px 1px 0;
-    border-top: 0;
-    border-left: 0;
-    border-right: 0;
-    border-bottom: 1px solid #aaa;
-}
-
-table.field-list td, table.field-list th {
-    border: 0 !important;
-}
-
-table.footnote td, table.footnote th {
-    border: 0 !important;
-}
-
-.field-list ul {
-    margin: 0;
-    padding-left: 1em;
-}
-
-.field-list p {
-    margin: 0;
-}
-
-dl {
-    margin-bottom: 15px;
-    clear: both;
-}
-
-dd p {
-    margin-top: 0px;
-}
-
-dd ul, dd table {
-    margin-bottom: 10px;
-}
-
-dd {
-    margin-top: 3px;
-    margin-bottom: 10px;
-    margin-left: 30px;
-}
-
-.refcount {
-    color: #060;
-}
-
-dt:target,
-.highlight {
-    background-color: #fbe54e;
-}
-
-dl.glossary dt {
-    font-weight: bold;
-    font-size: 1.1em;
-}
-
-th {
-    text-align: left;
-    padding-right: 5px;
-}
-
-pre {
-    padding: 5px;
-    background-color: #efc;
-    color: #333;
-    border: 1px solid #ac9;
-    border-left: none;
-    border-right: none;
-    overflow: auto;
-}
-
-td.linenos pre {
-    padding: 5px 0px;
-    border: 0;
-    background-color: transparent;
-    color: #aaa;
-}
-
-table.highlighttable {
-    margin-left: 0.5em;
-}
-
-table.highlighttable td {
-    padding: 0 0.5em 0 0.5em;
-}
-
-tt {
-    background-color: #ecf0f3;
-    padding: 0 1px 0 1px;
-    font-size: 0.95em;
-}
-
-tt.descname {
-    background-color: transparent;
-    font-weight: bold;
-    font-size: 1.2em;
-}
-
-tt.descclassname {
-    background-color: transparent;
-}
-
-tt.xref, a tt {
-    background-color: transparent;
-    font-weight: bold;
-}
-
-.footnote:target  { background-color: #ffa }
-
-h1 tt, h2 tt, h3 tt, h4 tt, h5 tt, h6 tt {
-    background-color: transparent;
-}
-
-.optional {
-    font-size: 1.3em;
-}
-
-.versionmodified {
-    font-style: italic;
-}
-
-form.comment {
-    margin: 0;
-    padding: 10px 30px 10px 30px;
-    background-color: #eee;
-}
-
-form.comment h3 {
-    background-color: #326591;
-    color: white;
-    margin: -10px -30px 10px -30px;
-    padding: 5px;
-    font-size: 1.4em;
-}
-
-form.comment input,
-form.comment textarea {
-    border: 1px solid #ccc;
-    padding: 2px;
-    font-family: sans-serif;
-    font-size: 100%;
-}
-
-form.comment input[type="text"] {
-    width: 240px;
-}
-
-form.comment textarea {
-    width: 100%;
-    height: 200px;
-    margin-bottom: 10px;
-}
-
-.system-message {
-    background-color: #fda;
-    padding: 5px;
-    border: 3px solid red;
-}
-
-/* :::: PRINT :::: */
-@media print {
-    div.document,
-    div.documentwrapper,
-    div.bodywrapper {
-        margin: 0;
-        width : 100%;
-    }
-
-    div.sphinxsidebar,
-    div.related,
-    div.footer,
-    div#comments div.new-comment-box,
-    #top-link {
-        display: none;
-    }
-}
--- a/docs/.templates/layout.html	Fri Dec 13 05:36:22 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,195 +0,0 @@
-{%- block doctype -%}
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-  "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-{%- endblock %}
-{%- set reldelim1 = reldelim1 is not defined and ' &raquo;' or reldelim1 %}
-{%- set reldelim2 = reldelim2 is not defined and ' |' or reldelim2 %}
-{%- macro relbar() %}
-    <div class="related">
-      <h3>Navigation</h3>
-      <ul>
-        {%- for rellink in rellinks %}
-        <li class="right" {% if loop.first %}style="margin-right: 10px"{% endif %}>
-          <a href="{{ pathto(rellink[0]) }}" title="{{ rellink[1]|striptags }}"
-             accesskey="{{ rellink[2] }}">{{ rellink[3] }}</a>
-          {%- if not loop.first %}{{ reldelim2 }}{% endif %}</li>
-        {%- endfor %}
-        {%- block rootrellink %}
-        <li><a href="{{ pathto('index') }}">{{ shorttitle }}</a>{{ reldelim1 }}</li>
-        {%- endblock %}
-        {%- for parent in parents %}
-          <li><a href="{{ parent.link|e }}" accesskey="U">{{ parent.title }}</a>{{ reldelim1 }}</li>
-        {%- endfor %}
-        {%- block relbaritems %}{% endblock %}
-      </ul>
-    </div>
-{%- endmacro %}
-{%- macro sidebar() %}
-      {%- if builder != 'htmlhelp' %}
-      <div class="sphinxsidebar">
-        <div class="sphinxsidebarwrapper">
-          {%- block sidebarlogo %}
-          {%- if logo %}
-            <p class="logo"><img class="logo" src="{{ pathto('_static/' + logo, 1) }}" alt="Logo"/></p>
-          {%- endif %}
-          {%- endblock %}
-          {%- block sidebartoc %}
-          {%- if display_toc %}
-            <h3>Table Of Contents</h3>
-            {{ toc }}
-          {%- endif %}
-          {%- endblock %}
-          {%- block sidebarrel %}
-          {%- if prev %}
-            <h4>Previous topic</h4>
-            <p class="topless"><a href="{{ prev.link|e }}" title="previous chapter">{{ prev.title }}</a></p>
-          {%- endif %}
-          {%- if next %}
-            <h4>Next topic</h4>
-            <p class="topless"><a href="{{ next.link|e }}" title="next chapter">{{ next.title }}</a></p>
-          {%- endif %}
-          {%- endblock %}
-          {%- if sourcename %}
-            <h3>This Page</h3>
-            <ul class="this-page-menu">
-            {%- if builder == 'web' %}
-              <li><a href="#comments">Comments ({{ comments|length }} so far)</a></li>
-              <li><a href="{{ pathto('@edit/' + sourcename)|e }}">Suggest Change</a></li>
-              <li><a href="{{ pathto('@source/' + sourcename)|e }}">Show Source</a></li>
-            {%- elif builder == 'html' %}
-              <li><a href="{{ pathto('_sources/' + sourcename, true)|e }}">Show Source</a></li>
-            {%- endif %}
-            </ul>
-          {%- endif %}
-          {%- if customsidebar %}
-          {{ rendertemplate(customsidebar) }}
-          {%- endif %}
-          {%- block sidebarsearch %}
-          {%- if pagename != "search" %}
-            <h3>{{ builder == 'web' and 'Keyword' or 'Quick' }} search</h3>
-            <form class="search" action="{{ pathto('search') }}" method="get">
-              <input type="text" name="q" size="18" /> <input type="submit" value="Go" />
-              <input type="hidden" name="check_keywords" value="yes" />
-              <input type="hidden" name="area" value="default" />
-            </form>
-            {%- if builder == 'web' %}
-            <p style="font-size: 90%">Enter a module, class or function name.</p>
-            {%- endif %}
-          {%- endif %}
-          {%- endblock %}
-        </div>
-      </div>
-      {%- endif %}
-{%- endmacro -%}
-
-<html xmlns="http://www.w3.org/1999/xhtml">
-  <head>
-    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-    {%- if builder != 'htmlhelp' %}
-      {%- set titlesuffix = " &mdash; " + docstitle %}
-    {%- endif %}
-    <title>{{ title|striptags }}{{ titlesuffix }}</title>
-    {%- if builder == 'web' %}
-    <link rel="stylesheet" href="{{ pathto('index') }}?do=stylesheet{%
-      if in_admin_panel %}&admin=yes{% endif %}" type="text/css" />
-    {%- for link, type, title in page_links %}
-    <link rel="alternate" type="{{ type|e(true) }}" title="{{ title|e(true) }}" href="{{ link|e(true) }}" />
-    {%- endfor %}
-    {%- else %}
-    <link rel="stylesheet" href="{{ pathto('_static/' + style, 1) }}" type="text/css" />
-    <link rel="stylesheet" href="{{ pathto('_static/pygments.css', 1) }}" type="text/css" />
-    {%- endif %}
-    {%- if builder != 'htmlhelp' %}
-    <script type="text/javascript">
-      var DOCUMENTATION_OPTIONS = {
-          URL_ROOT:    '{{ pathto("", 1) }}',
-          VERSION:     '{{ release }}',
-          COLLAPSE_MODINDEX: false,
-          FILE_SUFFIX: '{{ file_suffix }}'
-      };
-    </script>
-    <script type="text/javascript" src="{{ pathto('_static/jquery.js', 1) }}"></script>
-    <script type="text/javascript" src="{{ pathto('_static/interface.js', 1) }}"></script>
-    <script type="text/javascript" src="{{ pathto('_static/doctools.js', 1) }}"></script>
-    {%- if use_opensearch %}
-    <link rel="search" type="application/opensearchdescription+xml"
-          title="Search within {{ docstitle }}"
-          href="{{ pathto('_static/opensearch.xml', 1) }}"/>
-    {%- endif %}
-    {%- if favicon %}
-    <link rel="shortcut icon" href="{{ pathto('_static/' + favicon, 1) }}"/>
-    {%- endif %}
-    {%- endif %}
-{%- block rellinks %}
-    {%- if hasdoc('about') %}
-    <link rel="author" title="About these documents" href="{{ pathto('about') }}" />
-    {%- endif %}
-    <link rel="contents" title="Global table of contents" href="{{ pathto('contents') }}" />
-    <link rel="index" title="Global index" href="{{ pathto('genindex') }}" />
-    <link rel="search" title="Search" href="{{ pathto('search') }}" />
-    {%- if hasdoc('copyright') %}
-    <link rel="copyright" title="Copyright" href="{{ pathto('copyright') }}" />
-    {%- endif %}
-    <link rel="top" title="{{ docstitle }}" href="{{ pathto('index') }}" />
-    {%- if parents %}
-    <link rel="up" title="{{ parents[-1].title|striptags }}" href="{{ parents[-1].link|e }}" />
-    {%- endif %}
-    {%- if next %}
-    <link rel="next" title="{{ next.title|striptags }}" href="{{ next.link|e }}" />
-    {%- endif %}
-    {%- if prev %}
-    <link rel="prev" title="{{ prev.title|striptags }}" href="{{ prev.link|e }}" />
-    {%- endif %}
-{%- endblock %}
-{%- block extrahead %}{% endblock %}
-  </head>
-  <body>
-
-{% block logilablogo %}
-<div class="logilablogo">
-	<a class="logogo" href="http://www.logilab.org"><img border="0" src="{{ pathto('_static/logilab.png', 1) }}"/></a>
-  </div>
-{% endblock %}
-
-{%- block relbar1 %}{{ relbar() }}{% endblock %}
-
-{%- block sidebar1 %}{# possible location for sidebar #}{% endblock %}
-
-{%- block document %}
-    <div class="document">
-      <div class="documentwrapper">
-      {%- if builder != 'htmlhelp' %}
-        <div class="bodywrapper">
-      {%- endif %}
-          <div class="body">
-            {% block body %}{% endblock %}
-          </div>
-      {%- if builder != 'htmlhelp' %}
-        </div>
-      {%- endif %}
-      </div>
-{%- endblock %}
-
-{%- block sidebar2 %}{{ sidebar() }}{% endblock %}
-      <div class="clearer"></div>
-    </div>
-
-{%- block relbar2 %}{{ relbar() }}{% endblock %}
-
-{%- block footer %}
-    <div class="footer">
-    {%- if hasdoc('copyright') %}
-      &copy; <a href="{{ pathto('copyright') }}">Copyright</a> {{ copyright }}.
-    {%- else %}
-      &copy; Copyright {{ copyright }}.
-    {%- endif %}
-    {%- if last_updated %}
-      Last updated on {{ last_updated }}.
-    {%- endif %}
-    {%- if show_sphinx %}
-      Created using <a href="http://sphinx.pocoo.org/">Sphinx</a>.
-    {%- endif %}
-    </div>
-{%- endblock %}
-  </body>
-</html>
--- a/docs/Makefile	Fri Dec 13 05:36:22 2019 +0100
+++ b/docs/Makefile	Fri Dec 13 05:54:11 2019 +0100
@@ -1,70 +1,19 @@
-# Makefile for Sphinx documentation
+# Minimal makefile for Sphinx documentation
 #
 
 # You can set these variables from the command line.
 SPHINXOPTS    =
 SPHINXBUILD   = sphinx-build
-PAPER         =
+SOURCEDIR     = .
+BUILDDIR      = _build
 
-# Internal variables.
-PAPEROPT_a4     = -D latex_paper_size=a4
-PAPEROPT_letter = -D latex_paper_size=letter
-ALLSPHINXOPTS   = -d build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
-
-.PHONY: help clean html web pickle htmlhelp latex changes linkcheck
-
+# Put it first so that "make" without argument is like "make help".
 help:
-	@echo "Please use \`make <target>' where <target> is one of"
-	@echo "  html      to make standalone HTML files"
-	@echo "  pickle    to make pickle files (usable by e.g. sphinx-web)"
-	@echo "  htmlhelp  to make HTML files and a HTML help project"
-	@echo "  latex     to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
-	@echo "  changes   to make an overview over all changed/added/deprecated items"
-	@echo "  linkcheck to check all external links for integrity"
-
-clean:
-	-rm -rf build/*
-
-html:
-	mkdir -p build/html build/doctrees
-	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) build/html
-	@echo
-	@echo "Build finished. The HTML pages are in build/html."
+	@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
 
-pickle:
-	mkdir -p build/pickle build/doctrees
-	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) build/pickle
-	@echo
-	@echo "Build finished; now you can process the pickle files or run"
-	@echo "  sphinx-web build/pickle"
-	@echo "to start the sphinx-web server."
-
-web: pickle
-
-htmlhelp:
-	mkdir -p build/htmlhelp build/doctrees
-	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) build/htmlhelp
-	@echo
-	@echo "Build finished; now you can run HTML Help Workshop with the" \
-	      ".hhp project file in build/htmlhelp."
+.PHONY: help Makefile
 
-latex:
-	mkdir -p build/latex build/doctrees
-	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) build/latex
-	@echo
-	@echo "Build finished; the LaTeX files are in build/latex."
-	@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \
-	      "run these through (pdf)latex."
-
-changes:
-	mkdir -p build/changes build/doctrees
-	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) build/changes
-	@echo
-	@echo "The overview file is in build/changes."
-
-linkcheck:
-	mkdir -p build/linkcheck build/doctrees
-	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) build/linkcheck
-	@echo
-	@echo "Link check complete; look for any errors in the above output " \
-	      "or in build/linkcheck/output.txt."
+# Catch-all target: route all unknown targets to Sphinx using the new
+# "make mode" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).
+%: Makefile
+	@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/canonisation.rst	Fri Dec 13 05:54:11 2019 +0100
@@ -0,0 +1,210 @@
+Idées sur la canonisation
+=========================
+
+::
+
+    from ginco.rql.node_lib import Variable
+
+    def sort(canon_dict):
+        canon_dict['all_variables'].sort()
+        for l in canon_dict['restriction'].values():
+            l.sort()
+
+Exemple 1
+---------
+
+Formules équivalentes
+`````````````````````
+
+::
+
+  Any N, N2 where N is Note, N2 is Note, N ecrit_par P1, P1 nom 'jphc', N2 ecrit_par P2, P2 nom 'ocy' ;
+  Any Y, X  where X is Note, Y is Note,  X ecrit_par P1, P1 nom 'ocy',  Y ecrit_par P2,  P2 nom 'jphc' ;
+
+Forme canonique
+```````````````
+
+::
+
+    N = Variable('N')
+    N2 = Variable('N2')
+    P1 = Variable('P1')
+    P2 = Variable('P2')
+
+    canon1 = {
+     'all_variables': [N, N2, P1, P2],
+     'selected' : [N, N2],
+     'restriction' : {'is' :        [(N, 'Note'), (N2, 'Note')],
+                      'ecrit_par' : [(N, P1), (N2, P2)],
+                      'nom' :       [(P1, 'jphc'), (P2, 'ocy')]
+                     }
+    }
+
+    N.name  = 'is_Note:ecrit_par:1' # 1 car c'est la première variable séléctionnée
+    N2.name = 'is_Note:ecrit_par:2' # deviner pourquoi 2 ...
+    P1.name = 'ecrit_par_jphc'
+    P2.name = 'ecrit_par_ocy'
+    sort(canon1)
+
+    Y = Variable('Y')
+    X = Variable('X')
+    P1 = Variable('P1')
+    P2 = Variable('P2')
+
+    canon2 = {
+     'all_variables': [X, Y, P1, P2],
+     'selected' : [Y, X],
+     'restriction' : {'is' :        [(X, 'Note'), (Y, 'Note')],
+                      'ecrit_par' : [(X, P1), (Y, P2)],
+                      'nom' :       [(P1, 'ocy'), (P2, 'jphc')]
+                     }
+    }
+
+    Y.name  = 'is_Note:ecrit_par:1'
+    X.name = 'is_Note:ecrit_par:2'
+    P1.name = 'ecrit_par_ocy'
+    P2.name = 'ecrit_par_jphc'
+    sort(canon2)
+
+
+    canon2 == canon1
+
+Exemple 2
+---------
+
+Formules équivalentes
+`````````````````````
+
+::
+
+  Note N WHERE N ecrit_le D, N ecrit_par P, P nom 'jphc', D day > (today-10);
+  Note K WHERE K ecrit_le D, K ecrit_par Y, D day > (today-10), Y nom 'jphc';
+
+Forme canonique
+```````````````
+
+::
+
+    N = Variable('N')
+    D = Variable('D')
+    P = Variable('P')
+    canon1 = {
+     'all_variables': [N, D, P],
+     'selected' : [N],
+     'restriction' : {'is' :        [(N, 'Note')],
+                      'day':        [(D, '> (today-10)')],
+                      'ecrit_le' :  [(N, D)],
+                      'ecrit_par' : [(N, P)],
+                      'nom' :       [(P, 'jphc')]
+                     }
+    }
+    N.name = 'is_Note:ecrit_le:ecrit_par:1'
+    D.name = 'ecrit_le:day_> (today-10)'
+    P.name = 'ecrit_par:nom_jphc'
+    sort(canon1)
+
+
+    K = Variable('K')
+    D = Variable('D')
+    Y = Variable('Y')
+    canon2 = {
+     'all_variables': [K, D, Y],
+     'selected' : [K],
+     'restriction' : {'is' :        [(K, 'Note')],
+                      'day':        [(D, '> (today-10)')],
+                      'ecrit_le' :  [(K, D)],
+                      'ecrit_par' : [(K, Y)],
+                      'nom' :       [(Y, 'jphc')]
+                     }
+    }
+    K.name = 'is_Note:ecrit_le:ecrit_par:1'
+    D.name = 'ecrit_le:day_> (today-10)'
+    Y.name = 'ecrit_par:nom_jphc'
+    sort(canon2)
+
+    canon1 == canon2
+
+
+Exemple 3
+---------
+
+Formules équivalentes
+`````````````````````
+
+::
+
+  Note N WHERE N ecrit_le D, D day > (today -10), N ecrit_par P, P nom 'jphc' or P nom 'ludal';
+  Note K WHERE K ecrit_le D, K ecrit_par Y, D day > (today -10), Y nom in ('jphc', 'ludal');
+
+Forme canonique
+```````````````
+
+::
+
+    N = Variable('N')
+    D = Variable('D')
+    P = Variable('P')
+    canon1 = {
+     'all_variables': [N, D, P],
+     'selected' : [N],
+     'restriction' : {'is' :        [(N, 'Note')],
+                      'day':        [(D, '> (today-10)')],
+                      'ecrit_le' :  [(N, D)],
+                      'ecrit_par' : [(N, P)],
+                      'nom' :       [(P, 'jphc'), (P, 'ludal')]
+                     }
+    }
+    N.name = 'is_Note:ecrit_le:ecrit_par:1'
+    D.name = 'ecrit_le:day_> (today-10)'
+    P.name = 'ecrit_par:nom_jphc'
+    sort(canon1)
+
+
+    K = Variable('K')
+    D = Variable('D')
+    Y = Variable('Y')
+    canon2 = {
+     'all_variables': [K, D, Y],
+     'selected' : [K],
+     'restriction' : {'is' :        [(K, 'Note')],
+                      'day':        [(D, '> (today-10)')],
+                      'ecrit_le' :  [(K, D)],
+                      'ecrit_par' : [(K, Y)],
+                      'nom' :       [(Y, 'jphc'), (Y, 'ludal')]
+                     }
+    }
+    K.name = 'is_Note:ecrit_le:ecrit_par:1'
+    D.name = 'ecrit_le:day_> (today-10)'
+    Y.name = 'ecrit_par:nom_jphc'
+    sort(canon2)
+
+    canon1 == canon2
+
+
+
+Problèmes
+---------
+
+1. Les paires de formules suivantes sont considérées comme identiques par
+   l'algorithme ci-dessus alors qu'elles ne le sont pas:
+
+::
+
+    Note N WHERE N ecrit_le D, D day > (today -10), N ecrit_par P, P nom 'jphc' or P nom 'ludal';
+    Note N WHERE N ecrit_le D, D day > (today -10), N ecrit_par P, P nom 'jphc', P nom 'ludal';
+
+    Note N WHERE N ecrit_le D, D day > (today -10), N ecrit_par P, P nom 'jphc' or P prenom 'ludal';
+    Note N WHERE N ecrit_le D, D day > (today -10), N ecrit_par P, P nom 'jphc', P prenom 'ludal';
+
+donne comme restriction:
+
+::
+
+ 'restriction' : {'is' :        [(K, 'Note')],
+                  'day':        [(D, '> (today-10)')],
+                  'ecrit_le' :  [(K, D)],
+                  'ecrit_par' : [(K, Y)],
+                  'nom_nom' :   [(Y, 'jphc', Y, 'ludal')]
+                 }
+
+2. risque de collision dans les noms de variables non sélectionnées (un exemple ?).
--- a/docs/canonisation.txt	Fri Dec 13 05:36:22 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,210 +0,0 @@
-Idées sur la canonisation
-=========================
-
-::
-
-    from ginco.rql.node_lib import Variable
-
-    def sort(canon_dict):
-        canon_dict['all_variables'].sort()
-        for l in canon_dict['restriction'].values():
-            l.sort()
-
-Exemple 1
----------
-
-Formules équivalentes
-`````````````````````
-
-::
-
-  Any N, N2 where N is Note, N2 is Note, N ecrit_par P1, P1 nom 'jphc', N2 ecrit_par P2, P2 nom 'ocy' ;
-  Any Y, X  where X is Note, Y is Note,  X ecrit_par P1, P1 nom 'ocy',  Y ecrit_par P2,  P2 nom 'jphc' ;
-
-Forme canonique
-```````````````
-
-::
-
-    N = Variable('N')
-    N2 = Variable('N2')
-    P1 = Variable('P1')
-    P2 = Variable('P2')
-
-    canon1 = {
-     'all_variables': [N, N2, P1, P2],
-     'selected' : [N, N2],
-     'restriction' : {'is' :        [(N, 'Note'), (N2, 'Note')],
-                      'ecrit_par' : [(N, P1), (N2, P2)],
-                      'nom' :       [(P1, 'jphc'), (P2, 'ocy')]
-                     }
-    }
-
-    N.name  = 'is_Note:ecrit_par:1' # 1 car c'est la première variable séléctionnée
-    N2.name = 'is_Note:ecrit_par:2' # deviner pourquoi 2 ...
-    P1.name = 'ecrit_par_jphc'
-    P2.name = 'ecrit_par_ocy'
-    sort(canon1)
-
-    Y = Variable('Y')
-    X = Variable('X')
-    P1 = Variable('P1')
-    P2 = Variable('P2')
-
-    canon2 = {
-     'all_variables': [X, Y, P1, P2],
-     'selected' : [Y, X],
-     'restriction' : {'is' :        [(X, 'Note'), (Y, 'Note')],
-                      'ecrit_par' : [(X, P1), (Y, P2)],
-                      'nom' :       [(P1, 'ocy'), (P2, 'jphc')]
-                     }
-    }
-
-    Y.name  = 'is_Note:ecrit_par:1'
-    X.name = 'is_Note:ecrit_par:2'
-    P1.name = 'ecrit_par_ocy'
-    P2.name = 'ecrit_par_jphc'
-    sort(canon2)
-
-
-    canon2 == canon1
-
-Exemple 2
----------
-
-Formules équivalentes
-`````````````````````
-
-::
-
-  Note N WHERE N ecrit_le D, N ecrit_par P, P nom 'jphc', D day > (today-10);
-  Note K WHERE K ecrit_le D, K ecrit_par Y, D day > (today-10), Y nom 'jphc';
-
-Forme canonique
-```````````````
-
-::
-
-    N = Variable('N')
-    D = Variable('D')
-    P = Variable('P')
-    canon1 = {
-     'all_variables': [N, D, P],
-     'selected' : [N],
-     'restriction' : {'is' :        [(N, 'Note')],
-                      'day':        [(D, '> (today-10)')],
-                      'ecrit_le' :  [(N, D)],
-                      'ecrit_par' : [(N, P)],
-                      'nom' :       [(P, 'jphc')]
-                     }
-    }
-    N.name = 'is_Note:ecrit_le:ecrit_par:1'
-    D.name = 'ecrit_le:day_> (today-10)'
-    P.name = 'ecrit_par:nom_jphc'
-    sort(canon1)
-
-
-    K = Variable('K')
-    D = Variable('D')
-    Y = Variable('Y')
-    canon2 = {
-     'all_variables': [K, D, Y],
-     'selected' : [K],
-     'restriction' : {'is' :        [(K, 'Note')],
-                      'day':        [(D, '> (today-10)')],
-                      'ecrit_le' :  [(K, D)],
-                      'ecrit_par' : [(K, Y)],
-                      'nom' :       [(Y, 'jphc')]
-                     }
-    }
-    K.name = 'is_Note:ecrit_le:ecrit_par:1'
-    D.name = 'ecrit_le:day_> (today-10)'
-    Y.name = 'ecrit_par:nom_jphc'
-    sort(canon2)
-
-    canon1 == canon2
-
-
-Exemple 3
----------
-
-Formules équivalentes
-`````````````````````
-
-::
-
-  Note N WHERE N ecrit_le D, D day > (today -10), N ecrit_par P, P nom 'jphc' or P nom 'ludal';
-  Note K WHERE K ecrit_le D, K ecrit_par Y, D day > (today -10), Y nom in ('jphc', 'ludal');
-
-Forme canonique
-```````````````
-
-::
-
-    N = Variable('N')
-    D = Variable('D')
-    P = Variable('P')
-    canon1 = {
-     'all_variables': [N, D, P],
-     'selected' : [N],
-     'restriction' : {'is' :        [(N, 'Note')],
-                      'day':        [(D, '> (today-10)')],
-                      'ecrit_le' :  [(N, D)],
-                      'ecrit_par' : [(N, P)],
-                      'nom' :       [(P, 'jphc'), (P, 'ludal')]
-                     }
-    }
-    N.name = 'is_Note:ecrit_le:ecrit_par:1'
-    D.name = 'ecrit_le:day_> (today-10)'
-    P.name = 'ecrit_par:nom_jphc'
-    sort(canon1)
-
-
-    K = Variable('K')
-    D = Variable('D')
-    Y = Variable('Y')
-    canon2 = {
-     'all_variables': [K, D, Y],
-     'selected' : [K],
-     'restriction' : {'is' :        [(K, 'Note')],
-                      'day':        [(D, '> (today-10)')],
-                      'ecrit_le' :  [(K, D)],
-                      'ecrit_par' : [(K, Y)],
-                      'nom' :       [(Y, 'jphc'), (Y, 'ludal')]
-                     }
-    }
-    K.name = 'is_Note:ecrit_le:ecrit_par:1'
-    D.name = 'ecrit_le:day_> (today-10)'
-    Y.name = 'ecrit_par:nom_jphc'
-    sort(canon2)
-
-    canon1 == canon2
-
-
-
-Problèmes
----------
-
-1. Les paires de formules suivantes sont considérées comme identiques par
-   l'algorithme ci-dessus alors qu'elles ne le sont pas:
-
-::
-
-    Note N WHERE N ecrit_le D, D day > (today -10), N ecrit_par P, P nom 'jphc' or P nom 'ludal';
-    Note N WHERE N ecrit_le D, D day > (today -10), N ecrit_par P, P nom 'jphc', P nom 'ludal';
-
-    Note N WHERE N ecrit_le D, D day > (today -10), N ecrit_par P, P nom 'jphc' or P prenom 'ludal';
-    Note N WHERE N ecrit_le D, D day > (today -10), N ecrit_par P, P nom 'jphc', P prenom 'ludal';
-
-donne comme restriction:
-
-::
-
- 'restriction' : {'is' :        [(K, 'Note')],
-                  'day':        [(D, '> (today-10)')],
-                  'ecrit_le' :  [(K, D)],
-                  'ecrit_par' : [(K, Y)],
-                  'nom_nom' :   [(Y, 'jphc', Y, 'ludal')]
-                 }
-
-2. risque de collision dans les noms de variables non sélectionnées (un exemple ?).
--- a/docs/conf.py	Fri Dec 13 05:36:22 2019 +0100
+++ b/docs/conf.py	Fri Dec 13 05:54:11 2019 +0100
@@ -1,194 +1,185 @@
 # -*- coding: utf-8 -*-
 #
-# RQL documentation build configuration file, created by
-# sphinx-quickstart on Tue Nov  4 07:54:06 2008.
-#
-# This file is execfile()d with the current directory set to its containing dir.
-#
-# The contents of this file are pickled, so don't put values in the namespace
-# that aren't pickleable (module imports are okay, they're removed automatically).
+# Configuration file for the Sphinx documentation builder.
 #
-# All configuration values have a default value; values that are commented out
-# serve to show the default value.
-# copyright 2004-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
-# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
-#
-# This file is part of rql.
-#
-# rql is free software: you can redistribute it and/or modify it under the
-# terms of the GNU Lesser General Public License as published by the Free
-# Software Foundation, either version 2.1 of the License, or (at your option)
-# any later version.
+# This file does only contain a selection of the most common options. For a
+# full list see the documentation:
+# http://www.sphinx-doc.org/en/master/config
+
+# -- Path setup --------------------------------------------------------------
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
 #
-# rql is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-# A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
-# details.
-#
-# You should have received a copy of the GNU Lesser General Public License along
-# with rql. If not, see <http://www.gnu.org/licenses/>.
+# import os
+# import sys
+# sys.path.insert(0, os.path.abspath('.'))
+
+
+# -- Project information -----------------------------------------------------
+
+project = 'RQL'
+copyright = '2019, Logilab'
+author = 'Logilab'
+
+# The short X.Y version
+version = ''
+# The full version, including alpha/beta/rc tags
+release = ''
 
-# If your extensions are in another directory, add it here. If the directory
-# is relative to the documentation root, use os.path.abspath to make it
-# absolute, like shown here.
-# sys.path.append(os.path.abspath('some/directory'))
+
+# -- General configuration ---------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#
+# needs_sphinx = '1.0'
 
-# General configuration
-# ---------------------
-
-# Add any Sphinx extension module names here, as strings. They can be extensions
-# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = ['sphinx.ext.autodoc']
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = [
+    'sphinx.ext.autodoc',
+    'sphinx.ext.doctest',
+    'sphinx.ext.intersphinx',
+    'sphinx.ext.viewcode',
+]
 
 # Add any paths that contain templates here, relative to this directory.
-templates_path = ['.templates']
+templates_path = ['_templates']
 
-# The suffix of source filenames.
-source_suffix = '.txt'
+# The suffix(es) of source filenames.
+# You can specify multiple suffix as a list of string:
+#
+# source_suffix = ['.rst', '.md']
+source_suffix = '.rst'
 
 # The master toctree document.
 master_doc = 'index'
 
-# General substitutions.
-project = 'RQL'
-copyright = '2008, Sylvain Thenault'
-
-# The default replacements for |version| and |release|, also used in various
-# other places throughout the built documents.
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
 #
-# The short X.Y version.
-version = '0.20.2'
-# The full version, including alpha/beta/rc tags.
-release = '0.20.2'
-
-# There are two options for replacing |today|: either, you set today to some
-# non-false value, then it is used:
-# today = ''
-# Else, today_fmt is used as the format for a strftime call.
-today_fmt = '%B %d, %Y'
+# This is also used if you do content translation via gettext catalogs.
+# Usually you set "language" from the command line for these cases.
+language = None
 
-# List of documents that shouldn't be included in the build.
-# unused_docs = []
-
-# List of directories, relative to source directories, that shouldn't be searched
-# for source files.
-# exclude_dirs = []
-
-# The reST default role (used for this markup: `text`) to use for all documents.
-# default_role = None
-
-# If true, '()' will be appended to :func: etc. cross-reference text.
-# add_function_parentheses = True
-
-# If true, the current module name will be prepended to all description
-# unit titles (such as .. function::).
-# add_module_names = True
-
-# If true, sectionauthor and moduleauthor directives will be shown in the
-# output. They are ignored by default.
-# show_authors = False
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+# This pattern also affects html_static_path and html_extra_path.
+exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
 
 # The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
+pygments_style = None
 
 
-# Options for HTML output
-# -----------------------
-
-# The style sheet to use for HTML and HTML Help pages. A file of that name
-# must exist either in Sphinx' static/ path, or in one of the custom paths
-# given in html_static_path.
-html_style = 'sphinx-default.css'
-
-# The name for this set of Sphinx documents.  If None, it defaults to
-# "<project> v<release> documentation".
-# html_title = None
+# -- Options for HTML output -------------------------------------------------
 
-# A shorter title for the navigation bar.  Default is the same as html_title.
-# html_short_title = None
+# The theme to use for HTML and HTML Help pages.  See the documentation for
+# a list of builtin themes.
+#
+html_theme = 'alabaster'
 
-# The name of an image file (within the static path) to place at the top of
-# the sidebar.
-# html_logo = None
-
-# The name of an image file (within the static path) to use as favicon of the
-# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
-# pixels large.
-# html_favicon = None
+# Theme options are theme-specific and customize the look and feel of a theme
+# further.  For a list of options available for each theme, see the
+# documentation.
+#
+# html_theme_options = {}
 
 # Add any paths that contain custom static files (such as style sheets) here,
 # relative to this directory. They are copied after the builtin static files,
 # so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = ['.static']
-
-# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
-# using the given strftime format.
-html_last_updated_fmt = '%b %d, %Y'
+html_static_path = ['_static']
 
-# If true, SmartyPants will be used to convert quotes and dashes to
-# typographically correct entities.
-# html_use_smartypants = True
-
-# Custom sidebar templates, maps document names to template names.
+# Custom sidebar templates, must be a dictionary that maps document names
+# to template names.
+#
+# The default sidebars (for documents that don't match any pattern) are
+# defined by theme itself.  Builtin themes are using these templates by
+# default: ``['localtoc.html', 'relations.html', 'sourcelink.html',
+# 'searchbox.html']``.
+#
 # html_sidebars = {}
 
-# Additional templates that should be rendered to pages, maps page names to
-# template names.
-# html_additional_pages = {}
 
-# If false, no module index is generated.
-# html_use_modindex = True
-
-# If false, no index is generated.
-# html_use_index = True
-
-# If true, the index is split into individual pages for each letter.
-# html_split_index = False
-
-# If true, the reST sources are included in the HTML build as _sources/<name>.
-# html_copy_source = True
-
-# If true, an OpenSearch description file will be output, and all pages will
-# contain a <link> tag referring to it.  The value of this option must be the
-# base URL from which the finished HTML is served.
-# html_use_opensearch = ''
-
-# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml").
-# html_file_suffix = ''
+# -- Options for HTMLHelp output ---------------------------------------------
 
 # Output file base name for HTML help builder.
 htmlhelp_basename = 'RQLdoc'
 
 
-# Options for LaTeX output
-# ------------------------
+# -- Options for LaTeX output ------------------------------------------------
+
+latex_elements = {
+    # The paper size ('letterpaper' or 'a4paper').
+    #
+    # 'papersize': 'letterpaper',
 
-# The paper size ('letter' or 'a4').
-# latex_paper_size = 'letter'
+    # The font size ('10pt', '11pt' or '12pt').
+    #
+    # 'pointsize': '10pt',
 
-# The font size ('10pt', '11pt' or '12pt').
-# latex_font_size = '10pt'
+    # Additional stuff for the LaTeX preamble.
+    #
+    # 'preamble': '',
+
+    # Latex figure (float) alignment
+    #
+    # 'figure_align': 'htbp',
+}
 
 # Grouping the document tree into LaTeX files. List of tuples
-# (source start file, target name, title, author, document class [howto/manual]).
+# (source start file, target name, title,
+#  author, documentclass [howto, manual, or own class]).
 latex_documents = [
-  ('index', 'RQL.tex', 'RQL Documentation',
-   'Sylvain Thenault', 'manual'),
+    (master_doc, 'RQL.tex', 'RQL Documentation',
+     'Logilab', 'manual'),
+]
+
+
+# -- Options for manual page output ------------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+    (master_doc, 'rql', 'RQL Documentation',
+     [author], 1)
 ]
 
-# The name of an image file (relative to this directory) to place at the top of
-# the title page.
-# latex_logo = None
+
+# -- Options for Texinfo output ----------------------------------------------
 
-# For "manual" documents, if this is true, then toplevel headings are parts,
-# not chapters.
-# latex_use_parts = False
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+#  dir menu entry, description, category)
+texinfo_documents = [
+    (master_doc, 'RQL', 'RQL Documentation',
+     author, 'RQL', 'One line description of project.',
+     'Miscellaneous'),
+]
+
+
+# -- Options for Epub output -------------------------------------------------
+
+# Bibliographic Dublin Core info.
+epub_title = project
 
-# Additional stuff for the LaTeX preamble.
-# latex_preamble = ''
+# The unique identifier of the text. This can be a ISBN number
+# or the project homepage.
+#
+# epub_identifier = ''
+
+# A unique identification for the text.
+#
+# epub_uid = ''
 
-# Documents to append as an appendix to all manuals.
-# latex_appendices = []
+# A list of files that should not be packed into the epub file.
+epub_exclude_files = ['search.html']
+
 
-# If false, no module index is generated.
-# latex_use_modindex = True
+# -- Extension configuration -------------------------------------------------
+
+# -- Options for intersphinx extension ---------------------------------------
+
+# Example configuration for intersphinx: refer to the Python standard library.
+intersphinx_mapping = {'https://docs.python.org/': None}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/index.rst	Fri Dec 13 05:54:11 2019 +0100
@@ -0,0 +1,25 @@
+.. RQL documentation master file, created by sphinx-quickstart on Tue Nov  4 07:54:06 2008.
+   You can adapt this file completely to your liking, but it should at least
+   contain the root `toctree` directive.
+
+Documentation technique de RQL
+==============================
+
+Contents:
+
+.. toctree::
+   :maxdepth: 2
+
+   specifications_fr
+   canonisation
+   tutoriel_fr
+
+   rql.rst
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
+
--- a/docs/index.txt	Fri Dec 13 05:36:22 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-.. RQL documentation master file, created by sphinx-quickstart on Tue Nov  4 07:54:06 2008.
-   You can adapt this file completely to your liking, but it should at least
-   contain the root `toctree` directive.
-
-Documentation technique de RQL
-==============================
-
-Contents:
-
-.. toctree::
-   :maxdepth: 2
-
-   specifications_fr.txt
-   canonisation.txt
-   tutoriel_fr.txt
-
-   rql
-
-Indices and tables
-==================
-
-* :ref:`genindex`
-* :ref:`modindex`
-* :ref:`search`
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/make.bat	Fri Dec 13 05:54:11 2019 +0100
@@ -0,0 +1,35 @@
+@ECHO OFF
+
+pushd %~dp0
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+	set SPHINXBUILD=sphinx-build
+)
+set SOURCEDIR=.
+set BUILDDIR=_build
+
+if "%1" == "" goto help
+
+%SPHINXBUILD% >NUL 2>NUL
+if errorlevel 9009 (
+	echo.
+	echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
+	echo.installed, then set the SPHINXBUILD environment variable to point
+	echo.to the full path of the 'sphinx-build' executable. Alternatively you
+	echo.may add the Sphinx directory to PATH.
+	echo.
+	echo.If you don't have Sphinx installed, grab it from
+	echo.http://sphinx-doc.org/
+	exit /b 1
+)
+
+%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
+goto end
+
+:help
+%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS%
+
+:end
+popd
--- a/docs/rql.rst	Fri Dec 13 05:36:22 2019 +0100
+++ b/docs/rql.rst	Fri Dec 13 05:54:11 2019 +0100
@@ -68,13 +68,14 @@
     :undoc-members:
     :show-inheritance:
 
-rql.pygments\_ext module
-------------------------
 
-.. automodule:: rql.pygments_ext
-    :members:
-    :undoc-members:
-    :show-inheritance:
+.. rql.pygments\_ext module
+.. ------------------------
+.. 
+.. .. automodule:: rql.pygments_ext
+..     :members:
+..     :undoc-members:
+..     :show-inheritance:
 
 rql.rqlgen module
 -----------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/rql_windows.rst	Fri Dec 13 05:54:11 2019 +0100
@@ -0,0 +1,121 @@
+Compiling rql for Windows
+=========================
+
+
+:author: Alexandre Fayolle
+:date: 2009/09/09
+
+RQL can use either logilab.constraint or gecode to perform type
+inference. This document explains how the gecode support can be added
+for the Windows platform. 
+
+The short way
+-------------
+
+Download and install http://ftp.logilab.org/pub/rql/rql-0.23.0.win32-py2.5.exe
+
+The long way
+------------
+
+Problem statement: we want to use python2.5 on windows. Compiling C
+extensions requires Visual Studio 2003, but Gecode requires Visual
+Studio 2008. So we are stuck with using MinGW, and then again Gecode
+requires gcc 4.2 or later and cygwin to support building. 
+But cygwin doesn't come with a mingw enabled gcc 4.x (only 3.x
+available), so some stiching is required. 
+
+Dependencies installation
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+* cygwin_: download http://www.cygwin.com/setup.exe, run it and select the following
+  packages:
+
+  - diffutils
+  - perl
+  - g++-mingw
+  - some text editor of your choice (nano, vim...)
+
+* mingw_: download the following files:
+
+  - `gcc-g++-4.4.0-bin <http://sourceforge.net/projects/mingw/files/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gcc-c%2B%2B-4.4.0-mingw32-bin.tar.gz/download>`_
+
+  - `gcc-g++-4.4.0-dll <http://sourceforge.net/projects/mingw/files/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gcc-c%2B%2B-4.4.0-mingw32-dll.tar.gz/download>`_
+
+  - `gcc-core-4.4.0-bin <http://sourceforge.net/projects/mingw/files/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gcc-core-4.4.0-mingw32-bin.tar.gz/download>`_
+
+  - `gcc-core-4.4.0-dll <http://sourceforge.net/projects/mingw/files/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gcc-core-4.4.0-mingw32-dll.tar.gz/download>`_
+
+ - `gmp-4.2.4-dll <http://sourceforge.net/projects/mingw/files/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gmp-4.2.4-mingw32-dll.tar.gz/download>`_
+
+ - `mpfr-2.4.1-dll <http://sourceforge.net/projects/mingw/files/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/mpfr-2.4.1-mingw32-dll.tar.gz/download>`_
+
+ - `binutils-2.19.1-bin <http://sourceforge.net/projects/mingw/files/GNU%20Binutils/Current%20Release_%20GNU%20binutils-2.19.1/binutils-2.19.1-mingw32-bin.tar.gz/download>`_
+
+ - `w32api-3.13-dev <http://sourceforge.net/projects/mingw/files/MinGW%20API%20for%20MS-Windows/Current%20Release_%20w32api-3.13/w32api-3.13-mingw32-dev.tar.gz/download>`_
+
+  - `mingwrt-3.15.2-dev <http://sourceforge.net/projects/mingw/files/MinGW%20Runtime/mingwrt-3.15.2/mingwrt-3.15.2-mingw32-dev.tar.gz/download>`_
+
+
+Create ``c:\MinGW``. Launch a cygwin shell, go to ``/cygdrive/c/MinGW`` and
+untar all the mingw tarballs
+
+Edit ``/etc/profile`` and go to the place where the ``PATH`` environment
+variable is set. Change the line to *prepend*
+``/cygdrive/c/MinGW/bin:/cygdrive/c/MinGW/libexec/mingw32/4.4.0`` to the ``PATH``
+
+* download and untar `Gecode 3.1.0 source distribution <http://www.gecode.org/download/gecode-3.1.0.tar.gz>`_.
+
+
+Compiling gecode
+~~~~~~~~~~~~~~~~
+
+In a cygwin shell, go the the untarred Gecode source directory and run::
+
+  $ ./configure --enable-version-specific-runtime-libs \
+                --disable-shared --disable-qt --disable-gist \
+                --disable-examples --enable-static
+
+Edit gecode/support/config.hpp, and change the line ::
+
+  #define GECODE_USE_GETTIMEOFDAY 1
+
+to::
+
+  #define GECODE_USE_CLOCK 1
+
+run::
+
+  $ make CXXFLAGS="-I. -O1 -DNDEBUG -Wextra -Wall -pipe -ggdb \
+  -fno-strict-aliasing -ffast-math -mthreads -DGECODE_BUILD_SUPPORT -static-libgcc"
+
+While this runs, consider renting some Bollywood movie (I enjoyed `this one
+<http://www.imdb.com/title/tt0172684/>`_) and watching it.
+
+
+Compiling the C extension in rql
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+in a Windows shell (aka "DOS Console"), go the the rql directory and
+run::
+
+ $ set PATH=%PATH%;c:\MinGW\bin;c:\MinGW\libexec\mingw32\4.4.0
+ $ python setup.py build_ext -c mingw32 \
+                             -Ic:\temp\gecode-3.1.0 \
+                             -Lc:\temp\gecode-3.1.0 
+                             --in-place
+
+Test
+~~~~
+
+Open a new console (to get the default ``PATH``). Go to the parent
+directory of rql. Launch the Python interpreter, and type::
+
+ >>> import rql.analyze
+
+If this works, congratulation, you're done. 
+
+
+
+.. _cygwin: http://www.cygwin.com
+.. _mingw: http://www.mingw.org
+
--- a/docs/rql_windows.txt	Fri Dec 13 05:36:22 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,121 +0,0 @@
-Compiling rql for Windows
-=========================
-
-
-:author: Alexandre Fayolle
-:date: 2009/09/09
-
-RQL can use either logilab.constraint or gecode to perform type
-inference. This document explains how the gecode support can be added
-for the Windows platform. 
-
-The short way
--------------
-
-Download and install http://ftp.logilab.org/pub/rql/rql-0.23.0.win32-py2.5.exe
-
-The long way
-------------
-
-Problem statement: we want to use python2.5 on windows. Compiling C
-extensions requires Visual Studio 2003, but Gecode requires Visual
-Studio 2008. So we are stuck with using MinGW, and then again Gecode
-requires gcc 4.2 or later and cygwin to support building. 
-But cygwin doesn't come with a mingw enabled gcc 4.x (only 3.x
-available), so some stiching is required. 
-
-Dependencies installation
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-* cygwin_: download http://www.cygwin.com/setup.exe, run it and select the following
-  packages:
-
-  - diffutils
-  - perl
-  - g++-mingw
-  - some text editor of your choice (nano, vim...)
-
-* mingw_: download the following files:
-
-  - `gcc-g++-4.4.0-bin <http://sourceforge.net/projects/mingw/files/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gcc-c%2B%2B-4.4.0-mingw32-bin.tar.gz/download>`_
-
-  - `gcc-g++-4.4.0-dll <http://sourceforge.net/projects/mingw/files/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gcc-c%2B%2B-4.4.0-mingw32-dll.tar.gz/download>`_
-
-  - `gcc-core-4.4.0-bin <http://sourceforge.net/projects/mingw/files/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gcc-core-4.4.0-mingw32-bin.tar.gz/download>`_
-
-  - `gcc-core-4.4.0-dll <http://sourceforge.net/projects/mingw/files/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gcc-core-4.4.0-mingw32-dll.tar.gz/download>`_
-
- - `gmp-4.2.4-dll <http://sourceforge.net/projects/mingw/files/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/gmp-4.2.4-mingw32-dll.tar.gz/download>`_
-
- - `mpfr-2.4.1-dll <http://sourceforge.net/projects/mingw/files/GCC%20Version%204/Current%20Release_%20gcc-4.4.0/mpfr-2.4.1-mingw32-dll.tar.gz/download>`_
-
- - `binutils-2.19.1-bin <http://sourceforge.net/projects/mingw/files/GNU%20Binutils/Current%20Release_%20GNU%20binutils-2.19.1/binutils-2.19.1-mingw32-bin.tar.gz/download>`_
-
- - `w32api-3.13-dev <http://sourceforge.net/projects/mingw/files/MinGW%20API%20for%20MS-Windows/Current%20Release_%20w32api-3.13/w32api-3.13-mingw32-dev.tar.gz/download>`_
-
-  - `mingwrt-3.15.2-dev <http://sourceforge.net/projects/mingw/files/MinGW%20Runtime/mingwrt-3.15.2/mingwrt-3.15.2-mingw32-dev.tar.gz/download>`_
-
-
-Create ``c:\MinGW``. Launch a cygwin shell, go to ``/cygdrive/c/MinGW`` and
-untar all the mingw tarballs
-
-Edit ``/etc/profile`` and go to the place where the ``PATH`` environment
-variable is set. Change the line to *prepend*
-``/cygdrive/c/MinGW/bin:/cygdrive/c/MinGW/libexec/mingw32/4.4.0`` to the ``PATH``
-
-* download and untar `Gecode 3.1.0 source distribution <http://www.gecode.org/download/gecode-3.1.0.tar.gz>`_.
-
-
-Compiling gecode
-~~~~~~~~~~~~~~~~
-
-In a cygwin shell, go the the untarred Gecode source directory and run::
-
-  $ ./configure --enable-version-specific-runtime-libs \
-                --disable-shared --disable-qt --disable-gist \
-                --disable-examples --enable-static
-
-Edit gecode/support/config.hpp, and change the line ::
-
-  #define GECODE_USE_GETTIMEOFDAY 1
-
-to::
-
-  #define GECODE_USE_CLOCK 1
-
-run::
-
-  $ make CXXFLAGS="-I. -O1 -DNDEBUG -Wextra -Wall -pipe -ggdb \
-  -fno-strict-aliasing -ffast-math -mthreads -DGECODE_BUILD_SUPPORT -static-libgcc"
-
-While this runs, consider renting some Bollywood movie (I enjoyed `this one
-<http://www.imdb.com/title/tt0172684/>`_) and watching it.
-
-
-Compiling the C extension in rql
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-in a Windows shell (aka "DOS Console"), go the the rql directory and
-run::
-
- $ set PATH=%PATH%;c:\MinGW\bin;c:\MinGW\libexec\mingw32\4.4.0
- $ python setup.py build_ext -c mingw32 \
-                             -Ic:\temp\gecode-3.1.0 \
-                             -Lc:\temp\gecode-3.1.0 
-                             --in-place
-
-Test
-~~~~
-
-Open a new console (to get the default ``PATH``). Go to the parent
-directory of rql. Launch the Python interpreter, and type::
-
- >>> import rql.analyze
-
-If this works, congratulation, you're done. 
-
-
-
-.. _cygwin: http://www.cygwin.com
-.. _mingw: http://www.mingw.org
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/specifications_en.rst	Fri Dec 13 05:54:11 2019 +0100
@@ -0,0 +1,588 @@
+.. -*- coding: utf-8 -*-
+
+
+===================================================
+Specification "Relations Query Language" (Hercules)
+===================================================
+
+Introduction
+============
+
+Goals RQL
+---------
+
+The goal is to have a language emphasizing the way of browsing
+relations. As such, attributes will be regarded as cases of
+special relations (in terms of implementation, the user
+language not to see virtually no difference between an attribute and a
+relation).
+
+RQL is inspired by SQL but is the highest level. A knowledge of the
+`CubicWeb` schema defining the application is necessary.
+
+Comparison with existing languages
+----------------------------------
+
+SQL
+```
+RQL builds on the features of SQL but is at a higher level
+(the current implementation of RQL generates SQL). For that it is limited
+to the way of browsing relations and introduces variables.
+The user does not need to know the model underlying SQL, but the `CubicWeb`
+scheam defining the application.
+
+Versa
+`````
+Should I look in more detail, but here is already some ideas for
+the moment ... Versa_ is the language most similar to what we wanted
+to do, but the model underlying data being RDF, there is some
+number of things such as namespaces or handling of the RDF types which
+does not interest us. On the functionality level, Versa_ is very comprehensive
+including through many functions of conversion and basic types manipulation,
+which may need to be guided at one time or another.
+Finally, the syntax is a little esoteric.
+
+See also
+``````````
+RDFQL_
+
+
+The different types of queries
+------------------------------
+
+Search ( `Any`)
+   This type of query can extract entities and attributes of entities.
+
+Inserting entities ( `INSERT`)
+   This type of query is used to insert new entities in the database. It
+   will also create direct relationships entities newly created.
+
+Update entities, relations creation( `SET`)
+   This type of query updates existing entities in the database,
+   or create relations between existing entities.
+
+Deletion of entities or relationship ( `DELETE`)
+   This type of query allows for the removal of entities and relations existing
+   in the database.
+
+
+
+Examples
+========
+
+(see the tutorial: ref: `tutorielRQL` for more examples)
+
+Search Query
+------------
+
+   [ `DISTINCT`] <entity type> V1 (V2) \ *
+   [ `GROUPBY` V1 (V2) \*] [ `ORDERBY` <orderterms>]
+   [ `WHERE` <restriction>]
+   [ `LIMIT` <value>] [ `OFFSET` <value>]
+
+:entity type:
+   Type of selected variables.
+   The special type `Any` is equivalent to not specify a type.
+:restriction:
+   list of relations to go through whic follow the pattern
+     `V1 relation V2 | <static value>`
+:orderterms:
+   Definition of the selection order: variable or column number followed by
+   sorting method ( `ASC`, `DESC`), ASC is the default.
+:note for grouped queries:
+   For grouped queries (e.g., a clause `GROUPBY`), all
+   selected variables must be aggregated or grouped.
+
+
+
+- *Search for the object of identifier 53*
+   ::
+
+        Any WHERE X
+        X eid 53
+
+- *Search material such as comics, owned by syt and available*
+   ::
+
+        WHERE X Document
+        X occurence_of F, F class C, C name 'Comics'
+        X owned_by U, U login 'syt'
+        X available true
+
+- *Looking for people working for eurocopter interested in training*
+   ::
+
+        Person P WHERE
+        P work_for P, S name 'Eurocopter'
+        P interested_by T, T name 'training'
+
+- *Search note less than 10 days old written by jphc or ocy*
+   ::
+
+        Note N WHERE
+        N written_on D, D day> (today -10),
+        N written_by P, P name 'jphc' or P name 'ocy'
+
+- *Looking for people interested in training or living in Paris*
+   ::
+
+        Person P WHERE
+        (P interested_by T, T name 'training') or
+        (P city 'Paris')
+
+- *The name and surname of all people*
+   ::
+
+        Any N, P WHERE
+        X is Person, X name N, X first_name P
+
+   Note that the selection of several entities generally force
+   the use of "Any" because the type specification applies otherwise
+   to all the selected variables. We could write here
+   ::
+
+        String N, P WHERE
+        X is Person, X name N, X first_name P
+
+
+Insertion query
+---------------
+
+    `INSERT` <entity type> V1 (, <entity type> V2) \ * `:` <assignments>
+    [ `WHERE` <restriction>]
+
+: assignments:
+   list of relations to assign in the form `V1 relationship V2 | <static value>`
+
+The restriction can define variables used in assignments.
+
+Caution, if a restriction is specified, the insertion is done for
+*each line results returned by the restriction*.
+
+- *Insert a new person named 'foo'*
+   ::
+
+        INSERT Person X: X name 'widget'
+
+- *Insert a new person named 'foo', another called 'nice' and a 'friend' relation
+  between them*
+  ::
+
+        INSERT Person X, Person Y: X name 'foo', Y name 'nice', X friend Y
+
+- *Insert a new person named 'foo' and a 'friend' relation with an existing
+  person called 'nice'*
+  ::
+
+        INSERT Person X: X name 'foo', X friend  Y WHERE name 'nice'
+
+Update and relation creation queries
+------------------------------------
+    `SET` <assignements>
+    [ `WHERE` <restriction>]
+
+Caution, if a restriction is specified, the update is done *for
+each line results returned by the restriction*.
+
+- *Renaming of the person named 'foo' to 'bar' with the first name changed*
+  ::
+
+        SET X name 'bar', X first_name 'original' where X is Person X name 'foo'
+
+- *Insert a relation of type 'know' between objects linked by
+  the relation of type 'friend'*
+  ::
+
+        SET X know Y  WHERE X friend Y
+
+
+Deletion query
+--------------
+    `DELETE` (<entity type> V) | (V1 relation v2 ),...
+    [ `WHERE` <restriction>]
+
+Caution, if a restriction is specified, the deletion is made *for
+each line results returned by the restriction*.
+
+- *Deletion of the person named 'foo'*
+  ::
+
+        DELETE Person X WHERE X name 'foo'
+
+- *Removal of all relations of type 'friend' from the person named 'foo'*
+  ::
+
+        DELETE X friend Y WHERE X is Person, X name 'foo'
+
+
+
+Language definition
+===================
+
+Reserved keywords
+-----------------
+The keywords are not case sensitive.
+
+::
+
+     DISTINCT, INSERT, SET, DELETE,
+     WHERE, AND, OR, NOT
+     IN, LIKE, ILIKE,
+     TRUE, FALSE, NULL, TODAY, NOW
+     GROUPBY, ORDERBY, ASC, DESC
+
+
+Variables and Typing
+--------------------
+
+With RQL, we do not distinguish between entities and attributes. The
+value of an attribute is considered an entity of a particular type (see
+below), linked to one (real) entity by a relation called the name of
+the attribute.
+
+Entities and values to browse and/or select are represented in
+the query by *variables* that must be written in capital letters.
+
+There is a special type **Any**, referring to a non specific type.
+
+We can restrict the possible types for a variable using the
+special relation **is**.
+The possible type(s) for each variable is derived from the schema
+according to the constraints expressed above and thanks to the relations between
+each variable.
+
+Built-in types
+``````````````
+
+The base types supported are string (between double or single quotes),
+integers or floats (the separator is the'.'), dates and
+boolean. We expect to receive a schema in which types String,
+Int, Float, Date and Boolean are defined.
+
+* `String` (literal: between double or single quotes).
+* `Int`, `Float` (separator being'.').
+* `Date`, `Datetime`, `Time` (literal: string YYYY/MM/DD [hh:mm] or keywords
+   `TODAY` and `NOW`).
+* `Boolean` (keywords `TRUE` and `FALSE`).
+* `Keyword` NULL.
+
+
+Operators
+---------
+
+Logical Operators
+```````````````````
+::
+
+     AND, OR, ','
+
+',' is equivalent to 'AND' but with the smallest among the priority
+of logical operators (see :ref:`PriorityOperators`).
+
+Mathematical Operators
+``````````````````````
+::
+
+     +, -, *, /
+
+Comparison operators
+````````````````````
+::
+
+     =, <, <=, >=, > = ~, IN, LIKE, ILIKE
+
+* The operator `=` is the default operator.
+
+* The operator `LIKE` equivalent to `~=` can be used with the
+  special character `%` in a string to indicate that the chain
+  must start or finish by a prefix/suffix:
+  ::
+
+     Any X WHERE X name =~ 'Th%'
+     Any X WHERE X name LIKE '%lt'
+
+* The operator `ILIKE` is a case-insensitive version of `LIKE`.
+
+* The operator `IN` provides a list of possible values:
+  ::
+
+    Any X WHERE X name IN ( 'chauvat', 'fayolle', 'di mascio', 'thenault')
+
+
+XXX nico: A trick <> 'bar' would not it be more convenient than NOT A
+trick 'bar'?
+
+.. _PriorityOperators:
+
+Operators priority
+``````````````````
+
+1. '*', '/'
+
+2. '+', '-'
+
+3. 'and'
+
+4. 'or'
+
+5. ','
+
+
+Advanced Features
+-----------------
+
+Functions aggregates
+````````````````````
+::
+
+     COUNT, MIN, MAX, AVG, SUM
+
+Functions on string
+```````````````````
+::
+
+     UPPER, LOWER
+
+Optional relations
+``````````````````
+
+* They allow you to select entities related or not to another.
+
+* You must use the `?` behind the variable to specify that the relation
+  toward it is optional:
+
+   - Anomalies of a project attached or not to a version ::
+
+       Any X, V WHERE X concerns P, P eid 42, X corrected_in V?
+
+   - All cards and the project they document if necessary ::
+
+       Any C, P WHERE C is Card, P? documented_by C
+
+
+
+BNF grammar
+-----------
+
+The terminal elements are in capital letters, non-terminal in lowercase.
+The value of the terminal elements (between quotes) is a Python regular
+expression.
+::
+
+     statement:: = (select | delete | insert | update) ';'
+
+
+     # select specific rules
+     select      ::= 'DISTINCT'? E_TYPE selected_terms restriction? group? sort?
+
+     selected_terms ::= expression ( ',' expression)*
+
+     group       ::= 'GROUPBY' VARIABLE ( ',' VARIABLE)*
+
+     sort        ::= 'ORDERBY' sort_term ( ',' sort_term)*
+
+     sort_term   ::=  VARIABLE sort_method =?
+
+     sort_method ::= 'ASC' | 'DESC'
+
+
+     # delete specific rules
+     delete ::= 'DELETE' (variables_declaration | relations_declaration) restriction?
+
+
+     # insert specific rules
+     insert ::= 'INSERT' variables_declaration ( ':' relations_declaration)? restriction?
+
+
+     # update specific rules
+     update ::= 'SET' relations_declaration restriction
+
+
+     # common rules
+     variables_declaration ::= E_TYPE VARIABLE (',' E_TYPE VARIABLE)*
+
+     relations_declaration ::= simple_relation (',' simple_relation)*
+
+     simple_relation ::= VARIABLE R_TYPE expression
+
+     restriction ::= 'WHERE' relations
+
+     relations   ::= relation (LOGIC_OP relation)*
+                   | '(' relations')'
+
+     relation    ::= 'NOT'? VARIABLE R_TYPE COMP_OP? expression
+                   | 'NOT'? R_TYPE VARIABLE 'IN' '(' expression (',' expression)* ')'
+
+     expression  ::= var_or_func_or_const (MATH_OP var_or_func_or_const) *
+                   | '(' expression ')'
+
+     var_or_func_or_const ::= VARIABLE | function | constant
+
+     function    ::= FUNCTION '(' expression ( ',' expression) * ')'
+
+     constant    ::= KEYWORD | STRING | FLOAT | INT
+
+     # tokens
+     LOGIC_OP ::= ',' | 'GOLD' | 'AND'
+     MATH_OP  ::= '+' | '-' | '/' | '*'
+     COMP_OP  ::= '>' | '>=' | '=' | '<=' | '<' | '~=' | 'LIKE' | 'ILIKE'
+
+     FUNCTION ::= 'MIN' | 'MAX' | 'SUM' | 'AVG' | 'COUNT' | 'upper' | 'LOWER'
+
+     VARIABLE ::= '[A-Z][A-Z0-9]*'
+     E_TYPE   ::= '[A-Z]\w*'
+     R_TYPE   ::= '[a-z_]+'
+
+     KEYWORD  ::= 'TRUE' | 'FALSE' | 'NULL' | 'TODAY' | 'NOW'
+     STRING   ::= "'([^'\]|\\.)*'" |'"([^\"]|\\.)*\"'
+     FLOAT    ::= '\d+\.\d*'
+     INT      ::= '\d+'
+
+
+Remarks
+-------
+
+Sorting and groups
+``````````````````
+
+- For grouped queries (e.g. with a GROUPBY clause), all
+  selected variables should be grouped.
+
+- To group and/or sort by attributes, we can do: "X,L user U, U
+  login L GROUPBY L, X ORDERBY L"
+
+- If the sorting method (SORT_METHOD) is not specified, then the sorting is
+  ascendant.
+
+Negation
+````````
+
+* A query such as `Document X WHERE NOT X owned_by U` means "the
+  documents have no relation `owned_by`".
+* But the query `Document X WHERE NOT X owned_by U, U login "syt"`
+  means "the documents have no relation `owned_by` with the user
+  syt". They may have a relation "owned_by" with another user.
+
+Identity
+````````
+
+You can use the special relation `identity` in a query to
+add an identity constraint between two variables. This is equivalent
+to ``is`` in python::
+
+   Any A WHERE A comments B, A identity B
+
+return all objects that comment themselves. The relation
+`identity` is especially useful when defining the rules for securities
+with `RQLExpressions`.
+
+Implementation
+==============
+
+Internal representation (syntactic tree)
+----------------------------------------
+
+The tree research does not contain the selected variables
+(e.g. there is only what follows "WHERE").
+
+The insertion tree does not contain the variables inserted or relations
+defined on these variables (e.g. there is only what follows "WHERE").
+
+The removal tree does not contain the deleted variables and relations
+(e.g. there is only what follows the "WHERE").
+
+The update tree does not contain the variables and relations updated
+(e.g. there is only what follows the "WHERE").
+
+::
+
+     Select         ((Relationship | And | Gold)?, Group?, Sort?)
+     Insert         (Relations | And | Gold)?
+     Delete         (Relationship | And | Gold)?
+     Update         (Relations | And | Gold)?
+
+     And            ((Relationship | And | Gold), (Relationship | And | Gold))
+     Or             ((Relationship | And | Gold), (Relationship | And | Gold))
+
+     Relationship   ((VariableRef, Comparison))
+
+     Comparison     ((Function | MathExpression | Keyword | Constant | VariableRef) +)
+
+     Function       (())
+     MathExpression ((MathExpression | Keyword | Constant | VariableRef), (MathExpression | Keyword | Constant | VariableRef))
+
+     Group          (VariableRef +)
+     Sort           (SortTerm +)
+     SortTerm       (VariableRef +)
+
+     VariableRef    ()
+     Variable       ()
+     Keyword        ()
+     Constant       ()
+
+
+Remarks
+-------
+
+- The current implementation does not support linking two relations of type
+  'is' with a OR. I do not think that the negation is  supported on this type
+  of relation (XXX FIXME to be confirmed).
+
+- Relations defining the variables must be left to those using them.
+  For example::
+
+     Point P where P abs X, P ord Y, P value X+Y
+
+   is valid, but::
+
+     Point P where P abs X, P value X+Y, P ord Y
+
+   is not.
+
+
+
+Conclusion
+==========
+
+Limitations
+-----------
+
+It lacks at the moment:
+
+- COALESCE
+
+- restrictions on groups (HAVING)
+
+and certainly other things ...
+
+A disadvantage is that to use this language we must know the
+format used (with real relation names and entities, not those viewing
+in the user interface). On the other hand, we can not really bypass
+that, and it is the job of a user interface to hide the RQL.
+
+
+Topics
+------
+
+It would be convenient to express the schema matching
+relations (non-recursive rules)::
+
+     Document class Type <-> Document occurence_of Fiche class Type
+     Sheet class Type    <-> Form collection Collection class Type
+
+Therefore 1. becomes::
+
+     Document X where
+     X class C, C name 'Cartoon'
+     X owned_by U, U login 'syt'
+     X available true
+
+I'm not sure that we should handle this at RQL level ...
+
+There should also be a special relation 'anonymous'.
+
+
+
+.. _Versa: Http://uche.ogbuji.net/tech/rdf/versa/
+.. _RDFQL: Http://www.w3.org/TandS/QL/QL98/pp/rdfquery.html
+
--- a/docs/specifications_en.txt	Fri Dec 13 05:36:22 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,588 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-
-===================================================
-Specification "Relations Query Language" (Hercules)
-===================================================
-
-Introduction
-============
-
-Goals RQL
----------
-
-The goal is to have a language emphasizing the way of browsing
-relations. As such, attributes will be regarded as cases of
-special relations (in terms of implementation, the user
-language not to see virtually no difference between an attribute and a
-relation).
-
-RQL is inspired by SQL but is the highest level. A knowledge of the
-`CubicWeb` schema defining the application is necessary.
-
-Comparison with existing languages
-----------------------------------
-
-SQL
-```
-RQL builds on the features of SQL but is at a higher level
-(the current implementation of RQL generates SQL). For that it is limited
-to the way of browsing relations and introduces variables.
-The user does not need to know the model underlying SQL, but the `CubicWeb`
-scheam defining the application.
-
-Versa
-`````
-Should I look in more detail, but here is already some ideas for
-the moment ... Versa_ is the language most similar to what we wanted
-to do, but the model underlying data being RDF, there is some
-number of things such as namespaces or handling of the RDF types which
-does not interest us. On the functionality level, Versa_ is very comprehensive
-including through many functions of conversion and basic types manipulation,
-which may need to be guided at one time or another.
-Finally, the syntax is a little esoteric.
-
-See also
-``````````
-RDFQL_
-
-
-The different types of queries
-------------------------------
-
-Search ( `Any`)
-   This type of query can extract entities and attributes of entities.
-
-Inserting entities ( `INSERT`)
-   This type of query is used to insert new entities in the database. It
-   will also create direct relationships entities newly created.
-
-Update entities, relations creation( `SET`)
-   This type of query updates existing entities in the database,
-   or create relations between existing entities.
-
-Deletion of entities or relationship ( `DELETE`)
-   This type of query allows for the removal of entities and relations existing
-   in the database.
-
-
-
-Examples
-========
-
-(see the tutorial: ref: `tutorielRQL` for more examples)
-
-Search Query
-------------
-
-   [ `DISTINCT`] <entity type> V1 (V2) \ *
-   [ `GROUPBY` V1 (V2) \*] [ `ORDERBY` <orderterms>]
-   [ `WHERE` <restriction>]
-   [ `LIMIT` <value>] [ `OFFSET` <value>]
-
-:entity type:
-   Type of selected variables.
-   The special type `Any` is equivalent to not specify a type.
-:restriction:
-   list of relations to go through whic follow the pattern
-     `V1 relation V2 | <static value>`
-:orderterms:
-   Definition of the selection order: variable or column number followed by
-   sorting method ( `ASC`, `DESC`), ASC is the default.
-:note for grouped queries:
-   For grouped queries (e.g., a clause `GROUPBY`), all
-   selected variables must be aggregated or grouped.
-
-
-
-- *Search for the object of identifier 53*
-   ::
-
-        Any WHERE X
-        X eid 53
-
-- *Search material such as comics, owned by syt and available*
-   ::
-
-        WHERE X Document
-        X occurence_of F, F class C, C name 'Comics'
-        X owned_by U, U login 'syt'
-        X available true
-
-- *Looking for people working for eurocopter interested in training*
-   ::
-
-        Person P WHERE
-        P work_for P, S name 'Eurocopter'
-        P interested_by T, T name 'training'
-
-- *Search note less than 10 days old written by jphc or ocy*
-   ::
-
-        Note N WHERE
-        N written_on D, D day> (today -10),
-        N written_by P, P name 'jphc' or P name 'ocy'
-
-- *Looking for people interested in training or living in Paris*
-   ::
-
-        Person P WHERE
-        (P interested_by T, T name 'training') or
-        (P city 'Paris')
-
-- *The name and surname of all people*
-   ::
-
-        Any N, P WHERE
-        X is Person, X name N, X first_name P
-
-   Note that the selection of several entities generally force
-   the use of "Any" because the type specification applies otherwise
-   to all the selected variables. We could write here
-   ::
-
-        String N, P WHERE
-        X is Person, X name N, X first_name P
-
-
-Insertion query
----------------
-
-    `INSERT` <entity type> V1 (, <entity type> V2) \ * `:` <assignments>
-    [ `WHERE` <restriction>]
-
-: assignments:
-   list of relations to assign in the form `V1 relationship V2 | <static value>`
-
-The restriction can define variables used in assignments.
-
-Caution, if a restriction is specified, the insertion is done for
-*each line results returned by the restriction*.
-
-- *Insert a new person named 'foo'*
-   ::
-
-        INSERT Person X: X name 'widget'
-
-- *Insert a new person named 'foo', another called 'nice' and a 'friend' relation
-  between them*
-  ::
-
-        INSERT Person X, Person Y: X name 'foo', Y name 'nice', X friend Y
-
-- *Insert a new person named 'foo' and a 'friend' relation with an existing
-  person called 'nice'*
-  ::
-
-        INSERT Person X: X name 'foo', X friend  Y WHERE name 'nice'
-
-Update and relation creation queries
-------------------------------------
-    `SET` <assignements>
-    [ `WHERE` <restriction>]
-
-Caution, if a restriction is specified, the update is done *for
-each line results returned by the restriction*.
-
-- *Renaming of the person named 'foo' to 'bar' with the first name changed*
-  ::
-
-        SET X name 'bar', X first_name 'original' where X is Person X name 'foo'
-
-- *Insert a relation of type 'know' between objects linked by
-  the relation of type 'friend'*
-  ::
-
-        SET X know Y  WHERE X friend Y
-
-
-Deletion query
---------------
-    `DELETE` (<entity type> V) | (V1 relation v2 ),...
-    [ `WHERE` <restriction>]
-
-Caution, if a restriction is specified, the deletion is made *for
-each line results returned by the restriction*.
-
-- *Deletion of the person named 'foo'*
-  ::
-
-        DELETE Person X WHERE X name 'foo'
-
-- *Removal of all relations of type 'friend' from the person named 'foo'*
-  ::
-
-        DELETE X friend Y WHERE X is Person, X name 'foo'
-
-
-
-Language definition
-===================
-
-Reserved keywords
------------------
-The keywords are not case sensitive.
-
-::
-
-     DISTINCT, INSERT, SET, DELETE,
-     WHERE, AND, OR, NOT
-     IN, LIKE, ILIKE,
-     TRUE, FALSE, NULL, TODAY, NOW
-     GROUPBY, ORDERBY, ASC, DESC
-
-
-Variables and Typing
---------------------
-
-With RQL, we do not distinguish between entities and attributes. The
-value of an attribute is considered an entity of a particular type (see
-below), linked to one (real) entity by a relation called the name of
-the attribute.
-
-Entities and values to browse and/or select are represented in
-the query by *variables* that must be written in capital letters.
-
-There is a special type **Any**, referring to a non specific type.
-
-We can restrict the possible types for a variable using the
-special relation **is**.
-The possible type(s) for each variable is derived from the schema
-according to the constraints expressed above and thanks to the relations between
-each variable.
-
-Built-in types
-``````````````
-
-The base types supported are string (between double or single quotes),
-integers or floats (the separator is the'.'), dates and
-boolean. We expect to receive a schema in which types String,
-Int, Float, Date and Boolean are defined.
-
-* `String` (literal: between double or single quotes).
-* `Int`, `Float` (separator being'.').
-* `Date`, `Datetime`, `Time` (literal: string YYYY/MM/DD [hh:mm] or keywords
-   `TODAY` and `NOW`).
-* `Boolean` (keywords `TRUE` and `FALSE`).
-* `Keyword` NULL.
-
-
-Operators
----------
-
-Logical Operators
-```````````````````
-::
-
-     AND, OR, ','
-
-',' is equivalent to 'AND' but with the smallest among the priority
-of logical operators (see :ref:`PriorityOperators`).
-
-Mathematical Operators
-``````````````````````
-::
-
-     +, -, *, /
-
-Comparison operators
-````````````````````
-::
-
-     =, <, <=, >=, > = ~, IN, LIKE, ILIKE
-
-* The operator `=` is the default operator.
-
-* The operator `LIKE` equivalent to `~=` can be used with the
-  special character `%` in a string to indicate that the chain
-  must start or finish by a prefix/suffix:
-  ::
-
-     Any X WHERE X name =~ 'Th%'
-     Any X WHERE X name LIKE '%lt'
-
-* The operator `ILIKE` is a case-insensitive version of `LIKE`.
-
-* The operator `IN` provides a list of possible values:
-  ::
-
-    Any X WHERE X name IN ( 'chauvat', 'fayolle', 'di mascio', 'thenault')
-
-
-XXX nico: A trick <> 'bar' would not it be more convenient than NOT A
-trick 'bar'?
-
-.. _PriorityOperators:
-
-Operators priority
-``````````````````
-
-1. '*', '/'
-
-2. '+', '-'
-
-3. 'and'
-
-4. 'or'
-
-5. ','
-
-
-Advanced Features
------------------
-
-Functions aggregates
-````````````````````
-::
-
-     COUNT, MIN, MAX, AVG, SUM
-
-Functions on string
-```````````````````
-::
-
-     UPPER, LOWER
-
-Optional relations
-``````````````````
-
-* They allow you to select entities related or not to another.
-
-* You must use the `?` behind the variable to specify that the relation
-  toward it is optional:
-
-   - Anomalies of a project attached or not to a version ::
-
-       Any X, V WHERE X concerns P, P eid 42, X corrected_in V?
-
-   - All cards and the project they document if necessary ::
-
-       Any C, P WHERE C is Card, P? documented_by C
-
-
-
-BNF grammar
------------
-
-The terminal elements are in capital letters, non-terminal in lowercase.
-The value of the terminal elements (between quotes) is a Python regular
-expression.
-::
-
-     statement:: = (select | delete | insert | update) ';'
-
-
-     # select specific rules
-     select      ::= 'DISTINCT'? E_TYPE selected_terms restriction? group? sort?
-
-     selected_terms ::= expression ( ',' expression)*
-
-     group       ::= 'GROUPBY' VARIABLE ( ',' VARIABLE)*
-
-     sort        ::= 'ORDERBY' sort_term ( ',' sort_term)*
-
-     sort_term   ::=  VARIABLE sort_method =?
-
-     sort_method ::= 'ASC' | 'DESC'
-
-
-     # delete specific rules
-     delete ::= 'DELETE' (variables_declaration | relations_declaration) restriction?
-
-
-     # insert specific rules
-     insert ::= 'INSERT' variables_declaration ( ':' relations_declaration)? restriction?
-
-
-     # update specific rules
-     update ::= 'SET' relations_declaration restriction
-
-
-     # common rules
-     variables_declaration ::= E_TYPE VARIABLE (',' E_TYPE VARIABLE)*
-
-     relations_declaration ::= simple_relation (',' simple_relation)*
-
-     simple_relation ::= VARIABLE R_TYPE expression
-
-     restriction ::= 'WHERE' relations
-
-     relations   ::= relation (LOGIC_OP relation)*
-                   | '(' relations')'
-
-     relation    ::= 'NOT'? VARIABLE R_TYPE COMP_OP? expression
-                   | 'NOT'? R_TYPE VARIABLE 'IN' '(' expression (',' expression)* ')'
-
-     expression  ::= var_or_func_or_const (MATH_OP var_or_func_or_const) *
-                   | '(' expression ')'
-
-     var_or_func_or_const ::= VARIABLE | function | constant
-
-     function    ::= FUNCTION '(' expression ( ',' expression) * ')'
-
-     constant    ::= KEYWORD | STRING | FLOAT | INT
-
-     # tokens
-     LOGIC_OP ::= ',' | 'GOLD' | 'AND'
-     MATH_OP  ::= '+' | '-' | '/' | '*'
-     COMP_OP  ::= '>' | '>=' | '=' | '<=' | '<' | '~=' | 'LIKE' | 'ILIKE'
-
-     FUNCTION ::= 'MIN' | 'MAX' | 'SUM' | 'AVG' | 'COUNT' | 'upper' | 'LOWER'
-
-     VARIABLE ::= '[A-Z][A-Z0-9]*'
-     E_TYPE   ::= '[A-Z]\w*'
-     R_TYPE   ::= '[a-z_]+'
-
-     KEYWORD  ::= 'TRUE' | 'FALSE' | 'NULL' | 'TODAY' | 'NOW'
-     STRING   ::= "'([^'\]|\\.)*'" |'"([^\"]|\\.)*\"'
-     FLOAT    ::= '\d+\.\d*'
-     INT      ::= '\d+'
-
-
-Remarks
--------
-
-Sorting and groups
-``````````````````
-
-- For grouped queries (e.g. with a GROUPBY clause), all
-  selected variables should be grouped.
-
-- To group and/or sort by attributes, we can do: "X,L user U, U
-  login L GROUPBY L, X ORDERBY L"
-
-- If the sorting method (SORT_METHOD) is not specified, then the sorting is
-  ascendant.
-
-Negation
-````````
-
-* A query such as `Document X WHERE NOT X owned_by U` means "the
-  documents have no relation `owned_by`".
-* But the query `Document X WHERE NOT X owned_by U, U login "syt"`
-  means "the documents have no relation `owned_by` with the user
-  syt". They may have a relation "owned_by" with another user.
-
-Identity
-````````
-
-You can use the special relation `identity` in a query to
-add an identity constraint between two variables. This is equivalent
-to ``is`` in python::
-
-   Any A WHERE A comments B, A identity B
-
-return all objects that comment themselves. The relation
-`identity` is especially useful when defining the rules for securities
-with `RQLExpressions`.
-
-Implementation
-==============
-
-Internal representation (syntactic tree)
-----------------------------------------
-
-The tree research does not contain the selected variables
-(e.g. there is only what follows "WHERE").
-
-The insertion tree does not contain the variables inserted or relations
-defined on these variables (e.g. there is only what follows "WHERE").
-
-The removal tree does not contain the deleted variables and relations
-(e.g. there is only what follows the "WHERE").
-
-The update tree does not contain the variables and relations updated
-(e.g. there is only what follows the "WHERE").
-
-::
-
-     Select         ((Relationship | And | Gold)?, Group?, Sort?)
-     Insert         (Relations | And | Gold)?
-     Delete         (Relationship | And | Gold)?
-     Update         (Relations | And | Gold)?
-
-     And            ((Relationship | And | Gold), (Relationship | And | Gold))
-     Or             ((Relationship | And | Gold), (Relationship | And | Gold))
-
-     Relationship   ((VariableRef, Comparison))
-
-     Comparison     ((Function | MathExpression | Keyword | Constant | VariableRef) +)
-
-     Function       (())
-     MathExpression ((MathExpression | Keyword | Constant | VariableRef), (MathExpression | Keyword | Constant | VariableRef))
-
-     Group          (VariableRef +)
-     Sort           (SortTerm +)
-     SortTerm       (VariableRef +)
-
-     VariableRef    ()
-     Variable       ()
-     Keyword        ()
-     Constant       ()
-
-
-Remarks
--------
-
-- The current implementation does not support linking two relations of type
-  'is' with a OR. I do not think that the negation is  supported on this type
-  of relation (XXX FIXME to be confirmed).
-
-- Relations defining the variables must be left to those using them.
-  For example::
-
-     Point P where P abs X, P ord Y, P value X+Y
-
-   is valid, but::
-
-     Point P where P abs X, P value X+Y, P ord Y
-
-   is not.
-
-
-
-Conclusion
-==========
-
-Limitations
------------
-
-It lacks at the moment:
-
-- COALESCE
-
-- restrictions on groups (HAVING)
-
-and certainly other things ...
-
-A disadvantage is that to use this language we must know the
-format used (with real relation names and entities, not those viewing
-in the user interface). On the other hand, we can not really bypass
-that, and it is the job of a user interface to hide the RQL.
-
-
-Topics
-------
-
-It would be convenient to express the schema matching
-relations (non-recursive rules)::
-
-     Document class Type <-> Document occurence_of Fiche class Type
-     Sheet class Type    <-> Form collection Collection class Type
-
-Therefore 1. becomes::
-
-     Document X where
-     X class C, C name 'Cartoon'
-     X owned_by U, U login 'syt'
-     X available true
-
-I'm not sure that we should handle this at RQL level ...
-
-There should also be a special relation 'anonymous'.
-
-
-
-.. _Versa: Http://uche.ogbuji.net/tech/rdf/versa/
-.. _RDFQL: Http://www.w3.org/TandS/QL/QL98/pp/rdfquery.html
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/specifications_fr.rst	Fri Dec 13 05:54:11 2019 +0100
@@ -0,0 +1,588 @@
+.. -*- coding: utf-8 -*-
+
+=================================================
+Spécification "Relation Query Language" (Hercule)
+=================================================
+
+:Author: Sylvain Thénault
+:Organization: Logilab
+:Version: $Revision: 1.10 $
+:Date: $Date: 2004-05-18 15:04:13 $
+
+Introduction
+============
+
+Objectifs de RQL
+----------------
+
+L'objectif est d'avoir un langage mettant l'accent sur le parcours de
+relations. A ce titre les attributs seront donc considérés comme des cas
+particuliers de relations (au niveau de l'implémentation, l'utilisateur du
+langage ne devant quasiment pas voir de différence entre un attribut et une
+relation).
+
+RQL s'inspire de SQL mais se veut plus haut niveau. Une connaissance du schéma
+Cubicweb définissant l'application est nécessaire.
+
+
+Comparaison avec des langages existants
+---------------------------------------
+
+SQL
+```
+RQL s'inspire des fonctionnalités de SQL mais se veut à un plus haut niveau
+(l'implémentation actuelle de RQL génère du SQL). Pour cela il se limite au
+parcours de relations et introduit des variables. L'utilisateur n'a pas besoin
+de connaitre le modèle SQL sous-jacent, mais uniquement le schéma Erudi
+définissant l'application.
+
+Versa
+`````
+Faudrait que je regarde plus en détail, mais voilâ déja quelques idées pour
+l'instant...  Versa_ est le langage ressemblant le plus à ce que nous voulions
+faire, mais le modèle de donnée sous-jacent étant du RDF, il y a un certain
+nombre de choses tels que les namespaces ou la manipulation des types RDF qui
+ne nous intéressent pas. Niveau fonctionnalité, Versa_ est très complet
+notamment grâce à de nombreuses fonctions de conversion et de manipulations
+des types de base, dont il faudra peut-être s'inspirer à un moment ou à
+l'autre.  Enfin, La syntaxe est un peu ésotérique.
+
+Voir aussi
+``````````
+RDFQL_
+
+
+Les différents types de requêtes
+--------------------------------
+
+Recherche (`Any`)
+  Ce type de requête permet d'extraire des entités ou des attributs d'entités.
+
+Insertion d'entités (`INSERT`)
+  Ce type de requête permet d'insérer de nouvelles entités dans la base. On
+  permettra également la création directe de relations sur les entités
+  nouvellement créées.
+
+Mise à jour d'entités, création de relations (`SET`)
+  Ce type de requête permet de mettre à jours des entités existantes dans la base,
+  ou de créer des relations entres des entités existantes.
+
+Suppression d'entités ou de relation (`DELETE`)
+  Ce type de requête permet de supprimer des entités et relations existantes dans
+  la base.
+
+
+
+Exemples
+========
+
+(voir le tutoriel :ref:`tutorielRQL` pour plus d'exemples)
+
+Requête de recherche
+--------------------
+
+  [`DISTINCT`] <type d'entité> V1(, V2)\*
+  [`GROUPBY` V1(, V2)\*]  [`ORDERBY` <orderterms>]
+  [`WHERE` <restriction>] 
+  [`LIMIT` <value>] [`OFFSET` <value>]
+
+:type d'entité:
+  Type de la ou des variables séléctionnées. 
+  Le type spécial `Any`, revient à ne pas spécifier de type.
+:restriction:
+  liste des relations à parcourir sous la forme 
+    `V1 relation V2|<valeur constante>`
+:orderterms:
+  Définition de l'ordre de selection : variable ou n° de colonne suivie de la
+  méthode de tri (`ASC`, `DESC`), ASC étant la valeur par défaut.
+:note pour les requêtes groupées:
+  Pour les requêtes groupées (i.e. avec une clause `GROUPBY`), toutes les
+  variables sélectionnée doivent être soit groupée soit aggrégée.
+
+
+
+- *recherche de l'objet ayant l'identifiant 53*
+  ::
+
+       Any X WHERE 
+       X eid 53 
+
+- *recherche des documents de type bande dessinée, appartenant à syt et disponible*
+  ::
+
+       Document X WHERE 
+       X occurence_of F, F class C, C name 'Bande dessinée',
+       X owned_by U, U login 'syt',
+       X available true
+
+- *recherche des personnes travaillant pour eurocopter intéressé par la formation*
+  ::
+
+       Personne P WHERE
+       P travaille_pour S, S nom 'Eurocopter',
+       P interesse_par T, T nom 'formation'
+
+- *recherche des notes de moins de 10 jours écrites par jphc ou ocy*
+  ::
+
+       Note N WHERE
+       N ecrit_le D, D day > (today -10), 
+       N ecrit_par P, P nom 'jphc' or P nom 'ocy'
+
+- *recherche des personnes intéressées par la formation ou habitant à Paris*
+  ::
+
+       Personne P WHERE
+       (P interesse_par T, T nom 'formation') or
+       (P ville 'Paris')
+
+- *Le nom et le prénom de toutes les personnes*
+  ::
+
+       Any N, P WHERE
+       X is Personne, X nom N, X prenom P
+
+  On remarquera que la selection de plusieurs entités force généralement
+  l'utilisation de "Any", car la spécification de type s'applique sinon
+  à toutes les variables séléctionnées. On aurait pu écrire ici 
+  ::
+
+       String N, P WHERE
+       X is Personne, X nom N, X prenom P
+
+
+Requête d'insertion
+-------------------
+   `INSERT` <type d'entité> V1(, <type d'entité> V2)\* `:` <assignements>
+   [`WHERE` <restriction>] 
+
+:assignements:
+  liste des relations à assigner sous la forme `V1 relation V2|<valeur constante>`
+
+La restriction permet de définir des variables utilisées dans les assignements.
+
+Attention, si une restriction est spécifiée, l'insertion est effectuée *pour
+chaque ligne de résultat renvoyée par la restriction*.
+
+- *insertion d'une nouvelle personne nommée 'bidule'*
+  ::
+
+       INSERT Personne X: X nom 'bidule'
+
+- *insertion d'une nouvelle personne nommée 'bidule', d'une autre nommée 'chouette' et d'une relation 'ami' entre eux*
+  ::
+
+       INSERT Personne X, Personne Y: X nom 'bidule', Y nom 'chouette', X ami Y
+
+- *insertion d'une nouvelle personne nommée 'bidule' et d'une relation 'ami' avec une personne existante nommée 'chouette'*
+  ::
+
+       INSERT Personne X: X nom 'bidule', X ami Y WHERE Y nom 'chouette'
+
+
+Requête de mise à jour, création de relations
+---------------------------------------------
+   `SET` <assignements>
+   [`WHERE` <restriction>] 
+
+Attention, si une restriction est spécifiée, la mise à jour est effectuée *pour
+chaque ligne de résultat renvoyée par la restriction*.
+
+- *renommage de la personne nommée 'bidule' en 'toto', avec modification du prénom*
+  ::
+
+       SET X nom 'toto', X prenom 'original' WHERE X is Person, X nom 'bidule'
+
+- *insertion d'une relation de type 'connait' entre les objets reliés par la relation de type 'ami'*
+  ::
+
+       SET X know Y WHERE X ami Y
+
+
+Requête de suppression
+----------------------
+   `DELETE` (<type d''entité> V) | (V1 relation v2),...
+   [`WHERE` <restriction>] 
+
+Attention, si une restriction est spécifiée, la suppression est effectuée *pour
+chaque ligne de résultat renvoyée par la restriction*.
+
+- *supression de la personne nommé 'toto'*
+  ::
+
+       DELETE Person X WHERE X nom 'toto'
+
+- *suppression de toutes les relations de type 'ami' partant de la personne nommée 'toto'*
+  ::
+
+       DELETE X ami Y WHERE X is Person, X nom 'toto'
+
+
+
+Définition du langage
+=====================
+
+Mots clés réservés
+------------------
+Les mots clés ne sont pas sensibles à la casse.
+
+::
+
+    DISTINCT, INSERT, SET, DELETE,
+    WHERE, AND, OR, NOT
+    IN, LIKE, ILIKE,
+    TRUE, FALSE, NULL, TODAY, NOW
+    GROUPBY, ORDERBY, ASC, DESC
+
+
+Variables et Typage
+-------------------
+
+Au niveau de RQL, on ne fait pas de distinction entre entités et attributs. La
+valeur d'un attribut est considérée comme une entité d'un type particulier (voir
+ci-dessous), lié à une (vraie) entité par une relation du nom de l'attribut.
+
+Les entités et valeurs à parcourir et / ou séléctionner sont représentées dans
+la requête par des *variables* qui doivent être écrites en majuscule.
+
+Il existe un type spécial **Any**, revenant à ne pas spécifier de type.
+
+On peut contraindre les types possibles pour une variable à l'aide de la
+relation spéciale **is**.
+
+Le(s) type(s) possible(s) pour chaque variable est déduit du schema en
+fonction des contraintes exprimées ci-dessus et à l'aide des relations entre
+chaque variable.
+
+Types de bases
+``````````````
+
+Les types de bases supportés sont les chaines (entre doubles ou simples quotes),
+les nombres entiers ou flottant (le séparateur étant le '.'), les dates et les
+booléens. On s'attend donc à recevoir un schéma dans lequel les types String,
+Int, Float, Date et Boolean sont définis.
+
+* `String` (litéral: entre doubles ou simples quotes).
+* `Int`, `Float` (le séparateur étant le '.').
+* `Date`, `Datetime`, `Time` (litéral: chaîne YYYY/MM/DD[ hh:mm] ou mots-clés
+  `TODAY` et `NOW`).
+* `Boolean` (mots-clés `TRUE` et `FALSE`).
+* mot-clé `NULL`.
+
+
+Opérateurs
+----------
+
+Opérateurs logiques
+```````````````````
+::
+
+    AND, OR, ','
+
+"," est équivalent à "AND" mais avec la plus petite priorité parmi les
+opérateurs logiques (voir `Priorité des opérateurs`_).
+
+Opérateurs mathématiques
+````````````````````````
+::
+
+    +, -, *, /
+
+Opérateurs de comparaison
+`````````````````````````
+::
+
+    =, <, <=, >=, >, ~=, IN, LIKE, ILIKE
+
+* L'opérateur `=` est l'opérateur par défaut.
+
+* L'opérateur `LIKE` équivalent à `~=` permet d'utiliser le caractère `%` dans
+  une chaine de caractère pour indiquer que la chaîne doit commencer ou terminer
+  par un préfix/suffixe::
+
+    Any X WHERE X nom ~= 'Th%'
+    Any X WHERE X nom LIKE '%lt'
+
+* L'opérateur `ILIKE` est une version de `LIKE` qui n'est pas sensible à la
+  casse.
+
+* L'opérateur `IN` permet de donner une liste de valeurs possibles::
+
+    Any X WHERE X nom IN ('chauvat', 'fayolle', 'di mascio', 'thenault')
+
+
+XXX nico: A truc <> 'titi' ne serait-il pas plus pratique que NOT A
+truc 'titi' ?
+
+Priorité des opérateurs
+```````````````````````
+
+1. '*', '/'
+
+2. '+', '-'
+
+3. 'and'
+
+4. 'or'
+
+5. ','
+
+
+Fonctionnalités avancées
+------------------------
+
+Fonctions d'aggrégat
+````````````````````
+::
+
+    COUNT, MIN, MAX, AVG, SUM
+
+Fonctions sur les chaines
+`````````````````````````
+::
+
+    UPPER, LOWER
+
+Relations optionnelles
+``````````````````````
+
+* Elles permettent de sélectionner des entités liées ou non à une autre.
+
+* Il faut utiliser le `?` derrière la variable pour spécifier que la relation
+  vers celle-ci est optionnelle :
+
+  - Anomalies d'un projet attachées ou non à une version ::
+
+      Any X,V WHERE X concerns P, P eid 42, X corrected_in V?
+
+  - Toutes les fiches et le projet qu'elles documentent le cas échéant ::
+
+      Any C,P WHERE C is Card, P? documented_by C
+
+
+
+Grammaire BNF
+-------------
+Les éléments terminaux sont en majuscules, les non-terminaux en minuscule. La
+valeur des éléments terminaux (entre quotes) correspond à une expression
+régulière Python.
+:: 
+
+    statement ::= (select | delete | insert | update) ';'
+
+
+    # select specific rules
+    select ::= 'DISTINCT'? E_TYPE selected_terms restriction? group? sort?
+
+    selected_terms ::= expression (',' expression)*
+
+    group       ::= 'GROUPBY' VARIABLE (',' VARIABLE)*
+
+    sort        ::= 'ORDERBY' sort_term (',' sort_term)*
+
+    sort_term   ::= VARIABLE sort_method? 
+
+    sort_method ::= 'ASC' | 'DESC'
+
+
+    # delete specific rules
+    delete ::= 'DELETE' (variables_declaration | relations_declaration) restriction?
+
+
+    # insert specific rules
+    insert ::= 'INSERT' variables_declaration (':' relations_declaration)? restriction?
+
+
+    # update specific rules
+    update ::= 'SET' relations_declaration restriction
+
+
+    # common rules
+    variables_declaration ::= E_TYPE VARIABLE (',' E_TYPE VARIABLE)*
+
+    relations_declaration ::= simple_relation (',' simple_relation)*
+
+    simple_relation ::= VARIABLE R_TYPE expression
+
+    restriction ::= 'WHERE' relations
+
+    relations   ::= relation (LOGIC_OP relation)*
+                  | '(' relations ')'
+
+    relation ::= 'NOT'? VARIABLE R_TYPE COMP_OP? expression 
+               | 'NOT'? VARIABLE R_TYPE 'IN' '(' expression (',' expression)* ')'
+    
+    expression ::= var_or_func_or_const (MATH_OP var_or_func_or_const)*
+                 | '(' expression ')'
+
+    var_or_func_or_const ::= VARIABLE | function | constant
+
+    function ::= FUNCTION '(' expression (',' expression)* ')'
+
+    constant ::= KEYWORD | STRING | FLOAT | INT
+
+    # tokens
+    LOGIC_OP ::= ',' | 'OR' | 'AND'
+    MATH_OP  ::= '+' | '-' | '/' | '*'
+    COMP_OP  ::= '>' | '>=' | '=' | '<=' | '<' | '~=' | 'LIKE' 
+
+    FUNCTION ::= 'MIN' | 'MAX' | 'SUM' | 'AVG' | 'COUNT' | 'UPPER' | 'LOWER'
+
+    VARIABLE ::= '[A-Z][A-Z0-9]*'
+    E_TYPE   ::= '[A-Z]\w*'
+    R_TYPE   ::= '[a-z_]+'
+
+    KEYWORD  ::= 'TRUE' | 'FALSE' | 'NULL' | 'TODAY' | 'NOW'
+    STRING   ::= "'([^'\]|\\.)*'" | '"([^\"]|\\.)*\"'
+    FLOAT    ::= '\d+\.\d*'
+    INT      ::= '\d+'
+
+
+Remarques
+---------
+
+Tri et groupes
+``````````````
+
+- pour les requêtes groupées (i.e. avec une clause GROUPBY), toutes les
+  variables sélectionnées doivent être groupées
+
+- pour grouper ou/et trier sur les attributs on peut faire : "X,L user U, U
+  login L GROUPBY L,X ORDERBY L"
+
+- si la méthode de tri (SORT_METHOD) n'est pas précisée, alors le tri est
+  ascendant.
+
+Négation
+````````
+
+* Une requête du type `Document X WHERE NOT X owned_by U` revient à dire "les
+  documents n'ayant pas de relation `owned_by`". 
+* En revanche la requête `Document X WHERE NOT X owned_by U, U login "syt"`
+  revient à dire "les  documents n'ayant pas de relation `owned_by` avec
+  l'utilisateur syt". Ils peuvent avoir une relation "owned_by" avec un autre
+  utilisateur.
+
+Identité
+````````
+
+On peut utiliser la relation spéciale `identity` dans une requête pour
+rajouter une contrainte d'identité entre deux variables. C'est l'équivalent
+du ``is`` en python::
+
+  Any A WHERE A comments B, A identity B
+
+retournerait l'ensemble des objets qui se commentent eux-mêmes. La relation
+`identity` est surtout pratique lors de la définition des règles de sécurités
+avec des `RQLExpressions`.
+
+Implémentation
+==============
+
+Représentation interne (arbre syntaxique)
+-----------------------------------------
+
+L'arbre de recherche ne contient pas les variables sélectionnées (i.e. on n'y 
+trouve que ce qui suit le "WHERE").
+
+L'arbre d'insertion ne contient pas les variables insérées ni les relations 
+définies sur ces variables (i.e. on n'y trouve que ce qui suit le
+"WHERE").
+
+L'arbre de suppression ne contient pas les variables ou relations supprimées 
+(i.e. on n'y trouve que ce qui suit le "WHERE").
+
+L'arbre de mise à jour ne contient pas les variables ou relations mises à jour
+(i.e. on n'y trouve que ce qui suit le "WHERE").
+
+::
+
+    Select         ((Relation|And|Or)?, Group?, Sort?)
+    Insert         (Relation|And|Or)?
+    Delete         (Relation|And|Or)?
+    Update         (Relation|And|Or)?
+
+    And            ((Relation|And|Or), (Relation|And|Or))
+    Or             ((Relation|And|Or), (Relation|And|Or))
+
+    Relation       ((VariableRef, Comparison))
+
+    Comparison     ((Function|MathExpression|Keyword|Constant|VariableRef)+)
+
+    Function       (())
+    MathExpression ((MathExpression|Keyword|Constant|VariableRef), (MathExpression|Keyword|Constant|VariableRef))
+
+    Group          (VariableRef+)
+    Sort           (SortTerm+)
+    SortTerm       (VariableRef+)
+
+    VariableRef ()
+    Variable    ()
+    Keyword     ()
+    Constant    ()
+
+
+Remarques
+---------
+
+- l'implémentation actuelle ne supporte pas de lier deux relations ayant comme
+  type de relation 'is' avec un OR. Je ne pense pas que la négation ne
+  soit supportée non plus sur ce type de relation (à confirmer).
+
+- les relations définissant les variables doivent être à gauche de celles les
+  utilisant. Par exemple ::
+
+    Point P where P abs X, P ord Y, P value X+Y
+
+  est valide, mais ::
+
+    Point P where P abs X, P value X+Y, P ord Y
+
+  ne l'est pas.
+
+
+
+Conclusion
+==========
+
+Limitations
+-----------
+
+Il manque pour l'instant:
+
+- COALESCE
+
+- restriction sur les groupes (HAVING)
+
+et certainement d'autres choses...
+
+Un inconvénient est que pour utiliser ce langage il faut bien connaitre le
+schéma utilisé (avec les vrais noms de relations et d'entités, pas ceux affichés
+dans l'interface utilisateur). D'un autre coté, on peut pas vraiment contourner
+cela, et c'est le boulot d'une interface utilisateur de cacher le RQL.
+
+
+Sujets de réflexion
+-------------------
+
+Il serait pratique de pouvoir exprimer dans le schema des correspondances de
+relations (règles non récursives)::
+
+    Document class Type <-> Document occurence_of Fiche class Type
+    Fiche class Type    <-> Fiche collection Collection class Type
+    
+Ainsi 1. devient::
+
+    Document X where 
+    X class C, C name 'Bande dessinée',
+    X owned_by U, U login 'syt',
+    X available true
+
+Je ne suis cependant pas sûr qu'il faille gérer ça au niveau de RQL...
+
+Il faudrait aussi une relation spéciale 'anonyme'.
+
+
+
+.. _Versa: http://uche.ogbuji.net/tech/rdf/versa/
+.. _RDFQL: http://www.w3.org/TandS/QL/QL98/pp/rdfquery.html
--- a/docs/specifications_fr.txt	Fri Dec 13 05:36:22 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,588 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-=================================================
-Spécification "Relation Query Language" (Hercule)
-=================================================
-
-:Author: Sylvain Thénault
-:Organization: Logilab
-:Version: $Revision: 1.10 $
-:Date: $Date: 2004-05-18 15:04:13 $
-
-Introduction
-============
-
-Objectifs de RQL
-----------------
-
-L'objectif est d'avoir un langage mettant l'accent sur le parcours de
-relations. A ce titre les attributs seront donc considérés comme des cas
-particuliers de relations (au niveau de l'implémentation, l'utilisateur du
-langage ne devant quasiment pas voir de différence entre un attribut et une
-relation).
-
-RQL s'inspire de SQL mais se veut plus haut niveau. Une connaissance du schéma
-Cubicweb définissant l'application est nécessaire.
-
-
-Comparaison avec des langages existants
----------------------------------------
-
-SQL
-```
-RQL s'inspire des fonctionnalités de SQL mais se veut à un plus haut niveau
-(l'implémentation actuelle de RQL génère du SQL). Pour cela il se limite au
-parcours de relations et introduit des variables. L'utilisateur n'a pas besoin
-de connaitre le modèle SQL sous-jacent, mais uniquement le schéma Erudi
-définissant l'application.
-
-Versa
-`````
-Faudrait que je regarde plus en détail, mais voilâ déja quelques idées pour
-l'instant...  Versa_ est le langage ressemblant le plus à ce que nous voulions
-faire, mais le modèle de donnée sous-jacent étant du RDF, il y a un certain
-nombre de choses tels que les namespaces ou la manipulation des types RDF qui
-ne nous intéressent pas. Niveau fonctionnalité, Versa_ est très complet
-notamment grâce à de nombreuses fonctions de conversion et de manipulations
-des types de base, dont il faudra peut-être s'inspirer à un moment ou à
-l'autre.  Enfin, La syntaxe est un peu ésotérique.
-
-Voir aussi
-``````````
-RDFQL_
-
-
-Les différents types de requêtes
---------------------------------
-
-Recherche (`Any`)
-  Ce type de requête permet d'extraire des entités ou des attributs d'entités.
-
-Insertion d'entités (`INSERT`)
-  Ce type de requête permet d'insérer de nouvelles entités dans la base. On
-  permettra également la création directe de relations sur les entités
-  nouvellement créées.
-
-Mise à jour d'entités, création de relations (`SET`)
-  Ce type de requête permet de mettre à jours des entités existantes dans la base,
-  ou de créer des relations entres des entités existantes.
-
-Suppression d'entités ou de relation (`DELETE`)
-  Ce type de requête permet de supprimer des entités et relations existantes dans
-  la base.
-
-
-
-Exemples
-========
-
-(voir le tutoriel :ref:`tutorielRQL` pour plus d'exemples)
-
-Requête de recherche
---------------------
-
-  [`DISTINCT`] <type d'entité> V1(, V2)\*
-  [`GROUPBY` V1(, V2)\*]  [`ORDERBY` <orderterms>]
-  [`WHERE` <restriction>] 
-  [`LIMIT` <value>] [`OFFSET` <value>]
-
-:type d'entité:
-  Type de la ou des variables séléctionnées. 
-  Le type spécial `Any`, revient à ne pas spécifier de type.
-:restriction:
-  liste des relations à parcourir sous la forme 
-    `V1 relation V2|<valeur constante>`
-:orderterms:
-  Définition de l'ordre de selection : variable ou n° de colonne suivie de la
-  méthode de tri (`ASC`, `DESC`), ASC étant la valeur par défaut.
-:note pour les requêtes groupées:
-  Pour les requêtes groupées (i.e. avec une clause `GROUPBY`), toutes les
-  variables sélectionnée doivent être soit groupée soit aggrégée.
-
-
-
-- *recherche de l'objet ayant l'identifiant 53*
-  ::
-
-       Any X WHERE 
-       X eid 53 
-
-- *recherche des documents de type bande dessinée, appartenant à syt et disponible*
-  ::
-
-       Document X WHERE 
-       X occurence_of F, F class C, C name 'Bande dessinée',
-       X owned_by U, U login 'syt',
-       X available true
-
-- *recherche des personnes travaillant pour eurocopter intéressé par la formation*
-  ::
-
-       Personne P WHERE
-       P travaille_pour S, S nom 'Eurocopter',
-       P interesse_par T, T nom 'formation'
-
-- *recherche des notes de moins de 10 jours écrites par jphc ou ocy*
-  ::
-
-       Note N WHERE
-       N ecrit_le D, D day > (today -10), 
-       N ecrit_par P, P nom 'jphc' or P nom 'ocy'
-
-- *recherche des personnes intéressées par la formation ou habitant à Paris*
-  ::
-
-       Personne P WHERE
-       (P interesse_par T, T nom 'formation') or
-       (P ville 'Paris')
-
-- *Le nom et le prénom de toutes les personnes*
-  ::
-
-       Any N, P WHERE
-       X is Personne, X nom N, X prenom P
-
-  On remarquera que la selection de plusieurs entités force généralement
-  l'utilisation de "Any", car la spécification de type s'applique sinon
-  à toutes les variables séléctionnées. On aurait pu écrire ici 
-  ::
-
-       String N, P WHERE
-       X is Personne, X nom N, X prenom P
-
-
-Requête d'insertion
--------------------
-   `INSERT` <type d'entité> V1(, <type d'entité> V2)\* `:` <assignements>
-   [`WHERE` <restriction>] 
-
-:assignements:
-  liste des relations à assigner sous la forme `V1 relation V2|<valeur constante>`
-
-La restriction permet de définir des variables utilisées dans les assignements.
-
-Attention, si une restriction est spécifiée, l'insertion est effectuée *pour
-chaque ligne de résultat renvoyée par la restriction*.
-
-- *insertion d'une nouvelle personne nommée 'bidule'*
-  ::
-
-       INSERT Personne X: X nom 'bidule'
-
-- *insertion d'une nouvelle personne nommée 'bidule', d'une autre nommée 'chouette' et d'une relation 'ami' entre eux*
-  ::
-
-       INSERT Personne X, Personne Y: X nom 'bidule', Y nom 'chouette', X ami Y
-
-- *insertion d'une nouvelle personne nommée 'bidule' et d'une relation 'ami' avec une personne existante nommée 'chouette'*
-  ::
-
-       INSERT Personne X: X nom 'bidule', X ami Y WHERE Y nom 'chouette'
-
-
-Requête de mise à jour, création de relations
----------------------------------------------
-   `SET` <assignements>
-   [`WHERE` <restriction>] 
-
-Attention, si une restriction est spécifiée, la mise à jour est effectuée *pour
-chaque ligne de résultat renvoyée par la restriction*.
-
-- *renommage de la personne nommée 'bidule' en 'toto', avec modification du prénom*
-  ::
-
-       SET X nom 'toto', X prenom 'original' WHERE X is Person, X nom 'bidule'
-
-- *insertion d'une relation de type 'connait' entre les objets reliés par la relation de type 'ami'*
-  ::
-
-       SET X know Y WHERE X ami Y
-
-
-Requête de suppression
-----------------------
-   `DELETE` (<type d''entité> V) | (V1 relation v2),...
-   [`WHERE` <restriction>] 
-
-Attention, si une restriction est spécifiée, la suppression est effectuée *pour
-chaque ligne de résultat renvoyée par la restriction*.
-
-- *supression de la personne nommé 'toto'*
-  ::
-
-       DELETE Person X WHERE X nom 'toto'
-
-- *suppression de toutes les relations de type 'ami' partant de la personne nommée 'toto'*
-  ::
-
-       DELETE X ami Y WHERE X is Person, X nom 'toto'
-
-
-
-Définition du langage
-=====================
-
-Mots clés réservés
-------------------
-Les mots clés ne sont pas sensibles à la casse.
-
-::
-
-    DISTINCT, INSERT, SET, DELETE,
-    WHERE, AND, OR, NOT
-    IN, LIKE, ILIKE,
-    TRUE, FALSE, NULL, TODAY, NOW
-    GROUPBY, ORDERBY, ASC, DESC
-
-
-Variables et Typage
--------------------
-
-Au niveau de RQL, on ne fait pas de distinction entre entités et attributs. La
-valeur d'un attribut est considérée comme une entité d'un type particulier (voir
-ci-dessous), lié à une (vraie) entité par une relation du nom de l'attribut.
-
-Les entités et valeurs à parcourir et / ou séléctionner sont représentées dans
-la requête par des *variables* qui doivent être écrites en majuscule.
-
-Il existe un type spécial **Any**, revenant à ne pas spécifier de type.
-
-On peut contraindre les types possibles pour une variable à l'aide de la
-relation spéciale **is**.
-
-Le(s) type(s) possible(s) pour chaque variable est déduit du schema en
-fonction des contraintes exprimées ci-dessus et à l'aide des relations entre
-chaque variable.
-
-Types de bases
-``````````````
-
-Les types de bases supportés sont les chaines (entre doubles ou simples quotes),
-les nombres entiers ou flottant (le séparateur étant le '.'), les dates et les
-booléens. On s'attend donc à recevoir un schéma dans lequel les types String,
-Int, Float, Date et Boolean sont définis.
-
-* `String` (litéral: entre doubles ou simples quotes).
-* `Int`, `Float` (le séparateur étant le '.').
-* `Date`, `Datetime`, `Time` (litéral: chaîne YYYY/MM/DD[ hh:mm] ou mots-clés
-  `TODAY` et `NOW`).
-* `Boolean` (mots-clés `TRUE` et `FALSE`).
-* mot-clé `NULL`.
-
-
-Opérateurs
-----------
-
-Opérateurs logiques
-```````````````````
-::
-
-    AND, OR, ','
-
-"," est équivalent à "AND" mais avec la plus petite priorité parmi les
-opérateurs logiques (voir `Priorité des opérateurs`_).
-
-Opérateurs mathématiques
-````````````````````````
-::
-
-    +, -, *, /
-
-Opérateurs de comparaison
-`````````````````````````
-::
-
-    =, <, <=, >=, >, ~=, IN, LIKE, ILIKE
-
-* L'opérateur `=` est l'opérateur par défaut.
-
-* L'opérateur `LIKE` équivalent à `~=` permet d'utiliser le caractère `%` dans
-  une chaine de caractère pour indiquer que la chaîne doit commencer ou terminer
-  par un préfix/suffixe::
-
-    Any X WHERE X nom ~= 'Th%'
-    Any X WHERE X nom LIKE '%lt'
-
-* L'opérateur `ILIKE` est une version de `LIKE` qui n'est pas sensible à la
-  casse.
-
-* L'opérateur `IN` permet de donner une liste de valeurs possibles::
-
-    Any X WHERE X nom IN ('chauvat', 'fayolle', 'di mascio', 'thenault')
-
-
-XXX nico: A truc <> 'titi' ne serait-il pas plus pratique que NOT A
-truc 'titi' ?
-
-Priorité des opérateurs
-```````````````````````
-
-1. '*', '/'
-
-2. '+', '-'
-
-3. 'and'
-
-4. 'or'
-
-5. ','
-
-
-Fonctionnalités avancées
-------------------------
-
-Fonctions d'aggrégat
-````````````````````
-::
-
-    COUNT, MIN, MAX, AVG, SUM
-
-Fonctions sur les chaines
-`````````````````````````
-::
-
-    UPPER, LOWER
-
-Relations optionnelles
-``````````````````````
-
-* Elles permettent de sélectionner des entités liées ou non à une autre.
-
-* Il faut utiliser le `?` derrière la variable pour spécifier que la relation
-  vers celle-ci est optionnelle :
-
-  - Anomalies d'un projet attachées ou non à une version ::
-
-      Any X,V WHERE X concerns P, P eid 42, X corrected_in V?
-
-  - Toutes les fiches et le projet qu'elles documentent le cas échéant ::
-
-      Any C,P WHERE C is Card, P? documented_by C
-
-
-
-Grammaire BNF
--------------
-Les éléments terminaux sont en majuscules, les non-terminaux en minuscule. La
-valeur des éléments terminaux (entre quotes) correspond à une expression
-régulière Python.
-:: 
-
-    statement ::= (select | delete | insert | update) ';'
-
-
-    # select specific rules
-    select ::= 'DISTINCT'? E_TYPE selected_terms restriction? group? sort?
-
-    selected_terms ::= expression (',' expression)*
-
-    group       ::= 'GROUPBY' VARIABLE (',' VARIABLE)*
-
-    sort        ::= 'ORDERBY' sort_term (',' sort_term)*
-
-    sort_term   ::= VARIABLE sort_method? 
-
-    sort_method ::= 'ASC' | 'DESC'
-
-
-    # delete specific rules
-    delete ::= 'DELETE' (variables_declaration | relations_declaration) restriction?
-
-
-    # insert specific rules
-    insert ::= 'INSERT' variables_declaration (':' relations_declaration)? restriction?
-
-
-    # update specific rules
-    update ::= 'SET' relations_declaration restriction
-
-
-    # common rules
-    variables_declaration ::= E_TYPE VARIABLE (',' E_TYPE VARIABLE)*
-
-    relations_declaration ::= simple_relation (',' simple_relation)*
-
-    simple_relation ::= VARIABLE R_TYPE expression
-
-    restriction ::= 'WHERE' relations
-
-    relations   ::= relation (LOGIC_OP relation)*
-                  | '(' relations ')'
-
-    relation ::= 'NOT'? VARIABLE R_TYPE COMP_OP? expression 
-               | 'NOT'? VARIABLE R_TYPE 'IN' '(' expression (',' expression)* ')'
-    
-    expression ::= var_or_func_or_const (MATH_OP var_or_func_or_const)*
-                 | '(' expression ')'
-
-    var_or_func_or_const ::= VARIABLE | function | constant
-
-    function ::= FUNCTION '(' expression (',' expression)* ')'
-
-    constant ::= KEYWORD | STRING | FLOAT | INT
-
-    # tokens
-    LOGIC_OP ::= ',' | 'OR' | 'AND'
-    MATH_OP  ::= '+' | '-' | '/' | '*'
-    COMP_OP  ::= '>' | '>=' | '=' | '<=' | '<' | '~=' | 'LIKE' 
-
-    FUNCTION ::= 'MIN' | 'MAX' | 'SUM' | 'AVG' | 'COUNT' | 'UPPER' | 'LOWER'
-
-    VARIABLE ::= '[A-Z][A-Z0-9]*'
-    E_TYPE   ::= '[A-Z]\w*'
-    R_TYPE   ::= '[a-z_]+'
-
-    KEYWORD  ::= 'TRUE' | 'FALSE' | 'NULL' | 'TODAY' | 'NOW'
-    STRING   ::= "'([^'\]|\\.)*'" | '"([^\"]|\\.)*\"'
-    FLOAT    ::= '\d+\.\d*'
-    INT      ::= '\d+'
-
-
-Remarques
----------
-
-Tri et groupes
-``````````````
-
-- pour les requêtes groupées (i.e. avec une clause GROUPBY), toutes les
-  variables sélectionnées doivent être groupées
-
-- pour grouper ou/et trier sur les attributs on peut faire : "X,L user U, U
-  login L GROUPBY L,X ORDERBY L"
-
-- si la méthode de tri (SORT_METHOD) n'est pas précisée, alors le tri est
-  ascendant.
-
-Négation
-````````
-
-* Une requête du type `Document X WHERE NOT X owned_by U` revient à dire "les
-  documents n'ayant pas de relation `owned_by`". 
-* En revanche la requête `Document X WHERE NOT X owned_by U, U login "syt"`
-  revient à dire "les  documents n'ayant pas de relation `owned_by` avec
-  l'utilisateur syt". Ils peuvent avoir une relation "owned_by" avec un autre
-  utilisateur.
-
-Identité
-````````
-
-On peut utiliser la relation spéciale `identity` dans une requête pour
-rajouter une contrainte d'identité entre deux variables. C'est l'équivalent
-du ``is`` en python::
-
-  Any A WHERE A comments B, A identity B
-
-retournerait l'ensemble des objets qui se commentent eux-mêmes. La relation
-`identity` est surtout pratique lors de la définition des règles de sécurités
-avec des `RQLExpressions`.
-
-Implémentation
-==============
-
-Représentation interne (arbre syntaxique)
------------------------------------------
-
-L'arbre de recherche ne contient pas les variables sélectionnées (i.e. on n'y 
-trouve que ce qui suit le "WHERE").
-
-L'arbre d'insertion ne contient pas les variables insérées ni les relations 
-définies sur ces variables (i.e. on n'y trouve que ce qui suit le
-"WHERE").
-
-L'arbre de suppression ne contient pas les variables ou relations supprimées 
-(i.e. on n'y trouve que ce qui suit le "WHERE").
-
-L'arbre de mise à jour ne contient pas les variables ou relations mises à jour
-(i.e. on n'y trouve que ce qui suit le "WHERE").
-
-::
-
-    Select         ((Relation|And|Or)?, Group?, Sort?)
-    Insert         (Relation|And|Or)?
-    Delete         (Relation|And|Or)?
-    Update         (Relation|And|Or)?
-
-    And            ((Relation|And|Or), (Relation|And|Or))
-    Or             ((Relation|And|Or), (Relation|And|Or))
-
-    Relation       ((VariableRef, Comparison))
-
-    Comparison     ((Function|MathExpression|Keyword|Constant|VariableRef)+)
-
-    Function       (())
-    MathExpression ((MathExpression|Keyword|Constant|VariableRef), (MathExpression|Keyword|Constant|VariableRef))
-
-    Group          (VariableRef+)
-    Sort           (SortTerm+)
-    SortTerm       (VariableRef+)
-
-    VariableRef ()
-    Variable    ()
-    Keyword     ()
-    Constant    ()
-
-
-Remarques
----------
-
-- l'implémentation actuelle ne supporte pas de lier deux relations ayant comme
-  type de relation 'is' avec un OR. Je ne pense pas que la négation ne
-  soit supportée non plus sur ce type de relation (à confirmer).
-
-- les relations définissant les variables doivent être à gauche de celles les
-  utilisant. Par exemple ::
-
-    Point P where P abs X, P ord Y, P value X+Y
-
-  est valide, mais ::
-
-    Point P where P abs X, P value X+Y, P ord Y
-
-  ne l'est pas.
-
-
-
-Conclusion
-==========
-
-Limitations
------------
-
-Il manque pour l'instant:
-
-- COALESCE
-
-- restriction sur les groupes (HAVING)
-
-et certainement d'autres choses...
-
-Un inconvénient est que pour utiliser ce langage il faut bien connaitre le
-schéma utilisé (avec les vrais noms de relations et d'entités, pas ceux affichés
-dans l'interface utilisateur). D'un autre coté, on peut pas vraiment contourner
-cela, et c'est le boulot d'une interface utilisateur de cacher le RQL.
-
-
-Sujets de réflexion
--------------------
-
-Il serait pratique de pouvoir exprimer dans le schema des correspondances de
-relations (règles non récursives)::
-
-    Document class Type <-> Document occurence_of Fiche class Type
-    Fiche class Type    <-> Fiche collection Collection class Type
-    
-Ainsi 1. devient::
-
-    Document X where 
-    X class C, C name 'Bande dessinée',
-    X owned_by U, U login 'syt',
-    X available true
-
-Je ne suis cependant pas sûr qu'il faille gérer ça au niveau de RQL...
-
-Il faudrait aussi une relation spéciale 'anonyme'.
-
-
-
-.. _Versa: http://uche.ogbuji.net/tech/rdf/versa/
-.. _RDFQL: http://www.w3.org/TandS/QL/QL98/pp/rdfquery.html
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/tutorial_en.rst	Fri Dec 13 05:54:11 2019 +0100
@@ -0,0 +1,239 @@
+.. -*- coding: utf-8 -*-
+
+.. _tutorielRQL:
+
+==================================
+"Relation Query Language" tutorial
+==================================
+
+
+Let's discover RQL with examples.
+
+
+Schema
+------
+
+We will assume the following data model.
+
+:Person:
+
+::
+
+	name      varchar(64) NOT NULL
+	firstname varchar(64)
+	sex       char(1) DEFAULT 'M' 
+	title     varchar(128)
+	email     varchar(128)
+	web       varchar(128)
+	tel       integer
+	birthdate date
+
+
+:Company:
+
+::
+
+	name  varchar(64)
+	web   varchar(128)
+	tel   varchar(15)
+	adr   varchar(128)
+	cp    varchar(12)
+	city  varchar(32)
+
+
+:Workcase:
+
+::
+
+	title varchar(128)
+	ref   varchar(12) 
+
+
+:Comment:
+
+::
+
+	diem date
+	type char(1)
+	para varchar(512)
+
+
+with relationships:
+
+::
+
+	Person works_for Company
+	Person commented_by Comment
+	Company commented_by Comment
+	Person concerned_by Workcase
+	Company concerned_by Workcase
+
+
+Toutes les entités ont un attribut supplémentaire 'eid', permettant
+d'identifier chaque instance de manière unique.
+
+De plus si les métadonnées sont utilisées, vous disposez pour chaque
+type d'entité des relations "creation_date", "modification_date" dont
+l'objet est une entité de type Dates (il y a un "s" pour ne pas avoir
+de conflit avec le type de base "date"), ainsi que de la relation
+"owned_by" dont l'objet est une entité de type Euser. Les schemas
+standards de ces types d'entités sont les suivants :
+
+:Dates:
+
+::
+
+	day date
+
+
+:Euser:
+
+::
+
+	login  	  varchar(64) not null
+	firstname varchar(64)
+	surname   varchar(64)
+	password  password
+	role      choice('admin','user','anonymous') default 'user'
+	email  	  varchar(128)
+	web    	  varchar(128)
+	birthday  date
+
+Enfin, il existe la relation spéciale "is" permettant de spécifier le
+type d'une variable. 
+
+
+Essentials
+----------
+
+1. *Alls persons*
+
+   ::
+      
+      Person X ;
+      or
+      Any X WHERE X is Person ;
+
+
+2. *The company namend Logilab*
+
+   ::
+
+      Company S WHERE S name 'Logilab' ;
+
+
+3. *All entities with a name starting with 'Log'*
+
+   ::
+
+      Any S WHERE S name LIKE 'Log%' ;
+      or 
+      Any S WHERE S name ~= 'Log%' ;
+
+   This query can return entities of type Person and Company.
+
+
+4. *All persons working for a company named Logilab*
+   
+   ::
+
+      Person P WHERE P works_for S, S name "Logilab" ;
+      or
+      Person P WHERE P works_for S AND S name "Logilab" ;
+      or
+      Person P WHERE P works_for "Logilab" ;
+
+   La dernière forme fonctionne car "nom" est le premier attribut des
+   entités de type "Société" XXX nico: toujours vrai ?
+
+
+5. *Companies named Caesium or Logilab*
+
+   ::
+
+      Company S WHERE S name IN ('Logilab','Caesium') ;
+      or
+      Company S WHERE S name 'Logilab' OR S name 'Caesium' ;
+
+
+6. *All companies that are not named Caesium or Logilab*
+
+   ::
+
+      Company S WHERE NOT S name IN ('Logilab','Caesium') ;
+      or
+      Company S WHERE NOT S name 'Logilab' AND NOT S name 'Caesium' ;
+
+
+7. *All entities commented by the entity number 43*
+
+   ::
+
+      Any X WHERE X commented_by N, N eid 43 ;
+
+
+8. *All persons sorted by birth date in descending order*
+
+   ::
+      
+      Any X WHERE X is Person, X birthdate D ORDERBY D DESC ;
+
+
+9. *All persons grouped by company*
+
+   ::
+      
+      Person X WHERE X works_for S GROUPBY S,X ;
+
+   On note qu'il faut définir une variable pour s'en servir pour le
+   groupage. De plus les variables séléctionnées doivent être groupées
+   (mais les variables groupées ne doivent pas forcément être sélectionnées).
+
+XXX nico: c'est peu utile comme requête
+   
+Exemples avancés
+----------------
+1. *All persons that have an empty name (i.e NULL)*
+
+   ::
+
+      Person P WHERE P name NULL ;
+
+
+2. *All persons that do not work for a company*
+
+   ::
+
+      Person P WHERE NOT P works_for S ;
+
+
+3. *All the companies that the person named 'toto' does not work for*
+
+   ::
+
+      Company S WHERE NOT P works_for S , P name 'toto' ;
+      or
+      Company S WHERE NOT 'toto' works_for S ;
+
+
+4. *All the entities modified yesterday and today*
+
+   ::
+
+      Any X WHERE X modification_date <= today, X modification_date >= today - 1
+
+
+5. *All the comments without type that required action within 7 days, sorted by date*
+
+
+   ::
+
+      Any N, D where N is Comment, N type NULL, N diem D, N diem >= today,
+      N diem < today + 7 ORDERBY D
+
+
+6. *All persons that have homonyms (each name listed only once)*
+
+   ::
+
+      Person X,Y where X name NX, Y name NX, X eid XE, Y eid > XE
--- a/docs/tutorial_en.txt	Fri Dec 13 05:36:22 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,239 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _tutorielRQL:
-
-==================================
-"Relation Query Language" tutorial
-==================================
-
-
-Let's discover RQL with examples.
-
-
-Schema
-------
-
-We will assume the following data model.
-
-:Person:
-
-::
-
-	name      varchar(64) NOT NULL
-	firstname varchar(64)
-	sex       char(1) DEFAULT 'M' 
-	title     varchar(128)
-	email     varchar(128)
-	web       varchar(128)
-	tel       integer
-	birthdate date
-
-
-:Company:
-
-::
-
-	name  varchar(64)
-	web   varchar(128)
-	tel   varchar(15)
-	adr   varchar(128)
-	cp    varchar(12)
-	city  varchar(32)
-
-
-:Workcase:
-
-::
-
-	title varchar(128)
-	ref   varchar(12) 
-
-
-:Comment:
-
-::
-
-	diem date
-	type char(1)
-	para varchar(512)
-
-
-with relationships:
-
-::
-
-	Person works_for Company
-	Person commented_by Comment
-	Company commented_by Comment
-	Person concerned_by Workcase
-	Company concerned_by Workcase
-
-
-Toutes les entités ont un attribut supplémentaire 'eid', permettant
-d'identifier chaque instance de manière unique.
-
-De plus si les métadonnées sont utilisées, vous disposez pour chaque
-type d'entité des relations "creation_date", "modification_date" dont
-l'objet est une entité de type Dates (il y a un "s" pour ne pas avoir
-de conflit avec le type de base "date"), ainsi que de la relation
-"owned_by" dont l'objet est une entité de type Euser. Les schemas
-standards de ces types d'entités sont les suivants :
-
-:Dates:
-
-::
-
-	day date
-
-
-:Euser:
-
-::
-
-	login  	  varchar(64) not null
-	firstname varchar(64)
-	surname   varchar(64)
-	password  password
-	role      choice('admin','user','anonymous') default 'user'
-	email  	  varchar(128)
-	web    	  varchar(128)
-	birthday  date
-
-Enfin, il existe la relation spéciale "is" permettant de spécifier le
-type d'une variable. 
-
-
-Essentials
-----------
-
-1. *Alls persons*
-
-   ::
-      
-      Person X ;
-      or
-      Any X WHERE X is Person ;
-
-
-2. *The company namend Logilab*
-
-   ::
-
-      Company S WHERE S name 'Logilab' ;
-
-
-3. *All entities with a name starting with 'Log'*
-
-   ::
-
-      Any S WHERE S name LIKE 'Log%' ;
-      or 
-      Any S WHERE S name ~= 'Log%' ;
-
-   This query can return entities of type Person and Company.
-
-
-4. *All persons working for a company named Logilab*
-   
-   ::
-
-      Person P WHERE P works_for S, S name "Logilab" ;
-      or
-      Person P WHERE P works_for S AND S name "Logilab" ;
-      or
-      Person P WHERE P works_for "Logilab" ;
-
-   La dernière forme fonctionne car "nom" est le premier attribut des
-   entités de type "Société" XXX nico: toujours vrai ?
-
-
-5. *Companies named Caesium or Logilab*
-
-   ::
-
-      Company S WHERE S name IN ('Logilab','Caesium') ;
-      or
-      Company S WHERE S name 'Logilab' OR S name 'Caesium' ;
-
-
-6. *All companies that are not named Caesium or Logilab*
-
-   ::
-
-      Company S WHERE NOT S name IN ('Logilab','Caesium') ;
-      or
-      Company S WHERE NOT S name 'Logilab' AND NOT S name 'Caesium' ;
-
-
-7. *All entities commented by the entity number 43*
-
-   ::
-
-      Any X WHERE X commented_by N, N eid 43 ;
-
-
-8. *All persons sorted by birth date in descending order*
-
-   ::
-      
-      Any X WHERE X is Person, X birthdate D ORDERBY D DESC ;
-
-
-9. *All persons grouped by company*
-
-   ::
-      
-      Person X WHERE X works_for S GROUPBY S,X ;
-
-   On note qu'il faut définir une variable pour s'en servir pour le
-   groupage. De plus les variables séléctionnées doivent être groupées
-   (mais les variables groupées ne doivent pas forcément être sélectionnées).
-
-XXX nico: c'est peu utile comme requête
-   
-Exemples avancés
-----------------
-1. *All persons that have an empty name (i.e NULL)*
-
-   ::
-
-      Person P WHERE P name NULL ;
-
-
-2. *All persons that do not work for a company*
-
-   ::
-
-      Person P WHERE NOT P works_for S ;
-
-
-3. *All the companies that the person named 'toto' does not work for*
-
-   ::
-
-      Company S WHERE NOT P works_for S , P name 'toto' ;
-      or
-      Company S WHERE NOT 'toto' works_for S ;
-
-
-4. *All the entities modified yesterday and today*
-
-   ::
-
-      Any X WHERE X modification_date <= today, X modification_date >= today - 1
-
-
-5. *All the comments without type that required action within 7 days, sorted by date*
-
-
-   ::
-
-      Any N, D where N is Comment, N type NULL, N diem D, N diem >= today,
-      N diem < today + 7 ORDERBY D
-
-
-6. *All persons that have homonyms (each name listed only once)*
-
-   ::
-
-      Person X,Y where X name NX, Y name NX, X eid XE, Y eid > XE
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/tutoriel_fr.rst	Fri Dec 13 05:54:11 2019 +0100
@@ -0,0 +1,242 @@
+.. -*- coding: utf-8 -*-
+
+.. _tutorielRQL:
+
+============================================
+Tutoriel "Relation Query Language" (Hercule)
+============================================
+
+
+Apprenons RQL par la pratique...
+
+
+
+Schema
+------
+Nous supposerons dans la suite de ce document que le schéma de
+l'application est le suivant. Les différentes entités
+disponibles sont :
+
+:Personne:
+
+::
+
+	nom    varchar(64) NOT NULL
+	prenom varchar(64)
+	sexe   char(1) DEFAULT 'M' 
+	promo  choice('bon','pasbon')
+	titre  varchar(128)
+	adel   varchar(128)
+	web    varchar(128)
+	tel    integer
+	datenaiss date
+
+
+:Societe:
+
+::
+
+	nom  varchar(64)
+	web varchar(128)
+	tel  varchar(15)
+	adr  varchar(128)
+	cp   varchar(12)
+	ville varchar(32)
+
+
+:Affaire:
+
+::
+
+	sujet varchar(128)
+	ref   varchar(12) 
+
+
+:Note:
+
+::
+
+	diem date
+	type char(1)
+	para varchar(512)
+
+
+Et les relations entre elles:
+
+::
+
+	Person travaille_pour Societe
+	Person evaluee_par Note
+	Societe evaluee_par Note
+	Person concerne_par Note
+	Person concerne_par Affaire
+	Societe concerne_par Affaire
+
+
+Toutes les entités ont un attribut supplémentaire 'eid', permettant
+d'identifier chaque instance de manière unique.
+
+De plus si les métadonnées sont utilisées, vous disposez pour chaque
+type d'entité des relations "creation_date", "modification_date" dont
+l'objet est une entité de type Dates (il y a un "s" pour ne pas avoir
+de conflit avec le type de base "date"), ainsi que de la relation
+"owned_by" dont l'objet est une entité de type Euser. Les schemas
+standards de ces types d'entités sont les suivants :
+
+:Dates:
+
+::
+
+	day date
+
+
+:Euser:
+
+::
+
+	login  	  varchar(64) not null
+	firstname varchar(64)
+	surname   varchar(64)
+	password  password
+	role      choice('admin','user','anonymous') default 'user'
+	email  	  varchar(128)
+	web    	  varchar(128)
+	birthday  date
+
+Enfin, il existe la relation spéciale "is" permettant de spécifier le
+type d'une variable. 
+
+
+L'essentiel
+-----------
+1. *Toutes les personnes*
+
+   ::
+      
+      Personne X ;
+      ou
+      Any X WHERE X is Personne ;
+
+
+2. *La societé nommé Logilab*
+
+   ::
+
+      Societe S WHERE S nom 'Logilab' ;
+
+
+3. *Tous les objets ayant un attribut nom commençant par 'Log'*
+
+   ::
+
+      Any S WHERE S nom LIKE 'Log%' ;
+      ou 
+      Any S WHERE S nom ~= 'Log%' ;
+
+   Cette requête peut renvoyer des objets de type personne et de type
+   société.
+
+
+4. *Toutes les personnes travaillant pour la société nommé Logilab*
+   
+   ::
+
+      Personne P WHERE P travaille_pour S, S nom "Logilab" ;
+      ou
+      Personne P WHERE P travaille_pour S AND S nom "Logilab" ;
+      ou
+      Personne P WHERE P travaille_pour "Logilab" ;
+
+   La dernière forme fonctionne car "nom" est le premier attribut des
+   entités de type "Société" XXX nico: toujours vrai ?
+
+
+5. *Les societés nommées Caesium ou Logilab*
+
+   ::
+
+      Societe S WHERE S nom IN ('Logilab','Caesium') ;
+      ou
+      Societe S WHERE S nom 'Logilab' OR S nom 'Caesium' ;
+
+
+6. *Toutes les societés sauf celles nommées Caesium ou Logilab*
+
+   ::
+
+      Societe S WHERE NOT S nom IN ('Logilab','Caesium') ;
+      ou
+      Societe S WHERE NOT S nom 'Logilab' AND NOT S nom 'Caesium' ;
+
+
+7. *Les objets évalués par la note d'identifiant 43*
+
+   ::
+
+      Any X WHERE X evaluee_par N, N eid 43 ;
+
+
+8. *Toutes les personnes triés par date de naissance dans l'ordre antechronologique*
+
+   ::
+      
+      Any X WHERE X is Personne, X datenaiss D ORDERBY D DESC ;
+
+
+9. *Toutes les personnes groupées par leur société*
+
+   ::
+      
+      Personne X WHERE X travaille_pour S GROUPBY S,X ;
+
+   On note qu'il faut définir une variable pour s'en servir pour le
+   groupage. De plus les variables séléctionnées doivent être groupées
+   (mais les variables groupées ne doivent pas forcément être sélectionnées).
+
+XXX nico: c'est peu utile comme requête
+   
+Exemples avancés
+----------------
+1. *Toutes les personnes dont le champ nom n'est pas spécifié (i.e NULL)*
+
+   ::
+
+      Personne P WHERE P nom NULL ;
+
+
+2. *Toutes les personnes qui ne travaillent pour aucune société*
+
+   ::
+
+      Personne P WHERE NOT P travaille_pour S ;
+
+
+3. *Toutes les sociétés où la personne nommée toto ne travaille pas*
+
+   ::
+
+      Societe S WHERE NOT P travaille_pour S , P nom 'toto' ;
+      ou
+      Societe S WHERE NOT 'toto' travaille_pour S ;
+
+
+4. *Toutes les entités ayant été modifiées entre aujourd'hui et hier*
+
+   ::
+
+      Any X WHERE X modification_date <= today, X modification_date >= today - 1
+
+
+5. *Toutes les notes n'ayant pas de type et à effectuer dans les 7 jours, triées par date*
+
+   ::
+
+      Any N, D where N is Note, N type NULL, N diem D, N diem >= today,
+      N diem < today + 7 ORDERBY D
+
+
+6. *Les personnes ayant un homonyme (sans doublons)*
+
+   ::
+
+      Personne X,Y where X nom NX, Y nom NX, X eid XE, Y eid > XE
--- a/docs/tutoriel_fr.txt	Fri Dec 13 05:36:22 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,242 +0,0 @@
-.. -*- coding: utf-8 -*-
-
-.. _tutorielRQL:
-
-============================================
-Tutoriel "Relation Query Language" (Hercule)
-============================================
-
-
-Apprenons RQL par la pratique...
-
-
-
-Schema
-------
-Nous supposerons dans la suite de ce document que le schéma de
-l'application est le suivant. Les différentes entités
-disponibles sont :
-
-:Personne:
-
-::
-
-	nom    varchar(64) NOT NULL
-	prenom varchar(64)
-	sexe   char(1) DEFAULT 'M' 
-	promo  choice('bon','pasbon')
-	titre  varchar(128)
-	adel   varchar(128)
-	web    varchar(128)
-	tel    integer
-	datenaiss date
-
-
-:Societe:
-
-::
-
-	nom  varchar(64)
-	web varchar(128)
-	tel  varchar(15)
-	adr  varchar(128)
-	cp   varchar(12)
-	ville varchar(32)
-
-
-:Affaire:
-
-::
-
-	sujet varchar(128)
-	ref   varchar(12) 
-
-
-:Note:
-
-::
-
-	diem date
-	type char(1)
-	para varchar(512)
-
-
-Et les relations entre elles:
-
-::
-
-	Person travaille_pour Societe
-	Person evaluee_par Note
-	Societe evaluee_par Note
-	Person concerne_par Note
-	Person concerne_par Affaire
-	Societe concerne_par Affaire
-
-
-Toutes les entités ont un attribut supplémentaire 'eid', permettant
-d'identifier chaque instance de manière unique.
-
-De plus si les métadonnées sont utilisées, vous disposez pour chaque
-type d'entité des relations "creation_date", "modification_date" dont
-l'objet est une entité de type Dates (il y a un "s" pour ne pas avoir
-de conflit avec le type de base "date"), ainsi que de la relation
-"owned_by" dont l'objet est une entité de type Euser. Les schemas
-standards de ces types d'entités sont les suivants :
-
-:Dates:
-
-::
-
-	day date
-
-
-:Euser:
-
-::
-
-	login  	  varchar(64) not null
-	firstname varchar(64)
-	surname   varchar(64)
-	password  password
-	role      choice('admin','user','anonymous') default 'user'
-	email  	  varchar(128)
-	web    	  varchar(128)
-	birthday  date
-
-Enfin, il existe la relation spéciale "is" permettant de spécifier le
-type d'une variable. 
-
-
-L'essentiel
------------
-1. *Toutes les personnes*
-
-   ::
-      
-      Personne X ;
-      ou
-      Any X WHERE X is Personne ;
-
-
-2. *La societé nommé Logilab*
-
-   ::
-
-      Societe S WHERE S nom 'Logilab' ;
-
-
-3. *Tous les objets ayant un attribut nom commençant par 'Log'*
-
-   ::
-
-      Any S WHERE S nom LIKE 'Log%' ;
-      ou 
-      Any S WHERE S nom ~= 'Log%' ;
-
-   Cette requête peut renvoyer des objets de type personne et de type
-   société.
-
-
-4. *Toutes les personnes travaillant pour la société nommé Logilab*
-   
-   ::
-
-      Personne P WHERE P travaille_pour S, S nom "Logilab" ;
-      ou
-      Personne P WHERE P travaille_pour S AND S nom "Logilab" ;
-      ou
-      Personne P WHERE P travaille_pour "Logilab" ;
-
-   La dernière forme fonctionne car "nom" est le premier attribut des
-   entités de type "Société" XXX nico: toujours vrai ?
-
-
-5. *Les societés nommées Caesium ou Logilab*
-
-   ::
-
-      Societe S WHERE S nom IN ('Logilab','Caesium') ;
-      ou
-      Societe S WHERE S nom 'Logilab' OR S nom 'Caesium' ;
-
-
-6. *Toutes les societés sauf celles nommées Caesium ou Logilab*
-
-   ::
-
-      Societe S WHERE NOT S nom IN ('Logilab','Caesium') ;
-      ou
-      Societe S WHERE NOT S nom 'Logilab' AND NOT S nom 'Caesium' ;
-
-
-7. *Les objets évalués par la note d'identifiant 43*
-
-   ::
-
-      Any X WHERE X evaluee_par N, N eid 43 ;
-
-
-8. *Toutes les personnes triés par date de naissance dans l'ordre antechronologique*
-
-   ::
-      
-      Any X WHERE X is Personne, X datenaiss D ORDERBY D DESC ;
-
-
-9. *Toutes les personnes groupées par leur société*
-
-   ::
-      
-      Personne X WHERE X travaille_pour S GROUPBY S,X ;
-
-   On note qu'il faut définir une variable pour s'en servir pour le
-   groupage. De plus les variables séléctionnées doivent être groupées
-   (mais les variables groupées ne doivent pas forcément être sélectionnées).
-
-XXX nico: c'est peu utile comme requête
-   
-Exemples avancés
-----------------
-1. *Toutes les personnes dont le champ nom n'est pas spécifié (i.e NULL)*
-
-   ::
-
-      Personne P WHERE P nom NULL ;
-
-
-2. *Toutes les personnes qui ne travaillent pour aucune société*
-
-   ::
-
-      Personne P WHERE NOT P travaille_pour S ;
-
-
-3. *Toutes les sociétés où la personne nommée toto ne travaille pas*
-
-   ::
-
-      Societe S WHERE NOT P travaille_pour S , P nom 'toto' ;
-      ou
-      Societe S WHERE NOT 'toto' travaille_pour S ;
-
-
-4. *Toutes les entités ayant été modifiées entre aujourd'hui et hier*
-
-   ::
-
-      Any X WHERE X modification_date <= today, X modification_date >= today - 1
-
-
-5. *Toutes les notes n'ayant pas de type et à effectuer dans les 7 jours, triées par date*
-
-   ::
-
-      Any N, D where N is Note, N type NULL, N diem D, N diem >= today,
-      N diem < today + 7 ORDERBY D
-
-
-6. *Les personnes ayant un homonyme (sans doublons)*
-
-   ::
-
-      Personne X,Y where X nom NX, Y nom NX, X eid XE, Y eid > XE