Commits

Anonymous committed d781d6c

v1.3a3 - fixes a bug that prevented saving schemes including multi-input widgets

Comments (0)

Files changed (87)

 
 .. _Orange: http://orange.biolab.si/
 
-Textable was designed and implemented `LangTech Sarl <http://langtech.ch>`_ on behalf of the department of language and information sciences (SLI_) at the `University of Lausanne <http://www.unil.ch>`_.
+Documentation is found at:
+
+Readthedocs_
+
+.. _Readthedocs: https://orange-textable.readthedocs.org/
+
+Textable was designed and implemented by `LangTech Sarl <http://langtech.ch>`_ on behalf of the department of language and information sciences (SLI_) at the `University of Lausanne <http://www.unil.ch>`_.
 
 .. _SLI: http://www.unil.ch/sli
 

_textable/widgets/OWTextableAnnotation.py

 #=============================================================================
-# Class OWTextableAnnotation, v0.05
+# Class OWTextableAnnotation, v0.07
 # Copyright 2012-2013 LangTech Sarl (info@langtech.ch)
 #=============================================================================
 # This file is part of the Textable (v1.3) extension to Orange Canvas.
 
     def handleNewSignals(self):
         """Overridden: called after multiple signals have been added"""
-        self.restoreSettings()
+        try:
+            self.restoreSettings()
+        except AttributeError:
+            pass
 
     def getSettings(self, alsoContexts = True, globalContexts=False):
         """Overridden: called when a file is saved (among other situations)"""
-        self.storeSettings()
+        try:
+            self.storeSettings()
+        except AttributeError:
+            pass
         return super(type(self), self).getSettings(
                 alsoContexts = True, globalContexts=False
         )
             self.settingsRestored = True
             for segIndex in xrange(len(self.segmentations)):
                 segmentation = self.segmentations[segIndex]
-                if segmentation[0][0].uuid == self.savedUnitSenderUuid:
+                if segmentation[0][2].uuid == self.savedUnitSenderUuid:
                     self.units = segIndex
-                if segmentation[0][0].uuid == self.savedContextSenderUuid:
+                if segmentation[0][2].uuid == self.savedContextSenderUuid:
                     self.contexts = segIndex
             self.updateGUI()
             if self.units is not None:
         if self.settingsRestored:
             if self.units is not None:
                 segmentation                = self.segmentations[self.units]
-                self.savedUnitSenderUuid    = segmentation[0][0].uuid
+                self.savedUnitSenderUuid    = segmentation[0][2].uuid
                 self.savedUnitAnnotationKey = self.unitAnnotationKey
             else:
                 self.savedUnitSenderUuid    = None
                 self.savedUnitAnnotationKey = None
             if self.contexts is not None:
                 segmentation               = self.segmentations[self.contexts]
-                self.savedContextSenderUuid    = segmentation[0][0].uuid
+                self.savedContextSenderUuid    = segmentation[0][2].uuid
                 self.savedContextAnnotationKey = self.contextAnnotationKey
             else:
                 self.savedContextSenderUuid    = None

_textable/widgets/OWTextableContext.py

 #=============================================================================
-# Class OWTextableContext, v0.03
+# Class OWTextableContext, v0.05
 # Copyright 2012-2013 LangTech Sarl (info@langtech.ch)
 #=============================================================================
 # This file is part of the Textable (v1.3) extension to Orange Canvas.
 
     def handleNewSignals(self):
         """Overridden: called after multiple signals have been added"""
-        self.restoreSettings()
+        try:
+            self.restoreSettings()
+        except AttributeError:
+            pass
 
     def getSettings(self, alsoContexts = True, globalContexts=False):
         """Overridden: called when a file is saved (among other situations)"""
-        self.storeSettings()
+        try:
+            self.storeSettings()
+        except AttributeError:
+            pass
         return super(type(self), self).getSettings(
                 alsoContexts = True, globalContexts=False
         )
             self.settingsRestored = True
             for segIndex in xrange(len(self.segmentations)):
                 segmentation = self.segmentations[segIndex]
-                if segmentation[0][0].uuid == self.savedUnitSenderUuid:
+                if segmentation[0][2].uuid == self.savedUnitSenderUuid:
                     self.units = segIndex
-                if segmentation[0][0].uuid == self.savedContextSenderUuid:
+                if segmentation[0][2].uuid == self.savedContextSenderUuid:
                     self.contexts = segIndex
             self.updateGUI()
             if self.units is not None:
         if self.settingsRestored:
             if self.units is not None:
                 segmentation                = self.segmentations[self.units]
-                self.savedUnitSenderUuid    = segmentation[0][0].uuid
+                self.savedUnitSenderUuid    = segmentation[0][2].uuid
                 self.savedUnitAnnotationKey = self.unitAnnotationKey
             else:
                 self.savedUnitSenderUuid    = None
                 self.savedUnitAnnotationKey = None
             if self.contexts is not None:
                 segmentation = self.segmentations[self.contexts]
-                self.savedContextSenderUuid    = segmentation[0][0].uuid
+                self.savedContextSenderUuid    = segmentation[0][2].uuid
                 self.savedContextAnnotationKey = self.contextAnnotationKey
             else:
                 self.savedContextSenderUuid    = None

_textable/widgets/OWTextableCount.py

 #=============================================================================
-# Class OWTextableCount, v0.13
+# Class OWTextableCount, v0.15
 # Copyright 2012-2013 LangTech Sarl (info@langtech.ch)
 #=============================================================================
 # This file is part of the Textable (v1.3) extension to Orange Canvas.
 
     def handleNewSignals(self):
         """Overridden: called after multiple signals have been added"""
-        self.restoreSettings()
-        
+        try:
+            self.restoreSettings()
+        except AttributeError:
+            pass
+
     def getSettings(self, alsoContexts = True, globalContexts=False):
         """Overridden: called when a file is saved (among other situations)"""
-        self.storeSettings()
+        try:
+            self.storeSettings()
+        except AttributeError:
+            pass
         return super(type(self), self).getSettings(
                 alsoContexts = True, globalContexts=False
         )
             self.mode             = self.savedMode
             for segIndex in xrange(len(self.segmentations)):
                 segmentation = self.segmentations[segIndex]
-                if segmentation[0][0].uuid == self.savedUnitSenderUuid:
+                if segmentation[0][2].uuid == self.savedUnitSenderUuid:
                     self.units = segIndex
                 if self.mode == u'Containing segmentation':
-                    if segmentation[0][0].uuid == self.savedContextSenderUuid:
+                    if segmentation[0][2].uuid == self.savedContextSenderUuid:
                         self.contexts = segIndex
             self.updateGUI()
             if self.units is not None:
             self.savedMode                  = self.mode
             if self.units is not None:
                 segmentation                = self.segmentations[self.units]
-                self.savedUnitSenderUuid    = segmentation[0][0].uuid
+                self.savedUnitSenderUuid    = segmentation[0][2].uuid
                 self.savedUnitAnnotationKey = self.unitAnnotationKey
                 if          self.mode == u'Containing segmentation' \
                         and self.contexts is not None:
                     segmentation = self.segmentations[self.contexts]
-                    self.savedContextSenderUuid = segmentation[0][0].uuid
+                    self.savedContextSenderUuid = segmentation[0][2].uuid
                     self.savedContextAnnotationKey \
                             = self.contextAnnotationKey
                 else:

_textable/widgets/OWTextableDisplay.py

 #=============================================================================
