Beispiel #1
0
        private static int InsertText(TextBuffer buffer, int offset, string data, Stack stack)
        {
            TagStart tagStart = (TagStart)stack.Peek();
            TextIter insertAt = buffer.GetIterAtOffset(offset);
            TextTag  textTag  = DocumentUtils.GetAssociatedTextTag(buffer, tagStart.Tag);

            DocumentUtils.AddText(buffer, ref insertAt, data, textTag);
//		buffer.InsertWithTags (ref insertAt, data, textTag);

                #if DEBUG
            Console.WriteLine("Text: {0} Value: {1} Start: {2}", textTag.Name, data, offset);
                #endif

            return(insertAt.Offset);
        }
Beispiel #2
0
        /// <summary>
        /// Redefine the standard Liquid {% if %} tag to allow "{% elsif %}" or "{% elseif %}".
        /// </summary>
        private void RegisterLavaElseIfTag()
        {
            var ifTag = LogicalExpression
                        .AndSkip(TagEnd)
                        .And(_anyTagsListParser)
                        .And(ZeroOrMany(
                                 TagStart.SkipAnd(Terms.Text("elsif").Or(Terms.Text("elseif"))).SkipAnd(LogicalExpression).AndSkip(TagEnd).And(_anyTagsListParser))
                             .Then(x => x.Select(e => new ElseIfStatement(e.Item1, e.Item2)).ToList()))
                        .And(ZeroOrOne(
                                 CreateTag("else").SkipAnd(_anyTagsListParser))
                             .Then(x => x != null ? new ElseStatement(x) : null))
                        .AndSkip(CreateTag("endif").ElseError($"'{{% endif %}}' was expected"))
                        .Then <Statement>(x => new IfStatement(x.Item1, x.Item2, x.Item4, x.Item3))
                        .ElseError("Invalid 'if' tag");

            RegisteredTags["if"] = ifTag;
        }
Beispiel #3
0
        private static int InsertEndElement(TextBuffer buffer, int offset, Stack stack, ref int depth)
        {
            TextIter insertAt, applyStart, applyEnd;
            TagStart tagStart = (TagStart)stack.Pop();
            string   suffix   = '#' + depth.ToString();

                #if DEBUG
            Console.WriteLine("Element: {0}, End: {1}", tagStart.Tag.Name, offset);
                #endif

            if (((DocumentTag)tagStart.Tag).IsEditable)
            {
                if (tagStart.Start + 1 == offset)
                {
                    offset = DocumentUtils.AddStub(buffer, offset, "To be added test", suffix);
                }

                insertAt = buffer.GetIterAtOffset(offset);
                buffer.Insert(ref insertAt, "]");
                offset += 1;
            }
            else if (tagStart.Start == offset)
            {
                offset = DocumentUtils.AddPaddingEmpty(buffer, offset, suffix);
            }

            applyStart = buffer.GetIterAtOffset(tagStart.Start);
            applyEnd   = buffer.GetIterAtOffset(offset);
            buffer.ApplyTag(tagStart.Tag, applyStart, applyEnd);
            offset = FormatEnd(buffer, offset, suffix, tagStart.Name);
            depth--;

                #if DEBUG
            Console.WriteLine("Applied: {0}, Start: {1}, End: {2}", tagStart.Tag.Name, tagStart.Start, offset);
                #endif

            // Padding between tag regions
            suffix = "#" + depth;
            offset = DocumentUtils.AddPadding(buffer, offset, suffix);

            return(offset);
        }
