]> matita.cs.unibo.it Git - helm.git/blobdiff - helm/DEVEL/mathml_editor/src/TPushParser.cc
Added the completion of the macro's name.
[helm.git] / helm / DEVEL / mathml_editor / src / TPushParser.cc
index 863ca7bb06e4e1bfb2e956036605e31ee76b7a87..433b3fdec3b3568f38f453eba1edd11f82622168 100644 (file)
@@ -437,10 +437,19 @@ TPushParser::do_superscript()
     }
 }
 
+bool
+TPushParser::do_ignorablespace(const std::string& s)
+{
+  // At the moment, do nothing
+}
+
 bool
 TPushParser::do_space(const std::string&)
 {
-  return false;
+  TNode elem = doc.createS(nextId++);
+  cursor.replace(elem);
+  advance(elem);
+  return true;
 }
 
 bool
@@ -711,7 +720,7 @@ TPushParser::drop_prev_token(bool special)
   assert(cursor.prev());
   assert(cursor.parent());
   TNode prev = cursor.prev();
-  assert(prev.is("i") || prev.is("o") || prev.is("n"));
+  assert(prev.isT());
  
   DOM::UCS4String ucs4val = prev.element().getAttribute("val");
   bool macro = prev.element().hasAttribute("name");
@@ -731,7 +740,7 @@ TPushParser::drop_prev_token(bool special)
       frame.pos--;
     }
 
-  if ((ucs4val.length() > 1) && !special)
+  if ((ucs4val.length() > 1))
     {
       if (!macro)
         {
@@ -739,18 +748,23 @@ TPushParser::drop_prev_token(bool special)
          // to convert it in a utf8
          DOM::GdomeString gdsval(ucs4val);
          std::string utf8val(gdsval);
-         utf8val = utf8val.erase(utf8val.length() - 1, 1);
-         return std::string(utf8val);
+         switch (utf8val[utf8val.length() - 1])
+           {
+           case '-':
+           case '_':
+             return (special) ? std::string(utf8val, 0, utf8val.length() - 1) + "\\" : std::string(utf8val, 0, utf8val.length() - 1);
+           default: return (special) ? "" : std::string(utf8val, 0, utf8val.length() - 1);
+           }
        }
       else
         {
          // in this case, the content of val could be in unicode, 
-         // but we have attribute name, which doesn't contain character not representable 
+         // but we have the attribute name, which doesn't contain character not representable 
          // with a byte.
-         return "\\" + utf8name.erase(utf8name.length() - 1, 1);
+         return (special) ? "\\" + utf8name : "";
        }
     }
-  else if ((ucs4val.length() <= 1) && macro && special) return "\\" + utf8name.erase(utf8name.length() - 1, 1);
+  else if (macro && special) return "\\" + utf8name;
   else return "";
 }
 
@@ -770,7 +784,7 @@ TPushParser::drop_prev_script(bool special)
   if (cursor.prev().isG() && !prev.hasId())
     {
       // in this case, the user has inserted the a sequence of '.
-      // Hence, we force a normal deleting, because the behaviour must be the same 
+      // Hence, we force a normal deleting, because the behavior must be the same 
       // for the two kind of deleting
       return drop_prev(false);
     }
@@ -788,6 +802,8 @@ TPushParser::drop_prev_group(bool special)
 
   if (parent.isC() && prev.hasId())
     {
+      // this previous group is a macro's argument. Entering inside it means that
+      // this argument becomes incomplete. Hence, we have to decrement the member pos.
       assert(!frames.empty());
       frames.top().pos--;
     }
@@ -817,9 +833,8 @@ TPushParser::drop_prev_macro(bool special)
   
   if (!entry.defined())
     {
-      // We can assume that the user wants to completely delete the undefined macro, 
-      // but we can also handle this case as we handle tokens. At the moment, we delete the 
-      // whole macro
+      // In this case, with a normal deletion, we completely remove the macro.
+      // With a special deletion, we remove the last character of the macro's name.
       cursor.remove();
       prev.replace(cursor);
       if (cursor.parent().isC())
@@ -828,7 +843,7 @@ TPushParser::drop_prev_macro(bool special)
          assert(!frames.empty());
          frames.top().pos--;
        }
-      if (special) return "\\" + macro_name.erase(macro_name.length() - 1, 1);
+      if (special) return "\\" + macro_name.erase(macro_name.length() - 1, 1); // we remove the last char, because an undefined macro's name is visible
       return "";
     }
   else