-# Class OWTextableDisplay, v0.08
+# Class OWTextableDisplay, v0.09
 # Copyright 2012-2013 LangTech Sarl (info@langtech.ch)
 #=============================================================================
 # This file is part of the Textable (v1.3) extension to Orange Canvas.
         """Send segmentation to output"""
         if not self.segmentation:
             self.infoBox.noDataSent(u'No input.')
-            self.send('Bypassed segmentation', None)
-            self.send('Displayed segmentation', None)
+            self.send('Bypassed segmentation', None, self)
+            self.send('Displayed segmentation', None, self)
             return
-        self.send('Bypassed segmentation', self.segmentation)
+        self.send('Bypassed segmentation', self.segmentation, self)
         if len(self.displayedSegmentation[0].get_content()) > 0:
-            self.send('Displayed segmentation', self.displayedSegmentation)
+            self.send(
+                    'Displayed segmentation',
+                    self.displayedSegmentation,
+                    self
+            )
         message = u'Data contains %i segment@p.' % len(self.segmentation)
         message = pluralize(message, len(self.segmentation))
         self.infoBox.dataSent(message)

_textable/widgets/OWTextableExtractXML.py

 #=============================================================================
-# Class OWTextableExtractXML, v0.07
+# Class OWTextableExtractXML, v0.08
 # Copyright 2012-2013 LangTech Sarl (info@langtech.ch)
 #=============================================================================
 # This file is part of the Textable (v1.3) extension to Orange Canvas.
         # Check that there's something on input...
         if not self.inputSegmentation:
             self.infoBox.noDataSent(u'No input.')
-            self.send('Extracted XML', None)
+            self.send('Extracted XML', None, self)
             return
 
         # Check that element field is not empty...
         if not self.element:
             self.infoBox.noDataSent(u'No XML element was specified.')
-            self.send('Extracted XML', None)
+            self.send('Extracted XML', None, self)
             return
 
         # Check that label is not empty...
         if not self.label:
             self.infoBox.noDataSent(u'No label was provided.')
-            self.send('Extracted XML', None)
+            self.send('Extracted XML', None, self)
             return
 
         # Check that importElementAs is not empty (if necessary)...
                 self.infoBox.noDataSent(
                         u'No annotation key was provided for auto-numbering.'
                 )
-                self.send('Extracted XML', None)
+                self.send('Extracted XML', None, self)
                 return
         else:
             autoNumberKey = None
         message = pluralize(message, len(xml_extracted_data))
         self.infoBox.dataSent(message)
 
-        self.send( 'Extracted XML', xml_extracted_data )
+        self.send( 'Extracted XML', xml_extracted_data, self)
         self.sendButton.resetSettingsChangedFlag()
 
 

_textable/widgets/OWTextableIntersect.py

 #=============================================================================
-# Class OWTextableIntersect, v0.08
+# Class OWTextableIntersect, v0.10
 # Copyright 2012-2013 LangTech Sarl (info@langtech.ch)
 #=============================================================================
 # This file is part of the Textable (v1.3) extension to Orange Canvas.
         # Check that there's something on input...
         if len(self.segmentations) == 0:
             self.infoBox.noDataSent(u'No input.')
-            self.send('Filtered data', None)
+            self.send('Filtered data', None, self)
             return
 
         # Check that label is not empty...
         if not self.label:
             self.infoBox.noDataSent(u'No label was provided.')
-            self.send('Filtered data', None)
+            self.send('Filtered data', None, self)
             return
 
         # Source and filtering parameter...
                 self.infoBox.noDataSent(
                         u'No annotation key was provided for auto-numbering.'
                 )
-                self.send('Filtered data', None)
+                self.send('Filtered data', None, self)
                 return
         else:
             autoNumberKey = None
         message = pluralize(message, len(filtered_data))
         self.infoBox.dataSent(message)
 
-        self.send( 'Filtered data', filtered_data )
-        self.send( 'Discarded data', discarded_data )
+        self.send( 'Filtered data', filtered_data, self)
+        self.send( 'Discarded data', discarded_data, self)
         self.sendButton.resetSettingsChangedFlag()
 
 
 
     def handleNewSignals(self):
         """Overridden: called after multiple signals have been added"""
-        self.restoreSettings()
+        try:
+            self.restoreSettings()
+        except AttributeError:
+            pass
 
     def getSettings(self, alsoContexts = True, globalContexts=False):
         """Overridden: called when a file is saved (among other situations)"""
-        self.storeSettings()
+        try:
+            self.storeSettings()
+        except AttributeError:
+            pass
         return super(type(self), self).getSettings(
                 alsoContexts = True, globalContexts=False
         )
             self.settingsRestored = True
             for segIndex in xrange(len(self.segmentations)):
                 segmentation = self.segmentations[segIndex]
-                if segmentation[0][0].uuid == self.savedSourceSenderUuid:
+                if segmentation[0][2].uuid == self.savedSourceSenderUuid:
                     self.source = segIndex
-                if segmentation[0][0].uuid == self.savedFilteringSenderUuid:
+                if segmentation[0][2].uuid == self.savedFilteringSenderUuid:
                     self.filtering = segIndex
             self.updateGUI()
             if self.source is not None:
         if self.settingsRestored:
             if self.source is not None:
                 segmentation                 = self.segmentations[self.source]
-                self.savedSourceSenderUuid   = segmentation[0][0].uuid
+                self.savedSourceSenderUuid   = segmentation[0][2].uuid
                 self.savedSourceAnnotationKey = self.sourceAnnotationKey
                 segmentation = self.segmentations[self.filtering]
             else:
                 self.savedSourceSenderUuid    = None
                 self.savedSourceAnnotationKey = None
             if self.filtering is not None:
-                self.savedFilteringSenderUuid = segmentation[0][0].uuid
+                self.savedFilteringSenderUuid = segmentation[0][2].uuid
                 if self.displayAdvancedSettings:
                     self.savedFilteringAnnotationKey \
                             = self.filteringAnnotationKey

_textable/widgets/OWTextableLength.py

 #=============================================================================
-# Class OWTextableLength, v0.08
+# Class OWTextableLength, v0.10
 # Copyright 2012-2013 LangTech Sarl (info@langtech.ch)
 #=============================================================================
 # This file is part of the Textable (v1.3) extension to Orange Canvas.
 
     def handleNewSignals(self):
         """Overridden: called after multiple signals have been added"""
-        self.restoreSettings()
+        try:
+            self.restoreSettings()
+        except AttributeError:
+            pass
 
     def getSettings(self, alsoContexts = True, globalContexts=False):
         """Overridden: called when a file is saved (among other situations)"""
-        self.storeSettings()
+        try:
+            self.storeSettings()
+        except AttributeError:
+            pass
         return super(type(self), self).getSettings(
                 alsoContexts = True, globalContexts=False
         )
             self.mode             = self.savedMode
             for segIndex in xrange(len(self.segmentations)):
                 segmentation = self.segmentations[segIndex]
-                if segmentation[0][0].uuid == self.savedUnitSenderUuid:
+                if segmentation[0][2].uuid == self.savedUnitSenderUuid:
                     self.units = segIndex
-                if segmentation[0][0].uuid == self.savedAveragingSenderUuid:
+                if segmentation[0][2].uuid == self.savedAveragingSenderUuid:
                     self.averagingSegmentation = segIndex
                 if self.mode == u'Containing segmentation':
