]> matita.cs.unibo.it Git - helm.git/blobdiff - helm/DEVEL/mathml_editor/src/TPushParser.cc
* this is a large commit
[helm.git] / helm / DEVEL / mathml_editor / src / TPushParser.cc
index 62a9208e66ac095920411ff0821e0c1ea2206446..906e8f414497e54254bd6ebc3dd4b0a9a596d05f 100644 (file)
@@ -5,27 +5,27 @@
 
 TPushParser::TPushParser(ALogger& l, const TDictionary& d) : APushParser(l), dictionary(d)
 {
-  init();
+  reset();
 }
 
 TPushParser::TPushParser(ALogger& l, AMathMLFactory& f, const TDictionary& d) : APushParser(l, f), dictionary(d)
 {
-  init();
+  reset();
+}
+
+TPushParser::~TPushParser()
+{
 }
 
 void
-TPushParser::init()
+TPushParser::reset()
 {
+  APushParser::reset();
   nextId = 1;
   cursor = doc.create("cursor");
   cursor["id"] = "I0";
   doc.clearDirty();
   doc.root().append(cursor);
-  logger.verbosity(ALogger::Debug);
-}
-
-TPushParser::~TPushParser()
-{
 }
 
 std::string
@@ -1233,159 +1233,156 @@ TPushParser::process(const TToken& token)
     case TToken::ACTIVE: do_active(token.value); break;
     case TToken::COMMENT: do_comment(); break;
     case TToken::CONTROL: do_control(token.value); break;
