Beispiel #1
0
        public static List <TikzParseItem> GetFullSelection(IEnumerable <TikzParseItem> ItemList)
        {
            List <TikzParseItem> ret = new List <TikzParseItem>();

            if (ItemList == null || ItemList.Count() == 0)
            {
                return(ret);
            }

            //  ** Find the least common ancestor **
            // find all ancestors for each Item
            var AncestorList = ItemList.Select(l => FindAncestors(l)).ToList();

            // as long as the highest ancestor is common, remove this ancestor from the lists
            while (AncestorList.AllEqual(l => l.Last()) && AncestorList.All(l => l.Count >= 2))
            {
                foreach (var l in AncestorList)
                {
                    l.RemoveAt(l.Count - 1);
                }
            }

            // Now the last elements of all lists are ancestors on one "level" of the tree.
            // Remove duplicates and sort
            var elements = AncestorList.Select(l => l.Last())
                           .Distinct()
                           .OrderBy(tpi => tpi.StartPosition())
                           .ToList();


            // Handle a special case: if the items are all coordinates in a single Tikz_Path,
            // that (other than those items) contains only Tikz_Somethings, then return the whole path
            TikzContainerParseItem commonparent = elements.First().parent;

            if (commonparent is Tikz_Path)
            {
                if (commonparent.Children.All(tpi => (tpi is Tikz_Something) || elements.Contains(tpi)))
                {
                    ret.Add(commonparent);
                    return(ret);
                }
            }

            // otherwise just return the elements found so far
            return(elements);
        }