-                    if segmentation[0][0].uuid == self.savedContextSenderUuid:
+                    if segmentation[0][2].uuid == self.savedContextSenderUuid:
                         self.contexts = segIndex
             self.updateGUI()
             if self.mode == u'Containing segmentation':
         if self.settingsRestored:
             self.savedMode                  = self.mode
             segmentation                    = self.segmentations[self.units]
-            self.savedUnitSenderUuid        = segmentation[0][0].uuid
+            self.savedUnitSenderUuid        = segmentation[0][2].uuid
             segmentation = self.segmentations[self.averagingSegmentation]
-            self.savedAveragingSenderUuid   = segmentation[0][0].uuid
+            self.savedAveragingSenderUuid   = segmentation[0][2].uuid
             if self.mode == u'Containing segmentation':
                 segmentation = self.segmentations[self.contexts]
-                self.savedContextSenderUuid    = segmentation[0][0].uuid
+                self.savedContextSenderUuid    = segmentation[0][2].uuid
                 self.savedContextAnnotationKey = self.contextAnnotationKey
         if self.settingsRestored:
             self.savedMode                  = self.mode
             if self.units is not None:
                 segmentation                = self.segmentations[self.units]
-                self.savedUnitSenderUuid    = segmentation[0][0].uuid
+                self.savedUnitSenderUuid    = segmentation[0][2].uuid
                 if self.units is not None:
                     segmentation = \
                             self.segmentations[self.averagingSegmentation]
-                    self.savedAveragingSenderUuid   = segmentation[0][0].uuid
+                    self.savedAveragingSenderUuid   = segmentation[0][2].uuid
                 else:
                     self.savedAveragingSenderUuid   = None
                 if          self.mode == u'Containing segmentation' \
                         and self.contexts is not None:
                     segmentation = self.segmentations[self.contexts]
-                    self.savedContextSenderUuid = segmentation[0][0].uuid
+                    self.savedContextSenderUuid = segmentation[0][2].uuid
                     self.savedContextAnnotationKey \
                             = self.contextAnnotationKey
                 else:

_textable/widgets/OWTextableMerge.py

 #=============================================================================
-# Class OWTextableMerge, v0.12
+# Class OWTextableMerge, v0.15
 # Copyright 2012-2013 LangTech Sarl (info@langtech.ch)
 #=============================================================================
 # This file is part of the Textable (v1.3) extension to Orange Canvas.
         # Check that there's something on input...
         if not self.texts:
             self.infoBox.noDataSent(u'No input.')
-            self.send('Merged data', None)
+            self.send('Merged data', None, self)
             return
 
         # Extract segmentations from self.texts and get number of segments...
         # Check that label is not empty...
         if not self.label:
             self.infoBox.noDataSent(u'No label was provided.')
-            self.send('Merged data', None)
+            self.send('Merged data', None, self)
             return
 
         # Check that labelKey is not empty (if necessary)...
                 self.infoBox.noDataSent(
                         u'No annotation key was provided for imported labels.'
                 )
-                self.send('Merged data', None)
+                self.send('Merged data', None, self)
                 return
         else:
             labelKey = None
                 self.infoBox.noDataSent(
                         u'No annotation key was provided for auto-numbering.'
                 )
-                self.send('Merged data', None)
+                self.send('Merged data', None, self)
                 return
         else:
             autoNumberKey = None
         message = pluralize(message, len(concatenation))
         self.infoBox.dataSent(message)
 
-        self.send('Merged data', concatenation)
+        self.send('Merged data', concatenation, self)
         self.sendButton.resetSettingsChangedFlag()
 
 
 
     def handleNewSignals(self):
         """Overridden: called after multiple signals have been added"""
-        self.restoreSettings()
+        try:
+            self.restoreSettings()
+        except AttributeError:
+            pass
 
     def getSettings(self, alsoContexts = True, globalContexts=False):
         """Overridden: called when a file is saved (among other situations)"""
-        self.storeSettings()
+        try:
+            self.storeSettings()
+        except AttributeError:
+            pass
         return super(type(self), self).getSettings(
                 alsoContexts = True, globalContexts=False
         )
         """
         if not self.settingsRestored:
             self.settingsRestored = True
-            newTexts = list()
             oldTexts = self.texts[:]
             for senderUuidIndex in xrange(len(self.savedSenderUuidOrder)):
                 for text in oldTexts:
                     senderUuid = self.savedSenderUuidOrder[senderUuidIndex]
-                    if text[0][0].uuid == senderUuid:
+                    if text[0][2].uuid == senderUuid:
                         self.texts[senderUuidIndex] = text
                         break
             self.textLabels = [text[1].label for text in self.texts]
         on the particular segmentations that enter this widget.
         """
         if self.settingsRestored:
-            self.savedSenderUuidOrder = [t[0][0].uuid for t in self.texts]
+            self.savedSenderUuidOrder = [t[0][2].uuid for t in self.texts]
 
 
 

_textable/widgets/OWTextablePreprocess.py

 #=============================================================================
-# Class OWTextablePreprocess, v0.06
+# Class OWTextablePreprocess, v0.07
 # Copyright 2012-2013 LangTech Sarl (info@langtech.ch)
 #=============================================================================
 # This file is part of the Textable (v1.3) extension to Orange Canvas.
         """Preprocess and send data"""
         if not self.segmentation:
             self.infoBox.noDataSent(u'No input.')
-            self.send('Preprocessed data', None)
+            self.send('Preprocessed data', None, self)
             return
         if not self.segmentation.is_non_overlapping():
             self.infoBox.noDataSent(u'Input segmentation is overlapping.')
-            self.send('Preprocessed data', None)
+            self.send('Preprocessed data', None, self)
             return
         if not self.label:
             self.infoBox.noDataSent(u'No label was provided.')
-            self.send('Preprocessed data', None)
+            self.send('Preprocessed data', None, self)
             return
         if self.applyCaseTransform:
             if self.caseTransform == 'to lower':
         progressBar.finish()
         newNumInputs = len(Segmentation.data)
         self.createdInputIndices = range(previousNumInputs, newNumInputs)
-        self.send('Preprocessed data', preprocessed_data)
+        self.send('Preprocessed data', preprocessed_data, self)
         message = u'Data contains %i segment@p.' % len(preprocessed_data)
         message = pluralize(message, len(preprocessed_data))
         self.infoBox.dataSent(message)

_textable/widgets/OWTextableRecode.py

 #=============================================================================
-# Class OWTextableRecode, v0.06
+# Class OWTextableRecode, v0.07
 # Copyright 2012-2013 LangTech Sarl (info@langtech.ch)
 #=============================================================================
 # This file is part of the Textable (v1.3) extension to Orange Canvas.
         # Check that there's something on input...
         if not self.segmentation:
             self.infoBox.noDataSent(u'No input.')
-            self.send('Recoded data', None)
+            self.send('Recoded data', None, self)
             return
 
         # Check that segmentation is non-overlapping...
         if not self.segmentation.is_non_overlapping():
             self.infoBox.noDataSent(u'Input segmentation is overlapping.')
-            self.send('Recoded data', None)
+            self.send('Recoded data', None, self)
             return
 
         # Check that label is not empty...
         if not self.label:
             self.infoBox.noDataSent(u'No label was provided.')
-            self.send('Recoded data', None)
+            self.send('Recoded data', None, self)
             return
 
         # Get substitutions from basic or advanced settings...
         progressBar.finish()
         newNumInputs = len(Segmentation.data)
         self.createdInputIndices = range(previousNumInputs, newNumInputs)