Beispiel #4
0
		public static void Deserialize (Gtk.TextBuffer buffer,
		                                Gtk.TextIter   start,
		                                XmlTextReader  xml)
		{
			int offset = start.Offset;
			Stack<TagStart> stack = new Stack<TagStart> ();
			TagStart tag_start;

			NoteTagTable note_table = buffer.TagTable as NoteTagTable;

			int curr_depth = -1;

			// A stack of boolean values which mark if a
			// list-item contains content other than another list
			Stack<bool> list_stack = new Stack<bool> ();

			while (xml.Read ()) {
				switch (xml.NodeType) {
				case XmlNodeType.Element:
					if (xml.Name == "note-content")
						break;

					tag_start = new TagStart ();
					tag_start.Start = offset;

					if (note_table != null &&
					                note_table.IsDynamicTagRegistered (xml.Name)) {
						tag_start.Tag =
						        note_table.CreateDynamicTag (xml.Name);
					} else if (xml.Name == "list") {
						curr_depth++;
						break;
					} else if (xml.Name == "list-item") {
						if (curr_depth >= 0) {
							if (xml.GetAttribute ("dir") == "rtl") {
								tag_start.Tag =
								        note_table.GetDepthTag (curr_depth, Pango.Direction.Rtl);
							} else {
								tag_start.Tag =
								        note_table.GetDepthTag (curr_depth, Pango.Direction.Ltr);
							}
							list_stack.Push (false);
						} else {
							Logger.Error("</list> tag mismatch");
						}
					} else {
						tag_start.Tag = buffer.TagTable.Lookup (xml.Name);
					}

					if (tag_start.Tag is NoteTag) {
						((NoteTag) tag_start.Tag).Read (xml, true);
					}

					stack.Push (tag_start);
					break;
				case XmlNodeType.Text:
				case XmlNodeType.Whitespace:
				case XmlNodeType.SignificantWhitespace:
					Gtk.TextIter insert_at = buffer.GetIterAtOffset (offset);
					buffer.Insert (ref insert_at, xml.Value);

					offset += xml.Value.Length;

					// If we are inside a <list-item> mark off
					// that we have encountered some content
					if (list_stack.Count > 0) {
						list_stack.Pop ();
						list_stack.Push (true);
					}

					break;
				case XmlNodeType.EndElement:
					if (xml.Name == "note-content")
						break;

					if (xml.Name == "list") {
						curr_depth--;
						break;
					}

					tag_start = stack.Pop ();
					if (tag_start.Tag == null)
						break;

					Gtk.TextIter apply_start, apply_end;
					apply_start = buffer.GetIterAtOffset (tag_start.Start);
					apply_end = buffer.GetIterAtOffset (offset);

					if (tag_start.Tag is NoteTag) {
						((NoteTag) tag_start.Tag).Read (xml, false);
					}

					// Insert a bullet if we have reached a closing
					// <list-item> tag, but only if the <list-item>
					// had content.
					DepthNoteTag depth_tag = tag_start.Tag as DepthNoteTag;

					if (depth_tag != null && list_stack.Pop ()) {
						((NoteBuffer) buffer).InsertBullet (ref apply_start,
						                                    depth_tag.Depth,
						                                    depth_tag.Direction);
						buffer.RemoveAllTags (apply_start, apply_start);
						offset += 2;
					} else if (depth_tag == null) {
						buffer.ApplyTag (tag_start.Tag, apply_start, apply_end);
					}

					break;
				default:
					Logger.Warn ("Unhandled element {0}. Value: '{1}'",
					            xml.NodeType,
					            xml.Value);
					break;
				}
			}
		}
        public static void Deserialize (Gtk.TextBuffer buffer, Gtk.TextIter start, string content)
        {
            StringReader reader = new StringReader(content);
            int intCharacter;
            char convertedCharacter;
            int offset = start.Offset;
            string sbuffer = String.Empty;
            Stack<TagStart> stack = new Stack<TagStart> ();
            TagStart tag_start;

            while (true) {
                intCharacter = reader.Read ();

                if (intCharacter == -1) break;

                convertedCharacter = Convert.ToChar (intCharacter);

                if (sbuffer != String.Empty || convertedCharacter == '<') {
                    sbuffer += convertedCharacter;
                    if (sbuffer == "<bold>") {
                        tag_start = new TagStart ();
                        tag_start.Start = offset;
                        tag_start.Tag = buffer.TagTable.Lookup ("bold");
                        stack.Push (tag_start);
                        sbuffer = String.Empty;
                    } else if (sbuffer == "<italic>") {
                        tag_start = new TagStart ();
                        tag_start.Start = offset;
                        tag_start.Tag = buffer.TagTable.Lookup ("italic");
                        stack.Push (tag_start);
                        sbuffer = String.Empty;
                    } else if (sbuffer == "</bold>" || sbuffer == "</italic>") {
                        if (stack.Count > 0) {
                            tag_start = stack.Pop ();
                            Gtk.TextIter apply_start, apply_end;
                            apply_start = buffer.GetIterAtOffset (tag_start.Start);
                            apply_end = buffer.GetIterAtOffset (offset);
                            buffer.ApplyTag (tag_start.Tag, apply_start, apply_end);
                            sbuffer = String.Empty;
                        }
                    } else if (sbuffer.Length > 9) {
                        Gtk.TextIter insert_at = buffer.GetIterAtOffset(offset);
                        buffer.Insert (ref insert_at, sbuffer);
                        offset += sbuffer.Length;
                        sbuffer = String.Empty;
                    }
                } else {
                    Gtk.TextIter insert_at = buffer.GetIterAtOffset(offset);
                    buffer.Insert (ref insert_at, convertedCharacter.ToString ());
                    offset += 1;
                }
            }
        }