-    case TToken::GDELETE: do_gdelete(); break;
     }
 }
 
 void
 TPushParser::push(const TToken& token)
 {
-  if (token.category == TToken::GDELETE)
-    {
-      process(token);
-    }
-  else
-    {
-
-      TNode parent = cursor.parent();
-      // If the cursor has no parent then it is detached from the editing
-      // tree, which means this token will be ignored
-
-      if (parent)
-        // If the parent is a phantom group and the grand-parent is a
-        // control sequence, there are two cases:
-        // a. we are parsing a delimited argument of a entry
-        // b. we are parsing a side of a right- or left-open entry
-        if (parent.isG() && !parent.hasId() && parent.parent().isC())
-          {
-           // There must be an open frame, for the grand-parent is a control sequence
-           assert(!frames.empty());
-           Frame& frame = frames.top();
-           if (!frame.entry.pattern.empty())
+  TNode parent = cursor.parent();
+  // If the cursor has no parent then it is detached from the editing
+  // tree, which means this token will be ignored
+
+  if (parent)
+    // If the parent is a phantom group and the grand-parent is a
+    // control sequence, there are two cases:
+    // a. we are parsing a delimited argument of a entry
+    // b. we are parsing a side of a right- or left-open entry
+    if (parent.isG() && !parent.hasId() && parent.parent().isC())
+      {
+       // There must be an open frame, for the grand-parent is a control sequence
+       assert(!frames.empty());
+       Frame& frame = frames.top();
+       if (!frame.entry.pattern.empty())
+         {
+           // The entry pattern is not empty. By our conventions this means
+           // the entry cannot be open at either end, hence we are parsing
+           // a delimited argument
+           assert(frame.pos + 1 < frame.entry.pattern.size());
+           assert(frame.entry.pattern[frame.pos + 1].category != TToken::PARAMETER);
+           if (frame.entry.pattern[frame.pos + 1] == token)
              {
-               // The entry pattern is not empty. By our conventions this means
-               // the entry cannot be open at either end, hence we are parsing
-               // a delimited argument
-               assert(frame.pos + 1 < frame.entry.pattern.size());
-               assert(frame.entry.pattern[frame.pos + 1].category != TToken::PARAMETER);
-               if (frame.entry.pattern[frame.pos + 1] == token)
-                 {
-                   // The token matches with a delimiter of the argument, 
-                   // so we increment the frame.pos
+               // The token matches with a delimiter of the argument, 
+               // so we increment the frame.pos
+               frame.pos++;
+
+               if (frame.entry.lastDelimiter(frame.pos))
+                 {
+                   // this delimiter is the last one for the argumet, 
+                   // so the argument is completed
+                   cursor.remove();
                    frame.pos++;
 
-                   if (frame.entry.lastDelimiter(frame.pos))
+                   if (frame.pos == frame.entry.pattern.size())
                      {
-                       // this delimiter is the last one for the argumet, 
-                       // so the argument is completed
-                       cursor.remove();
-                       frame.pos++;
-
-                       if (frame.pos == frame.entry.pattern.size())
-                         {
-                           // This token has completed the entry
-                           advance(parent);
-                         }
-                       else if (frame.entry.paramDelimited(frame.pos))
-                         {
-                           // For the next is a delimited argument we have to place
-                           // a suitable phantom group with the cursor inside
-                           TNode g = doc.createG();
-                           parent.parent().append(g);
-                           g.append(cursor);
-                         }
-                       else
-                         parent.parent().append(cursor);
+                       // This token has completed the entry
+                       advance(parent);
                      }
-                 }
-               else
-                 {
-                   // Delimiter mismatch.
-                   if (frame.entry.pattern[frame.pos].category != TToken::PARAMETER)
+                   else if (frame.entry.paramDelimited(frame.pos))
                      {
-                       // in this case, there is a sequence of delimiters that delimitates
-                       // the argument, and the user correctly inserted a portion of this 
-                       // sequence, but now has inserted a wrong delimiter.
-                       // Here, there are some possibilities:
-                       //   - ignore the token, and wait for the correct delimiter
-                       //   - ignore the token, wait for the correct delimiter and emit an error
-                       // At the moment, we implement the second possibily
-                       logger.error("parser: it's not the correct delimiter...you have to type " + frame.entry.pattern[frame.pos + 1].value);
+                       // For the next is a delimited argument we have to place
+                       // a suitable phantom group with the cursor inside
+                       TNode g = doc.createG();
+                       parent.parent().append(g);
+                       g.append(cursor);
                      }
                    else
-                     {
-                       // in this case, the sequence of delimiters is composed of one 
-                       // delimiter. It means that we have to process the token
-                       process(token);
-                     }
-                 }
+                     parent.parent().append(cursor);
+                 }
              }
            else
              {
-               // The entry pattern is empty, hence we are parsing a right-open
-               // entry. What happens if we actually are in the left side?
-               // This could happen only when re-editing an entered expression
-               // We'll see...
-               assert(frame.entry.rightOpen);
-               process(token);
-             }
-          }
-        else if (parent.isC())
-          {
-           // We are parsing a non-delimited argument entry
-           // or a fixed token
-           Frame& frame = frames.top();
-           assert(frame.pos < frame.entry.pattern.size());
-
-           if (frame.entry.pattern[frame.pos].category == TToken::PARAMETER)
-             {
-               // As by the TeX parsing rules of undelimited parameters,
-               // empty spaces are ignored
-               if (token.category != TToken::SPACE)
-                 {
-                   // We need to increase the frame position here, becase inside
-                   // process the function advance will be called. At that point
-                   // it will be important for the parser to know that the entry
-                   // has been completed in order to place the cursor correctly
-                   // in the next position
-                   frame.pos++;
+               // Delimiter mismatch.
+               if (frame.entry.pattern[frame.pos].category != TToken::PARAMETER)
+                 {
+                   // in this case, there is a sequence of delimiters that delimitates
+                   // the argument, and the user correctly inserted a portion of this 
+                   // sequence, but now has inserted a wrong delimiter.
+                   // Here, there are some possibilities:
+                   //   - ignore the token, and wait for the correct delimiter
+                   //   - ignore the token, wait for the correct delimiter and emit an error
+                   // At the moment, we implement the second possibily
+                   logger.error("parser: it's not the correct delimiter...you have to type " + frame.entry.pattern[frame.pos + 1].value);
+                 }
+               else
+                 {
+                   // in this case, the sequence of delimiters is composed of one 
+                   // delimiter. It means that we have to process the token
                    process(token);
-                 }
+                 }
              }
-           else if (frame.entry.pattern[frame.pos] == token)
+         }
+       else
+         {
+           // The entry pattern is empty, hence we are parsing a right-open
+           // entry. What happens if we actually are in the left side?
+           // This could happen only when re-editing an entered expression
+           // We'll see...
+           assert(frame.entry.rightOpen);
+           process(token);
+         }
+      }
+    else if (parent.isC())
+      {
+       // We are parsing a non-delimited argument entry
+       // or a fixed token
+       Frame& frame = frames.top();
+       assert(frame.pos < frame.entry.pattern.size());
+
+       if (frame.entry.pattern[frame.pos].category == TToken::PARAMETER)
+         {
+           // As by the TeX parsing rules of undelimited parameters,
+           // empty spaces are ignored
+           if (token.category != TToken::SPACE)
              {
-               // The token has been accepted
-               frame.pos++;
-               if (frame.pos < frame.entry.pattern.size() &&
-                   frame.entry.paramDelimited(frame.pos))
-                 {
-                   // If the next is a delimited argument we have to place
-                   // the phantom group with the cursor inside
-                   TNode g = doc.createG();
-                   cursor.replace(g);
-                   g.append(cursor);
-                 }
-               else
-                 advance(parent);
+               // We need to increase the frame position here, becase inside
+               // process the function advance will be called. At that point
+               // it will be important for the parser to know that the entry
+               // has been completed in order to place the cursor correctly
+               // in the next position
+               frame.pos++;
+               process(token);
              }
-           else
+         }
+       else if (frame.entry.pattern[frame.pos] == token)
+         {
+           // The token has been accepted
+           frame.pos++;
+           if (frame.pos < frame.entry.pattern.size() &&
+               frame.entry.paramDelimited(frame.pos))
              {
-               // There is a mismatch. Emit an error and ignore the token?
-               logger.debug("parser: token ignored: " + token.value);
+               // If the next is a delimited argument we have to place
+               // the phantom group with the cursor inside
+               TNode g = doc.createG();
+               cursor.replace(g);
+               g.append(cursor);
              }
+           else
+             advance(parent);
+         }
+       else
+         {
+           // There is a mismatch. Emit an error and ignore the token?
+           logger.debug("parser: token ignored: " + token.value);
+         }
 
-          }
-        else
-          process(token);
-      else
-        {
-          logger.warning("ignored token");
-        }
-
-    } // this end corresponds to the else of the if (token.category == TToken::GDELETE)
+      }
+    else
+      process(token);
+  else
+    {
+      logger.warning("ignored token");
+    }
 
-  if (factory) factory->documentModified(doc);
+  if (factory && doc.dirtyNode() && !frozen()) factory->documentModified(doc);
+}
 
+std::string
+TPushParser::drop()
+{
+  do_gdelete();
+  if (factory && doc.dirtyNode() && !frozen()) factory->documentModified(doc);
+  return "";
 }
 
 void
@@ -1426,6 +1423,21 @@ TPushParser::advance(const TNode& node)
 void
 TPushParser::setCursorHint(const std::string& c)
 {
-  cursor["val"] = c;
-  if (factory) factory->documentModified(doc);
+  if (cursor["val"] != c)
+    {
+      cursor["val"] = c;
+      if (factory && doc.dirtyNode() && !frozen()) factory->documentModified(doc);
+    }
+}
+
+bool
+TPushParser::thaw()
+{
+  if (APushParser::thaw() && factory && doc.dirtyNode())
+    {
+      factory->documentModified(doc);
+      return true;
+    }
+  else
+    return false;
 }