-        self.send('Recoded data', recoded_data)
+        self.send('Recoded data', recoded_data, self)
         message = u'Data contains %i segment@p.' % len(recoded_data)
         message = pluralize(message, len(recoded_data))
         self.infoBox.dataSent(message)

_textable/widgets/OWTextableSegment.py

 #=============================================================================
-# Class OWTextableSegment, v0.13
+# Class OWTextableSegment, v0.14
 # Copyright 2012-2013 LangTech Sarl (info@langtech.ch)
 #=============================================================================
 # This file is part of the Textable (v1.3) extension to Orange Canvas.
         # Check that there's something on input...
         if not self.inputSegmentation:
             self.infoBox.noDataSent(u'No input.')
-            self.send('Segmented data', None)
+            self.send('Segmented data', None, self)
             return
 
         # Check that there's at least one regex...
             or not (self.regex or self.displayAdvancedSettings)
         ):
             self.infoBox.noDataSent(u'No regex defined.')
-            self.send('Segmented data', None)
+            self.send('Segmented data', None, self)
             return
 
         # Get regexes from basic or advanced settings...
         # Check that label is not empty...
         if not self.label:
             self.infoBox.noDataSent(u'No label was provided.')
-            self.send('Segmented data', None)
+            self.send('Segmented data', None, self)
             return
 
         # Check that autoNumberKey is not empty (if necessary)...
                 self.infoBox.noDataSent(
                         u'No annotation key was provided for auto-numbering.'
                 )
-                self.send('Segmented data', None)
+                self.send('Segmented data', None, self)
                 return
         else:
             autoNumberKey = None
         message = pluralize(message, len(segmented_data))
         self.infoBox.dataSent(message)
 
-        self.send( 'Segmented data', segmented_data )
+        self.send( 'Segmented data', segmented_data, self)
         self.sendButton.resetSettingsChangedFlag()
 
 

_textable/widgets/OWTextableSelect.py

 #=============================================================================
-# Class OWTextableSelect, v0.10
+# Class OWTextableSelect, v0.11
 # Copyright 2012-2013 LangTech Sarl (info@langtech.ch)
 #=============================================================================
 # This file is part of the Textable (v1.3) extension to Orange Canvas.
         # Check that there's something on input...
         if not self.segmentation:
             self.infoBox.noDataSent(u'No input.')
-            self.send('Selected data', None)
+            self.send('Selected data', None, self)
             return
 
         # Check that label is not empty...
         if not self.label:
             self.infoBox.noDataSent(u'No label was provided.')
-            self.send('Selected data', None)
+            self.send('Selected data', None, self)
             return
 
         # Advanced settings...
                 # Check that regex is not empty...
                 if not self.regex:
                     self.infoBox.noDataSent(u'No regex defined.')
-                    self.send('Selected data', None)
+                    self.send('Selected data', None, self)
                     return
 
                 # Prepare regex...
                     sampleSize = self.sampleSize
                 if sampleSize <= 0:
                     self.infoBox.noDataSent(u'Sample size too small.')
-                    self.send('Selected data', None)
+                    self.send('Selected data', None, self)
                     return
 
                 # Get number of iterations...
                     self.infoBox.noDataSent(
                             u'No annotation key was provided for auto-numbering.'
                     )
-                    self.send('Selected data', None)
+                    self.send('Selected data', None, self)
                     return
             else:
                 autoNumberKey = None
             # Check that regex is not empty...
             if not self.regex:
                 self.infoBox.noDataSent(u'No regex defined.')
-                self.send('Selected data', None)
+                self.send('Selected data', None, self)
                 return
 
             # Get number of iterations...
         message = pluralize(message, len(selected_data))
         self.infoBox.dataSent(message)
 
-        self.send( 'Selected data', selected_data )
-        self.send( 'Discarded data', discarded_data )
+        self.send( 'Selected data', selected_data, self)
+        self.send( 'Discarded data', discarded_data, self)
         self.sendButton.resetSettingsChangedFlag()
 
 

_textable/widgets/OWTextableTextField.py

 #=============================================================================
-# Class OWTextableTextField, v0.06
+# Class OWTextableTextField, v0.07
 # Copyright 2012-2013 LangTech Sarl (info@langtech.ch)
 #=============================================================================
 # This file is part of the Textable (v1.3) extension to Orange Canvas.
 
 from unicodedata        import normalize
 from PyQt4              import QtCore
+from LTTL.Segmentation  import Segmentation
 from LTTL.Input         import Input
 
 from TextableUtils      import *
 
         # Input and output channels...
         self.inputs             = []
-        self.outputs            = [('Text data', Input)]
+        self.outputs            = [('Text data', Segmentation)]
 
         # Settings...
         self.textFieldContent   = u''.encode('utf-8')
         # Check that text field is not empty...
         if not self.textFieldContent:
             self.infoBox.noDataSent(u'Text field is empty.')
-            self.send('Text data', None)
+            self.send('Text data', None, self)
             return
 
         # Check that label is not empty...
         if not self.label:
             self.infoBox.noDataSent(u'No label was provided.')
-            self.send('Text data', None)
+            self.send('Text data', None, self)
             return
 
         # Set status to OK...
         self.segmentation.update(textFieldContent, label=self.label)
 
         # Send token...
-        self.send('Text data', self.segmentation)
+        self.send('Text data', self.segmentation, self)
         self.sendButton.resetSettingsChangedFlag()
 
 

_textable/widgets/OWTextableTextFiles.py

 #=============================================================================
-# Class OWTextableTextFiles, v0.09
+# Class OWTextableTextFiles, v0.10
 # Copyright 2012-2013 LangTech Sarl (info@langtech.ch)
 #=============================================================================
 # This file is part of the Textable (v1.3) extension to Orange Canvas.
              or not (self.file or self.displayAdvancedSettings)
         ):
             self.infoBox.noDataSent(u'No input.')
-            self.send('Text data', None)
+            self.send('Text data', None, self)
             return
 
         # Check that label is not empty...
         if not self.label:
             self.infoBox.noDataSent(u'No label was provided.')
-            self.send('Text data', None)
+            self.send('Text data', None, self)
             return
 
         # Check that autoNumberKey is not empty (if necessary)...
                 self.infoBox.noDataSent(
                         u'No annotation key was provided for auto-numbering.'
                 )
-                self.send('Text data', None)
+                self.send('Text data', None, self)
                 return
         else:
             autoNumberKey = None
                     )
                     m = '\n\t'.join(textwrap.wrap(m, 35))
                     self.infoBox.noDataSent(m)
-                    self.send('Text data', None)
+                    self.send('Text data', None, self)
                     return
                 finally:
                     fileHandle.close()
                         35
                 ))
                 self.infoBox.noDataSent(m)
-                self.send('Text data', None)
+                self.send('Text data', None, self)
                 return
 
             # Replace newlines with '\n'...

_textable/widgets/OWTextableURLs.py

 #=============================================================================
-# Class OWTextableURLs, v0.06
+# Class OWTextableURLs, v0.07
 # Copyright 2012-2013 LangTech Sarl (info@langtech.ch)
 #=============================================================================
 # This file is part of the Textable (v1.3) extension to Orange Canvas.
              or not (self.URL or self.displayAdvancedSettings)
         ):
             self.infoBox.noDataSent(u'No input.')
-            self.send('Text data', None)
+            self.send('Text data', None, self)
             return
 
         # Check that label is not empty...
         if not self.label:
             self.infoBox.noDataSent(u'No label was provided.')