Beispiel #6
0
        private static int InsertStartElement(TextBuffer buffer, int offset, XmlTextReader xmlReader, Stack stack, ref int depth, ref int count)
        {
            string           elementName = xmlReader.Name;
            string           suffix = String.Empty;
            DocumentTagTable tagTable = (DocumentTagTable)buffer.TagTable;
            bool             emptyElement = xmlReader.IsEmptyElement;
            bool             isDynamic = DocumentTagTable.IsDynamic(elementName);
            TextIter         insertAt, applyStart, applyEnd;

            depth++;

            // We define a suffix so each dynamic tag has an unique name.
            // Suffix has format: #{depth level}
            if (isDynamic)
            {
                suffix = "#" + depth;
            }

            // We add any needed string to give format to the document.
            offset = FormatStart(buffer, offset, suffix, elementName);

            TagStart tagStart = new TagStart();

            tagStart.Start = offset;
            tagStart.Name  = elementName;

            // We first lookup the tag name, if the element is dynamic, we can
            // have three scenarios.
            // 1) The tag is not in the table: So we create it in the spot.
            // 2) Tag is in table but it priority is wrong: We created a new
            // dynamic tag with an extra suffix. Format #{depth level}.{count}
            // 3) Tag is in table with right priority: We reuse it and we don't
            // create a new dymamic tag.
            tagStart.Tag = tagTable.Lookup(elementName + suffix);
            if (isDynamic && tagStart.Tag == null)
            {
                tagStart.Tag = tagTable.CreateDynamicTag(elementName + suffix);
            }
            else if (isDynamic && tagStart.Tag != null && tagStart.Tag.Priority < ((TagStart)stack.Peek()).Tag.Priority)
            {
                suffix      += "." + count;
                tagStart.Tag = tagTable.CreateDynamicTag(elementName + suffix);
                count++;
            }

                #if DEBUG
            try {
                Console.WriteLine("Element: {0} Start: {1}", tagStart.Tag.Name, tagStart.Start);
            } catch (NullReferenceException) {
                Console.WriteLine("Error: Missing {0} element", xmlReader.Name);
                Environment.Exit(1);
            }
                #endif

            // If element has attributes we have to get them and deserialize them.
            if (xmlReader.HasAttributes)
            {
                offset = DeserializeAttributes(buffer, offset, xmlReader, suffix);
            }

            // Special case when an elment is empty.
            // Case A: If element is editable a string stub is inserted to allow edition.
            // Case B: If element is not editable then a padding is inserted to handle
            // TextTag behaviour in which zero length ranges are lost.
            if (emptyElement)
            {
                if (((DocumentTag)tagStart.Tag).IsEditable)
                {
                    insertAt = buffer.GetIterAtOffset(offset);
                    buffer.Insert(ref insertAt, "[");
                    offset += 1;

                    offset = DocumentUtils.AddStub(buffer, offset, "Click to Add Documentation", suffix);

                    insertAt = buffer.GetIterAtOffset(offset);
                    buffer.Insert(ref insertAt, "]");
                    offset += 1;
                }
                else
                {
                    offset = DocumentUtils.AddPaddingEmpty(buffer, offset, suffix);
                }

                applyStart = buffer.GetIterAtOffset(tagStart.Start);
                applyEnd   = buffer.GetIterAtOffset(offset);
                buffer.ApplyTag(tagStart.Tag, applyStart, applyEnd);
                offset = FormatEnd(buffer, offset, suffix, elementName);

                // Padding between tag regions
                offset = DocumentUtils.AddPadding(buffer, offset, suffix);
                depth--;

                        #if DEBUG
                Console.WriteLine("Empty Element: {0}, Start: {1}, End: {2}", tagStart.Tag.Name, tagStart.Start, offset);
                        #endif
            }
            else
            {
                stack.Push(tagStart);

                if (((DocumentTag)tagStart.Tag).IsEditable)
                {
                    insertAt = buffer.GetIterAtOffset(offset);
                    buffer.Insert(ref insertAt, "[");
                    offset += 1;
                }
            }

            return(offset);
        }
	private static int InsertStartElement (TextBuffer buffer, int offset, XmlTextReader xmlReader, Stack stack, ref int depth, ref int count)
	{
		string elementName = xmlReader.Name;
		string suffix = String.Empty;
		DocumentTagTable tagTable = (DocumentTagTable) buffer.TagTable;
		bool emptyElement = xmlReader.IsEmptyElement;
		bool isDynamic = DocumentTagTable.IsDynamic (elementName);
		TextIter insertAt, applyStart, applyEnd;
		depth++;
		
		// We define a suffix so each dynamic tag has an unique name.
		// Suffix has format: #{depth level}
		if (isDynamic)
			suffix = "#" + depth;
		
		// We add any needed string to give format to the document.
		offset = FormatStart (buffer, offset, suffix, elementName);
		
		TagStart tagStart = new TagStart ();
		tagStart.Start = offset;
		tagStart.Name = elementName;
		
		// We first lookup the tag name, if the element is dynamic, we can
		// have three scenarios.
		// 1) The tag is not in the table: So we create it in the spot.
		// 2) Tag is in table but it priority is wrong: We created a new
		// dynamic tag with an extra suffix. Format #{depth level}.{count}
		// 3) Tag is in table with right priority: We reuse it and we don't
		// create a new dymamic tag.
		tagStart.Tag = tagTable.Lookup (elementName + suffix);
		if (isDynamic && tagStart.Tag == null)
			tagStart.Tag = tagTable.CreateDynamicTag (elementName + suffix);
		else if (isDynamic && tagStart.Tag != null &&  tagStart.Tag.Priority < ((TagStart) stack.Peek ()).Tag.Priority) {
			suffix += "." + count;
			tagStart.Tag = tagTable.CreateDynamicTag (elementName + suffix);
			count++;
		}
		
		#if DEBUG
		try {
			Console.WriteLine ("Element: {0} Start: {1}", tagStart.Tag.Name, tagStart.Start);
		} catch (NullReferenceException) {
			Console.WriteLine ("Error: Missing {0} element", xmlReader.Name);
			Environment.Exit (1);
		}
		#endif
		
		// If element has attributes we have to get them and deserialize them.
		if (xmlReader.HasAttributes)
			offset = DeserializeAttributes (buffer, offset, xmlReader, suffix);
		
		// Special case when an elment is empty.
		// Case A: If element is editable a string stub is inserted to allow edition.
		// Case B: If element is not editable then a padding is inserted to handle
		// TextTag behaviour in which zero length ranges are lost.
		if (emptyElement) {
			if (((DocumentTag) tagStart.Tag).IsEditable) {
				insertAt = buffer.GetIterAtOffset (offset);
				buffer.Insert (ref insertAt, "[");
				offset += 1;
				
				offset = DocumentUtils.AddStub (buffer, offset, "Click to Add Documentation", suffix);
				
				insertAt = buffer.GetIterAtOffset (offset);
				buffer.Insert (ref insertAt, "]");
				offset += 1;
			} else
				offset = DocumentUtils.AddPaddingEmpty (buffer, offset, suffix);
			
			applyStart = buffer.GetIterAtOffset (tagStart.Start);
			applyEnd = buffer.GetIterAtOffset (offset);
			buffer.ApplyTag (tagStart.Tag, applyStart, applyEnd);
			offset = FormatEnd (buffer, offset, suffix, elementName);
			
			// Padding between tag regions
			offset = DocumentUtils.AddPadding (buffer, offset, suffix);
			depth--;
			
			#if DEBUG
			Console.WriteLine ("Empty Element: {0}, Start: {1}, End: {2}", tagStart.Tag.Name, tagStart.Start, offset);
			#endif
		} else {
			stack.Push (tagStart);
			
			if (((DocumentTag) tagStart.Tag).IsEditable) {
				insertAt = buffer.GetIterAtOffset (offset);
				buffer.Insert (ref insertAt, "[");
				offset += 1;
			}
		}
		
		return offset;
	}