@@ -842,7 +857,7 @@ TPushParser::drop_prev_macro(bool special)
       if (entry.rightOpen)
         {
          // In this fragment of code we also handle the leftOpen && rightOpen MACRO.
-         // if the control element is rightOpen, the cursor should be placed after 
+         // since the control element is rightOpen, the cursor should be placed after 
          // the last child of the control element's last child, and than, we try to remove something.
          // A frame MUST be pushed in the stack, because we dont' know if the following actions 
          // will completely remove the MACRO.
@@ -868,7 +883,8 @@ TPushParser::drop_prev_macro(bool special)
          // MACRO immediately, substituting it with the content of the phantom group.
          // We could remove the last child of the phantom group, but
          // it's not clear if it's the correct behavior of the graphical deleting.
-         // At the moment, to give a standard behaviour, we remove the last element.
+         // At the moment, to give a standard behavior, we remove the last element.
+         // With a special deletion, we do not remove it.
          assert(prev.first());
          assert(prev.first().isG());
          assert(prev.first() == prev.last());
@@ -881,7 +897,7 @@ TPushParser::drop_prev_macro(bool special)
              g.remove();
              prev.replace(g.first(), TNode());
              parent.append(cursor);
-             if (special) return "\\" + macro_name.erase(macro_name.length() - 1, 1);
+             if (special) return "\\" + macro_name;
              else return do_drop(special);
            }
          else
@@ -890,7 +906,7 @@ TPushParser::drop_prev_macro(bool special)
              cursor.remove();
              g.remove();
              prev.replace(cursor);
-             if (special) return "\\" + macro_name.erase(macro_name.length() - 1, 1);
+             if (special) return "\\" + macro_name;
              else
                {
                  // Once removed this empty macro, we could try to remove something else.
@@ -921,7 +937,7 @@ TPushParser::drop_prev_macro(bool special)
 
                  std::string last_del = entry.pattern[entry.pattern.size() - 1].value;
 
-                 return "\\" + last_del.erase(last_del.length() - 1, 1);
+                 return "\\" + last_del;
                }
              else
                {
@@ -937,7 +953,7 @@ TPushParser::drop_prev_macro(bool special)
                  // now, p is the correct value of pos, and we can push the frame.
                  frames.push(Frame(entry, p));
                  
-                 // To give a standard behaviour to the graphical deleting, we remove the last 
+                 // To give a standard behavior to the graphical deleting, we remove the last 
                  // element of the macro. Since we are in a phantom group, we can invoke the 
                  // do_drop_phantom_group(special).
                  return do_drop_phantom_group(special);
@@ -999,12 +1015,12 @@ TPushParser::drop_prev_macro(bool special)
              frames.top().pos--;
            }
 
-         if (special) return "\\" + macro_name.erase(macro_name.length() - 1, 1);
+         if (special) return "\\" + macro_name;
          else return "";
                  
-         // now we could start to remove something else. This behaviour would be justified by the 
+         // now we could start to remove something else. This behavior would be justified by the 
          // fact that, generally, an empty MACRO gives no visual information about it.
-         // To adopt this behaviour, just remove the comment to the following instruction
+         // To adopt this behavior, just remove the comment to the following instruction
          // return do_drop(special);
        }
     } // end of defined MACRO
@@ -1021,7 +1037,7 @@ TPushParser::drop_prev(bool special)
 
   TNode prev = cursor.prev();
 
-  if (prev.is("i") || prev.is("o") || prev.is("n"))
+  if (prev.isT())
     {
       return drop_prev_token(special);
     }
@@ -1120,15 +1136,6 @@ TPushParser::do_drop_script(bool special)
          // Since we don't know who is cursor's parent, and who is cursor's preceding 
          // element, we invoke the do_drop()
          return do_drop(special);
-         
-         /*
-          * * the following istructions have sense, only if we remove the preceding one.
-          * 
-         // if the new parent is a group with Id and the cursor is the only 
-         // element of this group, we have to remove the group. These controls are made
-         // in the method rgreplace_father().
-         if (cursor.parent().isG() && cursor.parent().hasId()) rgreplace_father();
-         */
        }
     }
   else
@@ -1142,7 +1149,7 @@ TPushParser::do_drop_script(bool special)
       if (special) return "";
       else
         {
-         // to give a standard behaviour, we try to remove the element, which was 
+         // to give a standard behavior, we try to remove the element, which was 
          // the script's base.
          return do_drop(special);
        }
@@ -1180,31 +1187,12 @@ TPushParser::do_drop_macro(bool special)
       parent.replace(cursor);
       frames.pop();
 
-      if (special) return "\\" + macro_name.erase(macro_name.length() - 1, 1);
+      if (special) return "\\" + macro_name;
       else
         {
-         // Since the macro hadn't no children and this is a graphical deleting, we try 
+         // Since the macro had no children and this is a graphical deleting, we try 
          // to remove something else
          return do_drop(special);
-
-          /*
-           * the following block of code has sense only if we remove the preceding instruction
-           * 
-           // if the new parent is a group with Id, and has no elements other than the 
-           // cursor, we can remove it, because it' a graphical deleting
-           if (cursor.parent() && cursor.parent().isG() && cursor.parent().hasId())
-            rgreplace_father();
-           else if (cursor.parent().isC())
-             {
-              // We have assumed that a MACRO cannot be a MACRO's child. 
-              // At the moment, this assumption is valid, but in a future 
-              // it might be false.
-              assert(!frames.empty());
-              Frame& frame = frames.top();
-              assert(frame.pos > 0);
-              frame.pos--;
-            }
-          */
        }
     }
   else