-            self.send('Text data', None)
+            self.send('Text data', None, self)
             return
 
         # Check that autoNumberKey is not empty (if necessary)...
                 self.infoBox.noDataSent(
                         u'No annotation key was provided for auto-numbering.'
                 )
-                self.send('Text data', None)
+                self.send('Text data', None, self)
                 return
         else:
             autoNumberKey = None
                     )
                     m = '\n\t'.join(textwrap.wrap(m, 35))
                     self.infoBox.noDataSent(m)
-                    self.send('Text data', None)
+                    self.send('Text data', None, self)
                     return
                 finally:
                     URLHandle.close()
                         35
                 ))
                 self.infoBox.noDataSent(m)
-                self.send('Text data', None)
+                self.send('Text data', None, self)
                 return
 
             # Replace newlines with '\n'...
         message = pluralize(message, numChars)
         self.infoBox.dataSent(message)
 
-        self.send( 'Text data', self.segmentation )
+        self.send( 'Text data', self.segmentation, self)
         self.sendButton.resetSettingsChangedFlag()
 
 

_textable/widgets/OWTextableVariety.py

 #=============================================================================
-# Class OWTextableVariety, v0.06
+# Class OWTextableVariety, v0.08
 # Copyright 2012-2013 LangTech Sarl (info@langtech.ch)
 #=============================================================================
 # This file is part of the Textable (v1.3) extension to Orange Canvas.
 
     def handleNewSignals(self):
         """Overridden: called after multiple signals have been added"""
-        self.restoreSettings()
+        try:
+            self.restoreSettings()
+        except AttributeError:
+            pass
 
     def getSettings(self, alsoContexts = True, globalContexts=False):
         """Overridden: called when a file is saved (among other situations)"""
-        self.storeSettings()
+        try:
+            self.storeSettings()
+        except AttributeError:
+            pass
         return super(type(self), self).getSettings(
                 alsoContexts = True, globalContexts=False
         )
             self.mode             = self.savedMode
             for segIndex in xrange(len(self.segmentations)):
                 segmentation = self.segmentations[segIndex]
-                if segmentation[0][0].uuid == self.savedUnitSenderUuid:
+                if segmentation[0][2].uuid == self.savedUnitSenderUuid:
                     self.units = segIndex
                 if self.mode == u'Containing segmentation':
-                    if segmentation[0][0].uuid == self.savedContextSenderUuid:
+                    if segmentation[0][2].uuid == self.savedContextSenderUuid:
                         self.contexts = segIndex
             self.updateGUI()
             if self.units is not None:
             self.savedMode                      =    self.mode
             if self.units is not None:
                 segmentation                  = self.segmentations[self.units]
-                self.savedUnitSenderUuid        = segmentation[0][0].uuid
+                self.savedUnitSenderUuid        = segmentation[0][2].uuid
                 self.savedUnitAnnotationKey     = self.unitAnnotationKey
                 self.savedCategoryAnnotationKey = self.categoryAnnotationKey
             else:
             if          self.mode == u'Containing segmentation' \
                     and self.contexts is not None:
                 segmentation = self.segmentations[self.contexts]
-                self.savedContextSenderUuid = segmentation[0][0].uuid
+                self.savedContextSenderUuid = segmentation[0][2].uuid
                 self.savedContextAnnotationKey \
                         = self.contextAnnotationKey
             else:

_textable/widgets/TextableUtils.py

     replacement = plural if criterion > 1 else singular
     return re.compile(r'@p').sub(replacement, input_string)
 
-
-def updateMultipleInputs(itemList, newItem, newId=None, removalCallback=None):
+def updateMultipleInputs(
+        itemList,
+        newItem,
+        newId           = None,
+        removalCallback = None
+    ):
     """Process input when the widget can take multiple ones"""
     ids = [x[0] for x in itemList]
     if not newItem: # remove

_textable/widgets/icons/Thumbs.db

Binary file modified.

docs/rst/annotating_merging.rst

+Annotating by merging
+=====================
+
+In preparation.
+

docs/rst/annotation.rst

+Annotation
+==========
+
+In preparation.
+

docs/rst/annotations.rst

+Annotations
+===========
+
+Annotations let you go beyond what's in the text.
+
+.. toctree::
+    :maxdepth: 1
+   
+    Annotations and their uses <annotations_uses>
+    Annotating by merging <annotating_merging>
+    Converting XML markup to annotations <converting_xml_markup_annotations>
+    Exploiting annotations <exploiting_annotations>
+    
+
+

docs/rst/annotations_uses.rst

+Annotations and their uses
+==========================
+
+In preparation.
+

docs/rst/case_studies.rst

+Case studies
+============
+
+In preparation.
+
 
 # General information about the project.
 project = DOCUMENTATION_NAME
-copyright = AUTHOR
+copyright = u'2012-2013 ' + AUTHOR
 
 # The version info for the project you're documenting, acts as replacement for
 # |version| and |release|, also used in various other places throughout the
 html_show_sphinx = False
 
 # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
-html_show_copyright = False
+# html_show_copyright = False
 
 # 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

docs/rst/context.rst

+Context
+=======
+
+In preparation.
+

docs/rst/convert.rst

+Convert
+=======
+
+In preparation.
+

docs/rst/converting_table_formats.rst

+Converting between table formats
+================================
+
+In preparation.
+

docs/rst/converting_xml_markup_annotations.rst

+Converting XML markup to annotations
+====================================
+
+In preparation.
+

docs/rst/cookbook.rst

+Cookbook
+========
+
+In preparation.
+

docs/rst/count.rst

+Count
+=====
+
+In preparation.
+

docs/rst/counting_segment_types.rst

+Counting segment types
+======================
+
+In preparation.
+

docs/rst/counting_specific_contexts.rst

+Counting in specific contexts
+=============================
+
+In preparation.
+

docs/rst/display.rst

+Display
+=======
+
+In preparation.
+

docs/rst/exploiting_annotations.rst

+Exploiting annotations
+======================
+
+In preparation.
+

docs/rst/extract_xml.rst

+Extract XML
+===========
+
+In preparation.
+

docs/rst/figures/Thumbs.db

Binary file added.

docs/rst/figures/chaining_segmentations.png

Added
New image

docs/rst/figures/display_example.png

Added
New image

docs/rst/figures/display_merged_example.png

Added
New image

docs/rst/figures/goal_exercise_merge.png

Added
New image

docs/rst/figures/intersect_example.png

Added
New image

docs/rst/figures/intersect_example_scheme.png

Added
New image

docs/rst/figures/logo.png

Added
New image

docs/rst/figures/merge_example.png

Added
New image

docs/rst/figures/merge_example_scheme.png

Added
New image

docs/rst/figures/segment_example.png

Added
New image

docs/rst/figures/segment_example_scheme.png

Added
New image

docs/rst/figures/select_example.png

Added
New image

docs/rst/figures/select_example_reset_signals_dialog.png

Added
New image

docs/rst/figures/select_example_scheme.png

Added
New image

docs/rst/figures/solution_exercise_merge.png

Added
New image

docs/rst/figures/text_field_example.png

Added
New image

docs/rst/getting_started.rst

+Getting started
+===============
+
+This part of the documentation introduces the basic usage patterns of Orange
+Textable. It is meant to be read in the indicated order.
+
+.. toctree::
+    :maxdepth: 1
+    :numbered:
+
+    Segmentations <segmentations>
+    Tables <tables>
+    Annotations <annotations>
+    
+
+