Beispiel #2
0
        /// <summary>
        /// Recursive function to scan the parsetree in a depth first manner.
        /// nodelist contains the current map from _old_ nodenames to nodes. it is used to update node references
        /// </summary>
        private static void ScanTree(TikzContainerParseItem tc, Dictionary <string, Tikz_Node> nodelist, Tikz_Picture tp)
        {
            foreach (var tpi in tc.Children)
            {
                if (tpi is Tikz_Node)
                {
                    Tikz_Node tn = tpi as Tikz_Node;
                    if (tn.name != null && tn.name.Trim() != "")
                    {
                        string name = CleanName(tn.name.Trim());
                        // remember the node with its old name (all coordinates referring to this name henceforth will be changed to the new name
                        nodelist[name] = tn;

                        if (tp.nodelist.ContainsKey(name))
                        {
                            // we have to change the name
                            tn.name = UniquefyName(name, tp);
                            tn.UpdateText();
                        }
                        tn.RegisterNodeAndStyleRefs();
                    }
                }
                else if (tpi is Tikz_Coord)
                {
                    Tikz_Coord tco = tpi as Tikz_Coord;
                    if (tco.type == Tikz_CoordType.Named)
                    {
                        string nameref = CleanName(tco.nameref);
                        if (nodelist.ContainsKey(nameref))
                        {
                            if (CleanName(nodelist[nameref].name) != nameref)
                            {
                                tco.nameref = CleanName(nodelist[nameref].name);
                                tco.UpdateText();
                            }
                        }
                    }
                }
                else if (tpi is TikzContainerParseItem)
                {
                    ScanTree(tpi as TikzContainerParseItem, nodelist, tp);
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// The method returns a list of TikzParseItems that together form the "code block" of the argument.
        /// </summary>
        /// <param name="?"></param>
        /// <returns></returns>
        public static List <TikzParseItem> GetCodeBlock(IEnumerable <TikzParseItem> ItemList)
        {
            List <TikzParseItem> ret = new List <TikzParseItem>();

            if (ItemList == null || ItemList.Count() == 0)
            {
                return(ret);
            }

            // find all ancestors for each Item
            var AncestorList = ItemList.Select(l => FindAncestors(l)).ToList();

            // as long as the highest ancestor is common, remove this ancestor from the lists
            while (AncestorList.AllEqual(l => l.Last()) && AncestorList.All(l => l.Count >= 2))
            {
                foreach (var l in AncestorList)
                {
                    l.RemoveAt(l.Count - 1);
                }
            }

            // Now the last elements of all lists are ancestors on one "level" of the tree. Find the smallest and largest in the horizontal ordering
            var elements = AncestorList.Select(l => l.Last());
            TikzContainerParseItem commonparent = elements.First().parent;

            int firstind = elements.Min(t => commonparent.Children.IndexOf(t));
            int lastind  = elements.Max(t => commonparent.Children.IndexOf(t));

            // Handle a special case: if the items are all coordinates in a single Tikz_Path,
            // that (other than those items) contains only Tikz_Somethings, then return the whole path
            if (commonparent is Tikz_Path)
            {
                if (commonparent.Children.FindIndex(tpi => !(tpi is Tikz_Something)) >= firstind &&
                    commonparent.Children.FindLastIndex(tpi => !(tpi is Tikz_Something)) <= lastind)
                {
                    ret.Add(commonparent);
                    return(ret);
                }
            }

            return(commonparent.Children.GetRange(firstind, lastind - firstind + 1).ToList());
        }
Beispiel #4
0
        //create a new CurAddTo (even though their already might be one)
        //(needed for edge tool)
        protected virtual bool AddNewCurAddTo()
        {
            // find tikzpicture
            Tikz_Picture tpict = overlay.ParseTree.GetTikzPicture();

            if (tpict == null)
            {
                return(false);
            }


            Parser.Tikz_Path tp = new Parser.Tikz_Path();
            tp.starttag = @"\draw ";
            tp.endtag   = ";";
            if (overlay.EdgeStyle != "")
            {
                Parser.Tikz_Options topt = new Parser.Tikz_Options();
                topt.starttag = "[";
                topt.endtag   = "]";
                Parser.Tikz_Option to = new Parser.Tikz_Option();
                to.type = Parser.Tikz_OptionType.key;
                to.key  = overlay.EdgeStyle;

                topt.AddOption(to);
                tp.AddChild(topt);
                tp.options = topt;
            }
            if (overlay.CurEditing != null)
            {
                overlay.CurEditing.tikzitem.AddChild(tp);
                overlay.CurEditing.tikzitem.AddChild(new Parser.Tikz_Something("\r\n"));
            }
            else
            {
                tpict.AddChild(tp);
                tpict.AddChild(new Parser.Tikz_Something("\r\n"));
            }
            curAddTo = tp;

            return(true);
        }
Beispiel #5
0
        bool FillNodesOnArc()
        {
            TikzContainerParseItem pa = curDragged.item.parent;

            if (!(curDragged.item is Tikz_XYItem))
            {
                return(false);
            }
            Tikz_XYItem cur = curDragged.item as Tikz_XYItem;

            nodesOnArc.Clear();
            nodesOnArc.Add(cur);
            // find all arcs to the right
            for (int i = pa.Children.IndexOf(cur) + 1; i < pa.Children.Count; i++)
            {
                if (pa.Children[i] is Tikz_Arc)
                {
                    nodesOnArc.Add(pa.Children[i] as Tikz_Arc);
                }
                else if (pa.Children[i].ChangesCurPoint())
                {
                    break;
                }
            }

            // find all arcs to left, including startpoint
            if (cur is Tikz_Arc)
            {
                for (int i = pa.Children.IndexOf(cur) - 1; i >= 0; i--)
                {
                    if (pa.Children[i] is Tikz_Arc)
                    {
                        nodesOnArc.Insert(0, pa.Children[i] as Tikz_Arc);
                    }
                    else if (pa.Children[i].ChangesCurPoint())
                    {
                        if (pa.Children[i] is Tikz_XYItem)
                        {
                            nodesOnArc.Insert(0, pa.Children[i] as Tikz_XYItem);
                        }
                        break;
                    }
                }
            }

            // todo: no startpoint present...
            if (nodesOnArc.First() is Tikz_Arc)
            {
            }

            // compute radius and center
            // in absolute tikz coordinates
            Point    center, p;
            double   R;
            Tikz_Arc ta;

            if (cur is Tikz_Arc)
            {
                ta = cur as Tikz_Arc;
            }
            else if (nodesOnArc.Count > 1 && nodesOnArc[1] is Tikz_Arc)
            {
                ta = nodesOnArc[1] as Tikz_Arc;
            }
            else
            {
                return(false);
            }

            if (!ta.GetArcCenterAbs(out center) || !ta.GetAbsPos(out p))
            {
                throw new Exception("ArcEditTool: Invalid coordinate discovered.");
            }

            R = (p - center).Length;

            // throw out all items with non-fitting parameters
            for (int i = nodesOnArc.Count - 1; i >= 0; i--)
            {
                if (nodesOnArc[i] is Tikz_Arc)
                {
                    Point  cc, pp;
                    double RR;
                    if (!(nodesOnArc[i] as Tikz_Arc).GetArcCenterAbs(out cc) || !nodesOnArc[i].GetAbsPos(out pp))
                    {
                        throw new Exception("ArcEditTool: Invalid coordinate discovered.");
                    }
                    RR = (cc - pp).Length;
                    if ((cc - center).Length > 1e-3 || Math.Abs(RR - R) > 1e-3)
                    {
                        nodesOnArc.RemoveAt(i);
                    }
                }
                else  // other Tikz_XYItem, namely startpoint
                {
                    Point pp;
                    if (!nodesOnArc[i].GetAbsPos(out pp))
                    {
                        throw new Exception("ArcEditTool: Invalid coordinate discovered.");
                    }
                    // check if pooint lies on circle
                    if (Math.Abs(R - (pp - center).Length) > 1e-3)
                    {
                        nodesOnArc.RemoveAt(i);
                    }
                }
            }
            curDraggedInd     = nodesOnArc.IndexOf(cur);
            PreviewArc.Center = overlay.TikzToScreen(center, true);
            center_tikz       = center;

            // Fill the PreviewArcs Spokes array
            List <double> spokes = new List <double>();

            for (int i = 0; i < nodesOnArc.Count; i++)
            {
                if (nodesOnArc[i] is Tikz_Arc)
                {
                    Tikz_Arc tia = nodesOnArc[i] as Tikz_Arc;
                    double   a1 = tia.phi1.GetInCM() * Math.PI / 180, a2 = tia.phi2.GetInCM() * Math.PI / 180;

                    //if (!(spokes.Count > 0 && spokes.Last() == a1))
                    //    spokes.Add(a1);
                    spokes.Add(a2);

                    //Point pp;
                    //if (!nodesOnArc[i].GetAbsPos(out pp))
                    //    throw new Exception("ArcEditTool: Invalid coordinate discovered.");
                    //Vector v = pp - center;
                }
                else
                {
                    // should go here at most for the first item in list
                    double a1 = (nodesOnArc[1] as Tikz_Arc).phi1.GetInCM() * Math.PI / 180;
                    spokes.Add(a1);
                }
            }
            PreviewArc.Spokes = spokes;

            return(true);
        }
Beispiel #6
0
        /// <summary>
        /// Performs some action on the currently selected items.
        ///
        /// If necessary, raises the ReplaceText event (via calling RaiseRelaceText) to request text changes.
        /// This is necessary since the Parsetree currently does not support deletions.
        /// Ideally, we would directly do the changes to the Parsetree instead of firing the ReplaceText event.
        /// </summary>
        public void PerformCodeBlockOperation(CodeBlockAction action)
        {
            // The operations are only valid when the select tool is active
            if (View.Tool != OverlayToolType.move)
            {
                return;
            }

            List <TikzParseItem> FullSelection = TikzParseTreeHelper.GetFullSelection(selectionTool.SelItems.Select(ols => ols.item));

            if (!FullSelection.Any())
            {
                return;
            }

            // get codeblock text
            string cbtext = "", cbtextE = "";

            foreach (var tpi in FullSelection)
            {
                cbtext += tpi.ToString() + Environment.NewLine;
            }

            // if the selected items are within a path, enscope by adding { }. If they are within another scope or the tikzpicture, enscope by \begin{scope} \end{scope}
            TikzContainerParseItem tc = FullSelection.First().parent;

            if (tc is Tikz_Picture || tc is Tikz_Scope)
            {
                cbtextE = "\\begin{scope}[]" + Environment.NewLine + cbtext + Environment.NewLine + "\\end{scope}" + Environment.NewLine;
            }
            else
            {
                cbtextE = " { " + cbtext + " } ";
            }


            var ReplacementList = new List <ReplaceTextEventArgs.ReplaceData>();

            if (action == CodeBlockAction.Copy)
            {
                Clipboard.SetText(cbtext);
            }
            else if (action == CodeBlockAction.CopyEnscoped)
            {
                Clipboard.SetText(cbtextE);
            }
            else if (action == CodeBlockAction.Delete || action == CodeBlockAction.Cut || action == CodeBlockAction.CutEnscoped)
            {
                foreach (var tpi in FullSelection)
                {
                    ReplacementList.Insert(0, new ReplaceTextEventArgs.ReplaceData()
                    {
                        StartPosition = tpi.StartPosition(), Length = tpi.Length, ReplacementText = ""
                    });
                }

                if (action == CodeBlockAction.Cut)
                {
                    Clipboard.SetText(cbtext);
                }
                else if (action == CodeBlockAction.CutEnscoped)
                {
                    Clipboard.SetText(cbtextE);
                }

                View.RaiseReplaceText(new ReplaceTextEventArgs()
                {
                    Replacements = ReplacementList
                });
            }
            else if (action == CodeBlockAction.Collect || action == CodeBlockAction.CollectEnscoped)
            {
                // Text to delete ... mind the order
                foreach (var tpi in FullSelection)
                {
                    ReplacementList.Insert(0, new ReplaceTextEventArgs.ReplaceData()
                    {
                        StartPosition = tpi.StartPosition(), Length = tpi.Length, ReplacementText = ""
                    });
                }

                // text to insert (text of selected nodes, gathered together, optionally enscoped
                if (action == CodeBlockAction.Collect)
                {
                    ReplacementList.Add(new ReplaceTextEventArgs.ReplaceData()
                    {
                        StartPosition   = FullSelection.First().StartPosition(),
                        Length          = 0,
                        ReplacementText = cbtext
                    });
                }
                else
                {
                    ReplacementList.Add(new ReplaceTextEventArgs.ReplaceData()
                    {
                        StartPosition   = FullSelection.First().StartPosition(),
                        Length          = 0,
                        ReplacementText = cbtextE
                    });
                }

                View.RaiseReplaceText(new ReplaceTextEventArgs()
                {
                    Replacements = ReplacementList
                });
            }
        }
Beispiel #7
0
        static bool FillItem(TikzContainerParseItem item, CommonTree t, CommonTokenStream tokens)
        {
            int curToken = t.TokenStartIndex;

            if (item is Tikz_ParseTree)
            {
                curToken = 0;   // for root, start at the beginning
            }
            if (t.Children == null)
            {
                return(false);
            }

            foreach (CommonTree childt in t.Children)
            {
                addSomething(item, tokens, curToken, childt.TokenStartIndex - 1);

                switch (childt.Type)
                {
                case simpletikzParser.IM_PICTURE:
                    Tikz_Picture tp = new Tikz_Picture();
                    FillItem(tp, childt, tokens);
                    item.AddChild(tp);
                    break;

                case simpletikzParser.IM_STARTTAG:
                    item.starttag = getTokensString(tokens, childt.TokenStartIndex, childt.TokenStopIndex);
                    break;

                case simpletikzParser.IM_ENDTAG:
                    item.endtag = getTokensString(tokens, childt.TokenStartIndex, childt.TokenStopIndex);
                    break;

                case simpletikzParser.IM_PATH:
                    Tikz_Path tpath = new Tikz_Path();
                    FillItem(tpath, childt, tokens);
                    item.AddChild(tpath);
                    break;

                case simpletikzParser.IM_SCOPE:
                    Tikz_Scope tscope = new Tikz_Scope();
                    FillItem(tscope, childt, tokens);
                    item.AddChild(tscope);
                    break;

                case simpletikzParser.IM_COORD:
                    Tikz_Coord tc = Tikz_Coord.FromCommonTree(childt, tokens);
                    tc.text = getTokensString(tokens, childt);
                    item.AddChild(tc);
                    break;

                case simpletikzParser.IM_ARC:
                    Tikz_Arc ta = Tikz_Arc.FromCommonTree(childt, tokens);
                    ta.text = getTokensString(tokens, childt);
                    item.AddChild(ta);
                    break;

                case simpletikzParser.IM_NODE:
                    Tikz_Node tn = Tikz_Node.FromCommonTree(childt, tokens);
                    tn.text = getTokensString(tokens, childt);
                    item.AddChild(tn);
                    break;

                case simpletikzParser.IM_OPTION_KV:
                case simpletikzParser.IM_OPTION_STYLE:
                    Tikz_Option topt = Tikz_Option.FromCommonTree(childt, tokens);
                    if (topt == null)
                    {
                        break;
                    }
                    //topt.text = getTokensString(tokens, childt);
                    String s = getTokensString(tokens, childt);
                    topt.text = s;
                    item.AddChild(topt);
                    break;

                case simpletikzParser.IM_OPTIONS:
                    //Tikz_Options to = Tikz_Options.FromCommonTree(childt);
                    Tikz_Options to = new Tikz_Options();
                    FillItem(to, childt, tokens);
                    item.AddChild(to);
                    //to.text = getTokensString(tokens, childt);
                    //item.AddChild(tn);
                    if (item.options == null)
                    {
                        // determine whether option belongs to the item (e.g. \draw [this belongs to draw] blabla [thisnot])
                        // i.e., the scope of the options is the whole item's body
                        // this is hacky
                        if (item.Children.Count == 1 ||
                            (item.Children.Count == 2 && (item.Children[0] is Tikz_Something) &&
                             item.Children[0].ToString().Trim() == ""))
                        {
                            item.options = to;
                        }
                    }
                    break;

                case simpletikzParser.IM_TIKZSET:
                    Tikz_Options to2 = new Tikz_Options();
                    FillItem(to2, childt, tokens);
                    item.AddChild(to2);
                    break;

                case simpletikzParser.IM_STYLE:
                    Tikz_Option topt2 = Tikz_Option.FromCommonTree(childt, tokens);
                    //FillItem(to2, childt, tokens);
                    topt2.text = getTokensString(tokens, childt);
                    item.AddChild(topt2);
                    break;

                case simpletikzParser.IM_CONTROLS:
                    Tikz_Controls tcontrols = new Tikz_Controls();
                    FillItem(tcontrols, childt, tokens);
                    item.AddChild(tcontrols);
                    break;

                case simpletikzParser.IM_SIZE:
                    Tikz_Size tsize = Tikz_Size.FromCommonTree(childt, tokens);
                    tsize.text = getTokensString(tokens, childt);
                    item.AddChild(tsize);
                    //Tikz_Size tsize = new Tikz_Size();
                    //item.AddChild(tsize);
                    break;

                //case simpletikzParser.ID:
                //case simpletikzParser.IM_STRING:
                //case simpletikzParser.COMMAND:
                //case simpletikzParser.T__57:
                //    break;
                case simpletikzParser.IM_TIKZEDT_CMD:
                    Tikz_EdtCommand cmd = new Tikz_EdtCommand(getTokensString(tokens, childt));
                    item.AddChild(cmd);
                    break;

                case simpletikzParser.IM_DONTCARE:
                    Tikz_Something st = new Tikz_Something(getTokensString(tokens, childt));
                    item.AddChild(st);
                    break;

                default:
                    // getting here is an error
                    throw new Exception(" childt.Type not handled! " + childt.Type.ToString() + " (\"" + getTokensString(tokens, childt) + "\")");
                    //break;
                }

                curToken = childt.TokenStopIndex + 1;
            }

            if (t.TokenStartIndex >= 0)   // rule out empty code
            {
                addSomething(item, tokens, curToken, t.TokenStopIndex);
            }

            return(true);
        }
Beispiel #8
0
 public override void OnDeactivate()
 {
     base.OnDeactivate();
     curAddTo = null;
 }