@@ -1228,7 +1216,7 @@ TPushParser::do_drop_macro(bool special)
              // two units: the delimiter and the actual argument
              std::string last_del = frame.entry.pattern[frame.pos - 1].value;
              frame.pos = frame.pos - 2;
-             return "\\" + last_del.erase(last_del.length() - 1, 1);
+             return "\\" + last_del;
            }
          else
            {
@@ -1331,7 +1319,7 @@ TPushParser::do_drop_phantom_group(bool special)
                    {
                      std::string del = frame.entry.pattern[frame.pos].value;
                      frame.pos--;
-                     return "\\" + del.erase(del.length() - 1, 1);
+                     return "\\" + del;
                    }
                }
              else
@@ -1437,10 +1425,10 @@ TPushParser::do_drop_phantom_group(bool special)
              // this MACRO no longer exists.
              frames.pop();
 
-             if (special) return "\\" + macro_name.erase(macro_name.length() - 1, 1);
+             if (special) return "\\" + macro_name;
              else
                {
-                 // to give a standard behaviour to the graphical deleting, we call the do_drop.
+                 // to give a standard behavior to the graphical deleting, we call the do_drop.
                  return do_drop(special);
                }
            }
@@ -1458,10 +1446,10 @@ TPushParser::do_drop_phantom_group(bool special)
              // now we have the situation preceding the rightOpen MACRO, so we have to pop the frame
              frames.pop();
 
-             if (special) return "\\" + macro_name.erase(macro_name.length() - 1, 1);
+             if (special) return "\\" + macro_name;
              else
                {
-                 // to give a standard behaviour to the graphical deleting, we call the do_drop.
+                 // to give a standard behavior to the graphical deleting, we call the do_drop.
                  return do_drop(special);
                }
              
@@ -1490,7 +1478,7 @@ TPushParser::do_drop_phantom_group(bool special)
                  gfather.replace(cursor);
                  frames.pop();
 
-                 if (special) return "\\" + macro_name.erase(macro_name.length() - 1, 1);
+                 if (special) return "\\" + macro_name;
                  else
                    {
                      // once we have replaced the empty macro with the cursor, we can remove
@@ -1514,7 +1502,7 @@ TPushParser::do_drop_phantom_group(bool special)
                          // argument.
                          std::string last_del = frame.entry.pattern[frame.pos - 1].value;
                          frame.pos = frame.pos - 2;
-                         return "\\" +  last_del.erase(last_del.length() - 1, 1)
+                         return "\\" +  last_del; 
                        }
                      else
                        {
@@ -1714,21 +1702,22 @@ TPushParser::process(const TToken& token)
 {
   switch (token.category)
     {
-    case TToken::BEGIN: return do_begin(); break;
-    case TToken::END: return do_end(); break;
-    case TToken::SHIFT: return do_shift(); break;
-    case TToken::ALIGN: return do_align(); break;
-    case TToken::EOL: return do_eol(); break;
-    case TToken::PARAMETER: return do_parameter(token.value); break;
-    case TToken::SUPERSCRIPT: return do_superscript(); break;
-    case TToken::SUBSCRIPT: return do_subscript(); break;
-    case TToken::SPACE: return do_space(token.value); break;
-    case TToken::LETTER: return do_letter(token.value); break;
-    case TToken::DIGIT: return do_digit(token.value); break;
-    case TToken::OTHER: return do_other(token.value); break;
-    case TToken::ACTIVE: return do_active(token.value); break;
-    case TToken::COMMENT: return do_comment(); break;
-    case TToken::CONTROL: return do_control(token.value); break;
+    case TToken::BEGIN: return do_begin();
+    case TToken::END: return do_end();
+    case TToken::SHIFT: return do_shift();
+    case TToken::ALIGN: return do_align();
+    case TToken::EOL: return do_eol();
+    case TToken::PARAMETER: return do_parameter(token.value);
+    case TToken::SUPERSCRIPT: return do_superscript();
+    case TToken::SUBSCRIPT: return do_subscript();
+    case TToken::IGNORABLE_SPACE: return do_ignorablespace(token.value);
+    case TToken::SPACE: return do_space(token.value);
+    case TToken::LETTER: return do_letter(token.value);
+    case TToken::DIGIT: return do_digit(token.value);
+    case TToken::OTHER: return do_other(token.value);
+    case TToken::ACTIVE: return do_active(token.value);
+    case TToken::COMMENT: return do_comment();
+    case TToken::CONTROL: return do_control(token.value);
     }
 }
 
@@ -1813,7 +1802,7 @@ TPushParser::push(const TToken& token)
          {
            // As by the TeX parsing rules of undelimited parameters,
            // empty spaces are ignored
-           if (token.category != TToken::SPACE) process(token);
+           if ((token.category != TToken::SPACE) && (token.category != TToken::IGNORABLE_SPACE)) process(token);
          }
        else if (frame.entry.pattern[frame.pos] == token)
          {