docs/rst/hierarchical_segmentations_performance_issues.rst

+Hierarchical segmentations and performance issues
+=================================================
+
+When widget :doc:`Segment <segment>` is applied to real, much longer texts
+than *a simple example*, using such general regexes as *\\w+* or *\\w* may
+result in the creation of a huge number of segments. Creating and manipulating
+such segmentations can slow down excessively the execution of Orange Textable,
+or even lead to memory overflow.
+
+However, it is sometimes necessary to segment large texts into words or
+letters, for instance in order to examine their frequency distribution. In
+that case, if hardware allows it, a lot of time can be saved at the expense
+of memory usage. Indeed, the cumulated time required to successively create
+several ever more fine-grained segmentations (for instance into lines, then
+words, then letters) is usually spectacularly shorter than the time required
+to produce the most fine-grained segmentation directly (see :ref:`figure 1
+<hierarchical_segmentations_performance_issues_fig1>` below).
+
+.. _hierarchical_segmentations_performance_issues_fig1:
+
+.. figure:: figures/chaining_segmentations.png
+    :align: center
+    :alt: chained hierarchical segmentations execute faster
+    :figclass: align-center
+
+    Figure 1: Chaining :doc:`Segment <segment>` instances to reduce execution time.
+
+The situation is different when word or letter segmentation are conceived
+as intermediate steps toward the creation of a segmentation containing only
+selected words or letters. In that case, it is much more efficient (in memory
+and execution time) to use a single instance of :doc:`Segment <segment>` with
+a regex identifying only the desired words, as seen
+:doc:`previously <segmenting_data_smaller_units>`
+with the example of *\\bretriev(e|es|ed|ing)\\b*.

docs/rst/index.rst

 
 .. _Orange: http://orange.biolab.si/
 
-Textable was designed and implemented `LangTech Sarl <http://langtech.ch>`_ on behalf of the department of language and information sciences (SLI_) at the `University of Lausanne <http://www.unil.ch>`_.
+Textable was designed and implemented by `LangTech Sarl <http://langtech.ch>`_
+on behalf of the department of language and information sciences (SLI_) at the
+`University of Lausanne <http://www.unil.ch>`_.
 
 .. _SLI: http://www.unil.ch/sli
 
-Installation
-------------
+Contents
+--------
 
-To install Orange Textable add-on for Orange from PyPi_ run::
+.. toctree::
+    :maxdepth: 3
+   
+    Installation <installation>
+    Getting started <getting_started>
+    Widget reference <widget_reference>
+    Cookbook <cookbook>
+    Case studies <case_studies>
 
-    pip install Orange-Textable
+Further resource
+----------------
 
-To install it from source code run::
+The project's homepage is hosted at `langtech.ch
+<http://langtech.ch/textable>`_. Links to the source repository
+and further resource may be found there.
 
-    python setup.py install
-
-To build Python egg run::
-
-    python setup.py bdist_egg
-
-.. _PyPi: http://pypi.python.org/pypi
-
-Source Code and Issue Tracker
------------------------------
-
-Source code is available on Bitbucket_.
-
-.. _Bitbucket: https://bitbucket.org/langtech/orange-textable
 

docs/rst/installation.rst

+Installation
+============
+
+To install Orange Textable add-on for Orange from PyPi_ run::
+
+    pip install Orange-Textable
+
+To install it from source code run::
+
+    python setup.py install
+
+Orange Textable can also be installed directly from within Orange Canvas,
+using the Add-ons manager (menu **Options > Add-ons**).
+
+.. _PyPi: https://pypi.python.org/pypi/Orange-Textable

docs/rst/intersect.rst

+Intersect
+=========
+
+In preparation.
+

docs/rst/keyboard_input_segmentation_display.rst

+Keyboard input and segmentation display
+=======================================
+
+Typing text in a :doc:`Text Field <text_field>` widget is the simplest way to
+import a string in Orange Textable. This widget has no input connexions, and
+emits in output a segmentation containing a single segment whose address
+points to the entire string that was typed. This segmentation is assigned the
+label specified in the **Output segmentation label** field (see
+:ref:`figure 1 <keyboard_input_segmentation_fig1>` below):
+
+.. _keyboard_input_segmentation_fig1:
+
+.. figure:: figures/text_field_example.png
+    :align: center
+    :alt: Example usage of widget Text Field
+    :figclass: align-center
+
+    Figure 1: Typing *a simple example* in widget :doc:`Text Field <text_field>`.
+    
+This widget's simplicity makes it most adequate for pedagogic purposes. Later,
+we will discover other, more powerful ways of importing strings.
+
+The :doc:`Display <display>` widget can be used to visualize the details
+of a segmentation. By default, it shows the segmentation's label followed by
+each successive segment's address and content. A segmentation sent by a
+:doc:`Text Field <text_field>` instance will contain a single segment
+covering the whole string (see :ref:`figure 2
+<keyboard_input_segmentation_fig2>` below).
+
+.. _keyboard_input_segmentation_fig2:
+
+.. figure:: figures/display_example.png
+    :align: center
+    :alt: Example usage of widget Display
+    :figclass: align-center
+
+    Figure 2: Viewing *a simple example* in widget :doc:`Display <display>`.
+    
+By default, :doc:`Display <display>` passes its input data without
+modification to its output connexions. It is very useful for viewing
+intermediate results in an Orange Textable scheme and making sure that other
+widgets process data as expected.
+    
+
+
+

docs/rst/length.rst

+Length
+======
+
+In preparation.
+

docs/rst/merge.rst

+Merge
+=====
+
+In preparation.
+

docs/rst/merging_segmentations_together.rst

