Send to your Kindle static public PageElement Merge(PageElement[] elements) { var target = elements.First(); Debug.Assert(target is PageElements.Notations.Ol); foreach (var elem in elements.Skip(1)) { Debug.Assert(elem is PageElements.Notations.Ol); target.Children.AddRange(elem.Children); elem.Children.Clear(); } { var children_ = new List<PageElement>(); var buf = new List<PageElement>(); PageElement currentLi = null; foreach (var child in target.Children) { Debug.Assert(child is PageElements.Affix || child is Li); if (child is PageElements.Affix) { children_.Add(child); } else if (child is Li && child.Children.Count > 0 && child.Children[0] is Ol) { buf.Add(child.Children[0]); } else { if (buf.Count > 0) { //TODO:children_最後のLi.ChildrenにAdd、Affix.Childrenではなく //children_.Add(Merge(buf.ToArray())); Debug.Assert(currentLi != null); currentLi.Children.Add(Merge(buf.ToArray())); buf.Clear(); } children_.Add(child); if (child is Li) currentLi = child; } } if (buf.Count > 0) { children_.Add(Merge(buf.ToArray())); buf.Clear(); } target.Children.Clear(); target.Children.AddRange(children_); children_.Clear(); } // foreach (var grandchild in li.Children) // { // if (grandchild is PageElements.Notations.Ol) // { // buf.Add(grandchild); // } // else if (buf.Count > 0) // { // grandchildren_.Add(Merge(buf.ToArray())); // buf.Clear(); // } // else // { // grandchildren_.Add(grandchild); // } // } // if (buf.Count > 0) // { // grandchildren_.AddRange(buf.ToArray()); // buf.Clear(); // } // li.Children.Clear(); // li.Children.AddRange(grandchildren_); // } //} //var grandchildren = new List<PageElement>(); //{ // foreach (var elem in elements) // { // foreach (var li in elem.Children) // { // grandchildren.AddRange(li.Children); // } // } //} //{ // var grandchildren_ = new List<PageElement>(); // var buf = new List<PageElement>(); // foreach (var grandchild in grandchildren) // { // if (grandchild is PageElements.Notations.Ol) // { // buf.Add(grandchild); // } // else if (buf.Count > 0) // { // grandchildren_.Add(Merge(buf.ToArray())); // //Merge(buf.ToArray()); // buf.Clear(); // } // else // { // grandchildren_.Add(grandchild); // } // } // grandchildren = grandchildren_; //} //{ // var target = elements.First(); // var li = target.Children.First(); // target.Children.Clear(); // target.Children.Add(li); // target.Children[0].Children.Clear(); // target.Children[0].Children.AddRange(grandchildren); //} //foreach (var elem in elements.Skip(1)) //{ // Debug.Assert(elem is PageElements.Notations.Ol); // target.Children.AddRange(elem.Children); // elem.Children.Clear(); //} //Debug.Assert(target.Children[1] is PageElements.Notations.Li); //target.Children[1].Children.Clear(); //target.Children[1].Children.AddRange(grandchildren); //{ // var grandchildren_ = new List<PageElement>(); // var buf = new List<PageElement>(); // foreach (var li in target.Children.Where(e => e is PageElements.Notations.Li)) // { // foreach (var c in li.Children) // { // if (c is PageElements.Notations.Ol) // { // buf.Add(c); // } // else if (buf.Count > 0) // { // grandchildren_.Add(Merge(buf.ToArray())); // buf.Clear(); // } // else // { // grandchildren_.Add(c); // } // } // li.Children.Clear(); // li.Children.AddRange(grandchildren_); // grandchildren_.Clear(); // } //} //{ // // 連結可能Elementを連結 // var buf = new List<PageElement>(); // //FIXME:remove general adding // elements.Add(new Affix(null, "")); // foreach (var elem in elements) // { // if (buf.Count >= 1 && buf.Last().GetType() != elem.GetType()) // { // // 既存Elementに連結 // //TODO:Merge可能かどうかはPlugin.Mergableを実装しているかで判定 // var merge = buf.First().GetType().GetMethod("Merge", BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy); // if (buf.Count >= 2 && merge != null) // { // merge.Invoke(null, new object[] { buf.ToArray() }); // } // else // buf.Clear(); // } // buf.Add(elem); // } // buf.Clear(); //} return target; } /// <summary> /// 連結 /// </summary> static public void Merge(PageElements.Notations.Ol self, PageElements.Notations.Ol target) { Debug.Assert(self.Children.Count > 0); var existsTargetChild = target.Children[target.Children.Count - 2] is PageElements.Notations.Li && target.Children[target.Children.Count - 2].Children.Count > 0 && target.Children[target.Children.Count - 2].Children[0] is PageElements.Notations.Ol; var existsSelfChild = self.Children[self.Children.Count - 2] is PageElements.Notations.Li && self.Children[self.Children.Count - 2].Children.Count > 0 && self.Children[self.Children.Count - 2].Children[0] is PageElements.Notations.Ol; ; if (existsTargetChild && existsSelfChild) { Debug.Assert(self.Children[self.Children.Count - 2].Children[0] is Ol && target.Children[target.Children.Count - 2].Children[0] is Ol); // どちらもまだ深い階層がある(レベル解析途中) PageElements.Notations.Ol.Merge((Ol)self.Children[self.Children.Count - 2].Children[0], (Ol)target.Children[target.Children.Count - 2].Children[0]); //Debug.Assert(self is PageElements.Notations.Ol && self.Children[1] is PageElements.Notations.Li && self.Children[1].Children[1] is PageElements.Notations.Ol); //var selfLi = (Li)self.Children[1]; //var selfOl2 = (Ol)selfLi.Children[1]; //var targetLi = (Li)target.Children[1]; //var targetOl2 = (Ol)targetLi.Children[1]; //PageElements.Notations.Ol.Merge(selfOl2, targetOl2); } else if (!existsTargetChild && existsSelfChild) { // レベルが深くなった target.Children[target.Children.Count - 2].Children.Add(self.Children[self.Children.Count - 2].Children[0]); } else { // レベルが浅くなったかどちらも最下層(レベル解析完了) Debug.Assert( existsTargetChild && !existsSelfChild || !existsTargetChild && !existsSelfChild ); target.Children.AddRange(self.Children); } } static public PageElement Merge(PageElement[] elements) { var target = elements.First(); Debug.Assert(target is PageElements.Notations.Ol); foreach (var elem in elements.Skip(1)) { Debug.Assert(elem is PageElements.Notations.Ol); target.Children.AddRange(elem.Children); elem.Children.Clear(); } { var children_ = new List<PageElement>(); var buf = new List<PageElement>(); PageElement currentLi = null; foreach (var child in target.Children) { Debug.Assert(child is PageElements.Affix || child is Li); if (child is PageElements.Affix) { children_.Add(child); } else if (child is Li && child.Children.Count > 0 && child.Children[0] is Ol) { buf.Add(child.Children[0]); } else { if (buf.Count > 0) { //TODO:children_最後のLi.ChildrenにAdd、Affix.Childrenではなく //children_.Add(Merge(buf.ToArray())); Debug.Assert(currentLi != null); currentLi.Children.Add(Merge(buf.ToArray())); buf.Clear(); } children_.Add(child); if (child is Li) currentLi = child; } } if (buf.Count > 0) { children_.Add(Merge(buf.ToArray())); buf.Clear(); } target.Children.Clear(); target.Children.AddRange(children_); children_.Clear(); } // foreach (var grandchild in li.Children) // { // if (grandchild is PageElements.Notations.Ol) // { // buf.Add(grandchild); // } // else if (buf.Count > 0) // { // grandchildren_.Add(Merge(buf.ToArray())); // buf.Clear(); // } // else // { // grandchildren_.Add(grandchild); // } // } // if (buf.Count > 0) // { // grandchildren_.AddRange(buf.ToArray()); // buf.Clear(); // } // li.Children.Clear(); // li.Children.AddRange(grandchildren_); // } //} //var grandchildren = new List<PageElement>(); //{ // foreach (var elem in elements) // { // foreach (var li in elem.Children) // { // grandchildren.AddRange(li.Children); // } // } //} //{ // var grandchildren_ = new List<PageElement>(); // var buf = new List<PageElement>(); // foreach (var grandchild in grandchildren) // { // if (grandchild is PageElements.Notations.Ol) // { // buf.Add(grandchild); // } // else if (buf.Count > 0) // { // grandchildren_.Add(Merge(buf.ToArray())); // //Merge(buf.ToArray()); // buf.Clear(); // } // else // { // grandchildren_.Add(grandchild); // } // } // grandchildren = grandchildren_; //} //{ // var target = elements.First(); // var li = target.Children.First(); // target.Children.Clear(); // target.Children.Add(li); // target.Children[0].Children.Clear(); // target.Children[0].Children.AddRange(grandchildren); //} //foreach (var elem in elements.Skip(1)) //{ // Debug.Assert(elem is PageElements.Notations.Ol); // target.Children.AddRange(elem.Children); // elem.Children.Clear(); //} //Debug.Assert(target.Children[1] is PageElements.Notations.Li); //target.Children[1].Children.Clear(); //target.Children[1].Children.AddRange(grandchildren); //{ // var grandchildren_ = new List<PageElement>(); // var buf = new List<PageElement>(); // foreach (var li in target.Children.Where(e => e is PageElements.Notations.Li)) // { // foreach (var c in li.Children) // { // if (c is PageElements.Notations.Ol) // { // buf.Add(c); // } // else if (buf.Count > 0) // { // grandchildren_.Add(Merge(buf.ToArray())); // buf.Clear(); // } // else // { // grandchildren_.Add(c); // } // } // li.Children.Clear(); // li.Children.AddRange(grandchildren_); // grandchildren_.Clear(); // } //} //{ // // 連結可能Elementを連結 // var buf = new List<PageElement>(); // //FIXME:remove general adding // elements.Add(new Affix(null, "")); // foreach (var elem in elements) // { // if (buf.Count >= 1 && buf.Last().GetType() != elem.GetType()) // { // // 既存Elementに連結 // //TODO:Merge可能かどうかはPlugin.Mergableを実装しているかで判定 // var merge = buf.First().GetType().GetMethod("Merge", BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy); // if (buf.Count >= 2 && merge != null) // { // merge.Invoke(null, new object[] { buf.ToArray() }); // } // else // buf.Clear(); // } // buf.Add(elem); // } // buf.Clear(); //} return target; } /// <summary> /// 連結 /// </summary> static public void Merge(PageElements.Notations.Ol self, PageElements.Notations.Ol target) { Debug.Assert(self.Children.Count > 0); var existsTargetChild = target.Children[target.Children.Count - 2] is PageElements.Notations.Li && target.Children[target.Children.Count - 2].Children.Count > 0 && target.Children[target.Children.Count - 2].Children[0] is PageElements.Notations.Ol; var existsSelfChild = self.Children[self.Children.Count - 2] is PageElements.Notations.Li && self.Children[self.Children.Count - 2].Children.Count > 0 && self.Children[self.Children.Count - 2].Children[0] is PageElements.Notations.Ol; ; if (existsTargetChild && existsSelfChild) { Debug.Assert(self.Children[self.Children.Count - 2].Children[0] is Ol && target.Children[target.Children.Count - 2].Children[0] is Ol); // どちらもまだ深い階層がある(レベル解析途中) PageElements.Notations.Ol.Merge((Ol)self.Children[self.Children.Count - 2].Children[0], (Ol)target.Children[target.Children.Count - 2].Children[0]); //Debug.Assert(self is PageElements.Notations.Ol && self.Children[1] is PageElements.Notations.Li && self.Children[1].Children[1] is PageElements.Notations.Ol); //var selfLi = (Li)self.Children[1]; //var selfOl2 = (Ol)selfLi.Children[1]; //var targetLi = (Li)target.Children[1]; //var targetOl2 = (Ol)targetLi.Children[1]; //PageElements.Notations.Ol.Merge(selfOl2, targetOl2); } else if (!existsTargetChild && existsSelfChild) { // レベルが深くなった target.Children[target.Children.Count - 2].Children.Add(self.Children[self.Children.Count - 2].Children[0]); } else { // レベルが浅くなったかどちらも最下層(レベル解析完了) Debug.Assert( existsTargetChild && !existsSelfChild || !existsTargetChild && !existsSelfChild ); target.Children.AddRange(self.Children); } }