+Merging segmentations together
+==============================
+
+Computerized text analysis often implies consolidating various text sources
+into a single *corpus*. In the framework of Orange Textable, this amounts
+to grouping segmentations together, and it is the purpose of the
+:doc:`Merge <merge>` widget.
+
+To try out this widget, create on the canvas two instances of
+:doc:`Text Field <text_field>`, an instance of :doc:`Merge <merge>` and an
+instance of :doc:`Display <display>` (see
+:ref:`figure 1 <merging_segmentations_together_fig1>` below). Type
+a different string in each :doc:`Text Field <text_field>` instance (e.g.
+*a simple example* and *another example*) and assign it a distinct label (e.g.
+*text_string* and *text_string2*). Eventually, connect the instances as
+shown on :ref:`figure 1 <merging_segmentations_together_fig1>`.
+
+.. _merging_segmentations_together_fig1:
+
+.. figure:: figures/merge_example_scheme.png
+    :align: center
+    :alt: Scheme illustrating the usage of widget Merge
+    :figclass: align-center
+
+    Figure 1: Grouping *a simple example* with *another example* using widget :doc:`Merge <merge>`.
+
+The interface of widget :doc:`Merge <merge>` (see
+:ref:`figure 2 <merging_segmentations_together_fig2>` below) illustrates a
+feature shared by most Orange Textable widgets: the **Advanced settings**
+checkbox triggers the display of more complex controls offering more
+possibilities to the user. For now we will stick to the basic settings and
+leave the box unchecked.
+
+.. _merging_segmentations_together_fig2:
+
+.. figure:: figures/merge_example.png
+    :align: center
+    :alt: Interface of widget merge
+    :figclass: align-center
+
+    Figure 2: Interface of widget :doc:`Merge <merge>`.
+    
+Section **Ordering** of the widget's interface lets the user view the labels
+of incoming segmentations and control the order in which they will appear in
+the output segmentation (by selecting them and clicking on **Move Up** /
+**Down**). The **Output segmentation label** can be set in section
+**Options**. We will return :doc:`later <annotating_merging>` to the purpose
+of checkbox **Import labels with key**; leave it unchecked for now.
+
+.. _merging_segmentations_together_fig3:
+
+.. figure:: figures/display_merged_example.png
+    :align: center
+    :alt: Displaying a merged segmentation
+    :figclass: align-center
+
+    Figure 3: Merged segmentation.
+
+:ref:`Figure 3 <merging_segmentations_together_fig3>` above shows the
+resulting merged segmentation, as displayed by widget
+:doc:`Display <display>`. As can be seen, :doc:`Merge <merge>` makes it easy
+to concatenate several strings into a single segmentation. If the incoming
+segmentations contained several segments, each of them would appear in the
+output segmentation, in the order specified under **Ordering** (and, within
+each incoming segmentation, in the original order of segments).
+
+.. _merging_segmentations_together_ex1:
+
+**Exercise 1:** Can you add a new instance of :doc:`Merge <merge>` to the
+scheme illustrated on :ref:`figure 1 <merging_segmentations_together_fig1>`
+above and modify the connections (but not the configuration of existing
+widgets) so that the segmentation given in
+:ref:`figure 4 <merging_segmentations_together_fig1>` below appears in the
+:doc:`Display <display>` widget?
+(:ref:`solution <solution_merging_segmentations_together_ex1>`)
+
+.. _merging_segmentations_together_fig4:
+
+.. figure:: figures/goal_exercise_merge.png
+    :align: center
+    :alt: 3 segments: "a simple example", "another example", "another example"
+    :figclass: align-center
+
+    Figure 4: The segmentation requested in :ref:`exercise 1 <merging_segmentations_together_ex1>`.
+
+.. _solution_merging_segmentations_together_ex1:
+
+**Solution to exercise 1:** (:ref:`back to the exercise <merging_segmentations_together_ex1>`)
+
+.. figure:: figures/solution_exercise_merge.png
+    :align: center
+    :alt: New Merge widget takes input from old one and Text field, and sends output to Display
+    :figclass: align-center
+
+    Figure 5: Solution to :ref:`exercise 1 <merging_segmentations_together_ex1>`.
+

docs/rst/note_regular_expressions.rst

+A note on regular expressions
+=============================
+
+Orange Textable widgets rely heavily on *regular expressions* (or *regexes*),
+which are essentially a body of conventions for describing a set of strings
+by means of a single string. These conventions are widely documented in books
+and on the Internet, so we will not give here yet another introduction to this
+topic. Nevertheless, a basic knowledge of regexes is required to perform any
+non-trivial task with Orange Textable, and more advanced knowledge to
+fully exploit the software's possibilities.
+
+The syntax of regexes is partly standardized, but some variations remain.
+Orange Textable uses Python regexes, for which Python documentation is the
+best source of information. In particular, it features a good
+`introduction to regexes <http://docs.python.org/2/howto/regex.html>`_. A
+first reading might be limited to the following sections:
+
+    - `Simple Patterns <http://docs.python.org/2/howto/regex.html#simple-patterns>`_
+    - `More Metacharaters <http://docs.python.org/2/howto/regex.html#more-metacharacters>`_
+    
+Also recommended are the following:
+
+    - `Compilation Flags <http://docs.python.org/2/howto/regex.html#compilation-flags>`_
+    - `Lookahead Assertions <http://docs.python.org/2/howto/regex.html#lookahead-assertions>`_
+    - `Greedy vs. Non-Greedy <http://docs.python.org/2/howto/regex.html#greedy-versus-non-greedy>`_
+
+

docs/rst/partitioning_segmentations.rst

+Partitioning segmentations
+==========================
+
+There are many situations where we might want so selectively in- or exclude
+segments from a segmentation. For instance, a user might be want to exclude
+from a word segmentation all those that are less than 4 letters long. The
+:doc:`Select <select>` widget is tailored for such tasks.
+
+The widget's interface (see :ref:`figure 1 <partitioning_segmentations_fig1>`
+below) offers a choice between two modes: *Include* and *Exclude*. Depending
+on this parameter, incoming segments that satisfy a given condition will be
+either included in or excluded from the output segmentation. By default (i.e.
+when the **Advanced settings** box is unchecked), the condition is specified
+by means of a regex, which will be applied to each incoming segment
+successively. (For now, the option **Annotation key: (none)** can be ignored.)
+
+.. _partitioning_segmentations_fig1:
+
+.. figure:: figures/select_example.png
+    :align: center
+    :alt: Example usage of widget Select
+    :figclass: align-center
+
+    Figure 1: Excluding short words with widget :doc:`Select <select>`.
+
+In the example of :ref:`figure 1 <partitioning_segmentations_fig1>`, the
+widget is configured to exclude all incoming segments containing no more than
+3 letters. Note that without the *beginning of segment* and *end of segment*
+anchors (*^* and *$*), all words containing *at least* a sequence of 1 to 3
+letters--i.e. all the words--would be excluded.
+
+Note that :doc:`Select <select>` automatically emits a second segmentation
+containing all the segments that have been discarded from the main output
+segmentation (in the case of :ref:`figure 1 <partitioning_segmentations_fig1>`
+above, that would be all words less than 4 letters long). This feature is
+useful when both the selected *and* the discarded segments are to be further
+processed on distinct branches. By default, when :doc:`Select <select>` is connected to another widget, the
+main segmentation is being emitted. In order to send the segmentation of
+discarded segments instead, right-click on the outgoing connexion and select
+**Reset Signals** (see :ref:`figure 2 <partitioning_segmentations_fig2>`
+below).
+
+.. _partitioning_segmentations_fig2:
+
+.. figure:: figures/select_example_scheme.png
+    :align: center
+    :alt: Right-clicking on a connexion and requesting to "Reset Signals"
+    :figclass: align-center
+
+    Figure 2: Right-clicking on a connexion and requesting to **Reset Signals**.
+
+This opens the dialog shown on
+:ref:`figure 3 <partitioning_segmentations_fig3>` below, where the user can
+"drag-and-drop" from the gray box next to **Discarded data** up to the box
+next to **Segmentation**, thus replacing the existing green connexion.
+Clicking **OK** validates the modification and sends the discarded data
+through the connexion.
+
+.. _partitioning_segmentations_fig3:
+
+.. figure:: figures/select_example_reset_signals_dialog.png
+    :align: center
+    :alt: Dialog for modifying the connexion between two widgets
+    :figclass: align-center
+    :scale: 80 %
+
+    Figure 3: This dialog allows the user to select a non-default connexion between two widgets.
+
+

docs/rst/preprocess.rst

+Preprocess
+==========
+
+In preparation.
+

docs/rst/recode.rst

+Recode
+======
+
+In preparation.
+

docs/rst/segment.rst

+Segment
+=======
+
+In preparation.
+

docs/rst/segmentation_processing_widgets.rst

+Segmentation processing widgets
+===============================
+
+Widgets of this category take *Segmentation* data in input and emit data of
+the same type. Some of them (:doc:`Preprocess <preprocess>` and
+:doc:`Recode <recode>`) generate modified text data. Others
+(:doc:`Merge <merge>`, :doc:`Segment <segment>`, :doc:`Select <select>`,
+:doc:`Intersect <intersect>` and :doc:`Extract XML <extract_xml>`) do not
+generate new text data but only new *Segmentation* data.
+:doc:`Display <display>`, finally, is mainly used to visualize the details of
+a given *Segmentation* object (content and address of segments, as well as
+their possible annotations).
+
+.. toctree::
+    :maxdepth: 1
+
+    Preprocess <preprocess>
+    Recode <recode>
+    Merge <merge>
+    Segment <segment>
+    Select <select>
+    Intersect <intersect>
+    Extract XML <extract_xml>
+    Display <display>
+

docs/rst/segmentations.rst

+Segmentations
+=============
+
+Segmentations are at the heart of Orange Textable. Start learning about them.
+
+.. toctree::
+    :maxdepth: 1
+   
+    Strings, segments, and segmentations <strings_segments_segmentations>
+    Keyboard input and segmentation display <keyboard_input_segmentation_display>
+    Merging segmentations together <merging_segmentations_together>
+    A note on regular expressions <note_regular_expressions>
+    Segmenting data into smaller units <segmenting_data_smaller_units>
+    Hierarchical segmentations and performance issues <hierarchical_segmentations_performance_issues>
+    Partitioning segmentations <partitioning_segmentations>
+    Using a segmentation to filter another <using_segmentation_filter_another>
+
+

docs/rst/segmentations_tables.rst

+From segmentations to tables
+============================
+
+In preparation.
+

docs/rst/segmenting_data_smaller_units.rst

+Segmenting data into smaller units
+==================================
+
+We have seen :doc:`previously <merging_segmentations_together>` how to combine
+several segmentations into a single one. We will often be performing the
+inverse operation: create a segmentation whose segments are *parts* of another
+segmentation's segments. Typically, we will be segmenting strings into words,
+characters, or any kind of text units that will be later counted, measured,
+and so on. This is precisely the purpose of widget :doc:`Segment <segment>`.
+
+To try it out, create a new scheme with an instance of
+:doc:`Text Field <text_field>` connected to an instance of
+:doc:`Segment <segment>`, itself connected to an instance of
+:doc:`Display <display>` (see
+:ref:`figure 1 <segmenting_data_smaller_units_fig1>` below). In what follows,
+we will suppose that the string typed in :doc:`Text Field <text_field>` is
+*a simple example*.
+
+.. _segmenting_data_smaller_units_fig1:
+
+.. figure:: figures/segment_example_scheme.png
+    :align: center
+    :alt: Scheme illustrating the usage of widget Segment
+    :figclass: align-center
+
+    Figure 1: A scheme for testing the :doc:`Segment <segment>` widget
+    
+In its basic form (i.e. with **Advanced settings** unchecked, see
+:ref:`figure 2 <segmenting_data_smaller_units_fig2>` below),
+:doc:`Segment <segment>` takes a single parameter (aside from the
+**Output segmentation label**), namely a regex. The widget then looks for all
+matches of the regex pattern in each successive input segment, and creates for
+every match a new segment in the output segmentation.
+
+.. _segmenting_data_smaller_units_fig2:
+
+.. figure:: figures/segment_example.png
+    :align: center
+    :alt: Interface of widget Segment configured with regex "\w+"
+    :figclass: align-center
+
+    Figure 2: Interface of the :doc:`Segment <segment>` widget, configured for word segmentation
+
+For instance, the regex *\\w+* divides each incoming segment into sequences of
+alphanumeric character (and underscore)--which in our case amounts to
+segmenting *a simple example* into three words. To obtain a segmentation
+into letters (or to be precise, alphanumeric characters or underscores),
+simply use *\\w*.
+
+Of course, queries can be more specific. If the relevant unit is the word,
+regexes will often use the *\\b* *anchor*, which represents a word boundary.
+For instance, the words that contain less than 4 characters can be retrieved
+with *\\b\\w{1,3}\\b*, those ending in *-tion* with *\\b\\w+tion\\b*, and the
+flexion of *retrieve* with *\\bretriev(e|es|ed|ing)\\b*.

docs/rst/select.rst

+Select
+======
+
+In preparation.
+

docs/rst/strings_segments_segmentations.rst

+Strings, segments, and segmentations
+====================================
+
+The main purpose of Orange Textable is to build tables based on text strings.
+As we will see, there are several methods for importing text strings, the
+simplest of which is keyboard input using widget
+:doc:`Text Field <text_field>` (see also :doc:`Keyboard input and segmentation
+display <keyboard_input_segmentation_display>`). Whenever a new string is
+imported, it is assigned a unique identification number (called
+*string index*) and stays in memory as long as the widget that imported it.
+
+Consider the following string of 16 characters (note that whitespace counts as
+a character too), and let us suppose that its string index is 1:
+
+.. csv-table::
+    :stub-columns: 1
+    :widths: 10 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3
+
+    "Character", *a*, " ", *s*, *i*, *m*, *p*, *l*, *e*, " ", *e*, *x*, *a*, *m*, *p*, *l*, *e*
+    "Position", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,16
+
+In this context, a *segment* is basically a substring of characters. Every
+segment has an *address* consisting of three elements:
+
+    1. string index
+    2. initial position within the string
+    3. final position
+
+In the case of *a simple example*, address (1, 3, 8) refers to substring
+*simple*, (1, 12, 12) to character *a*, and (1, 1, 16) to the entire string.
+The substring corresponding to a given address is called the segment's
+*content*.
+
+A *segmentation* is an ordered list of segments. For instance, segmentation
+((1, 1, 1 ), (1, 3, 8), (1, 10, 16)) contains 3 word segments, ((1, 1, 1),
+(1, 2, 2 ), ..., (1, 16, 16)) contains 16 character segments, and ((1, 1, 16))
+contains a single segment covering the whole string.
+
+As shown by the word segmentation example, every character in the string needs
+not be included in a segment. Moreover, a single character may belong to
+several segments simultaneously, as in ((1, 1, 1), (1, 1, 8), (1, 3, 8),
+(1, 3, 16), (1, 10, 16), (1, 3, 8)). This also shows that the order of
+segments in a segmentation can diverge from the order of the corresponding
+substrings in the string.
+
+.. _string_segments_segmentations_ex1:
+
+**Exercise 1:** What is the content of each of the 6 segments in the previous
+example? (:ref:`solution <solution_string_segments_segmentations_ex1>`)
+
+In the previous examples, all the segments of a given segmentation refer to
+the same string. However, a segmentation may contain segments belonging to
+several distinct strings. Thus, if string *another example* has string index
+2, segmentation ((2, 1, 7), (1, 3, 16)) is perfectly valid.
+
+.. _string_segments_segmentations_ex2:
+
+**Exercise 2:** What is the content of the segments in the previous
+example? (:ref:`solution <solution_string_segments_segmentations_ex2>`)
+
+In order to store segmentations and transmit them between widgets, Orange
+Textable uses the *Segmentation* data type. Aside from the segment addresses,
+this data type associates a *label* with each segmentation, i.e. an arbitrary
+string used to identify the segmentation among others. [#]_
+
+.. _solution_string_segments_segmentations_ex1:
+
+**Solution to exercise 1:** *a*, *a simple*, *simple*, *simple example*, *example*,
+*simple* (in this order).
+(:ref:`back to the exercise <string_segments_segmentations_ex1>`)
+
+.. _solution_string_segments_segmentations_ex2:
+
+**Solution to exercise 2:** *another*, *simple example*.
+(:ref:`back to the exercise <string_segments_segmentations_ex2>`)
+