Пример #1
0
        /*
         * Aho-Corasick
         *
         * q = root
         * FOR i = 1 TO n
         *   WHILE q != fail AND g(q, text[i]) == fail
         *     q = h(q)
         *   ENDWHILE
         *   IF q == fail
         *     q = root
         *   ELSE
         *     q = g(q, text[i])
         *   ENDIF
         *   IF isElement(q, final)
         *     RETURN TRUE
         *   ENDIF
         * ENDFOR
         * RETURN FALSE
         */
        public IList <TrieHit> FindMatches(string haystack)
        {
            List <TrieHit> matches = new List <TrieHit> ();
            TrieState      q = root;
            TrieMatch      m = null;
            int            idx = 0, start_idx = 0, last_idx = 0;

            while (idx < haystack.Length)
            {
                char c = haystack [idx++];
                if (!case_sensitive)
                {
                    c = Char.ToLower(c);
                }

                while (q != null)
                {
                    m = FindMatchAtState(q, c);
                    if (m == null)
                    {
                        q = q.Fail;
                    }
                    else
                    {
                        break;
                    }
                }

                if (q == root)
                {
                    start_idx = last_idx;
                }

                if (q == null)
                {
                    q         = root;
                    start_idx = idx;
                }
                else if (m != null)
                {
                    q = m.State;

                    // Got a match!
                    if (q.Final != 0)
                    {
                        string key = haystack.Substring(start_idx,
                                                        idx - start_idx);
                        TrieHit hit =
                            new TrieHit(start_idx, idx, key, q.Id);
                        matches.Add(hit);
                    }
                }

                last_idx = idx;
            }

            return(matches);
        }
Пример #2
0
        void DoHighlight(TrieHit hit, Gtk.TextIter start, Gtk.TextIter end)
        {
            // Some of these checks should be replaced with fixes to
            // TitleTrie.FindMatches, probably.
            if (hit.Value == null)
            {
                Logger.Debug("DoHighlight: null pointer error for '{0}'.", hit.Key);
                return;
            }

            if (Manager.Find(hit.Key) == null)
            {
                Logger.Debug("DoHighlight: '{0}' links to non-existing note.", hit.Key);
                return;
            }

            Note hit_note = (Note)hit.Value;

            if (String.Compare(hit.Key.ToString(), hit_note.Title.ToString(), true) != 0)                 // == 0 if same string
            {
                Logger.Debug("DoHighlight: '{0}' links wrongly to note '{1}'.", hit.Key, hit_note.Title);
                return;
            }

            if (hit_note == this.Note)
            {
                return;
            }

            Gtk.TextIter title_start = start;
            title_start.ForwardChars(hit.Start);

            Gtk.TextIter title_end = start;
            title_end.ForwardChars(hit.End);

            // Only link against whole words/phrases
            if ((!title_start.StartsWord() && !title_start.StartsSentence()) ||
                (!title_end.EndsWord() && !title_end.EndsSentence()))
            {
                return;
            }

            // Don't create links inside URLs
            if (Note.TagTable.HasLinkTag(title_start))
            {
                return;
            }

            Logger.Debug("Matching Note title '{0}' at {1}-{2}...",
                         hit.Key,
                         hit.Start,
                         hit.End);

            Buffer.RemoveTag(Note.TagTable.BrokenLinkTag, title_start, title_end);
            Buffer.ApplyTag(Note.TagTable.LinkTag, title_start, title_end);
        }
Пример #3
0
        void HighlightNoteInBlock(Note find_note, Gtk.TextIter start, Gtk.TextIter end)
        {
            string buffer_text      = start.GetText(end).ToLower();
            string find_title_lower = find_note.Title.ToLower();
            int    idx = 0;

            while (true)
            {
                idx = buffer_text.IndexOf(find_title_lower, idx);
                if (idx < 0)
                {
                    break;
                }

                TrieHit hit = new TrieHit(idx,
                                          idx + find_title_lower.Length,
                                          find_title_lower,
                                          find_note);
                DoHighlight(hit, start, end);

                idx += find_title_lower.Length;
            }
        }
Пример #4
0
		void HighlightNoteInBlock (Note find_note, Gtk.TextIter start, Gtk.TextIter end)
		{
			string buffer_text = start.GetText (end).ToLower();
			string find_title_lower = find_note.Title.ToLower ();
			int idx = 0;

			while (true) {
				idx = buffer_text.IndexOf (find_title_lower, idx);
				if (idx < 0)
					break;

				TrieHit hit = new TrieHit (idx,
				                           idx + find_title_lower.Length,
				                           find_title_lower,
				                           find_note);
				DoHighlight (hit, start, end);

				idx += find_title_lower.Length;
			}
		}
Пример #5
0
		void DoHighlight (TrieHit hit, Gtk.TextIter start, Gtk.TextIter end)
		{
			// Some of these checks should be replaced with fixes to
			// TitleTrie.FindMatches, probably.
			if (hit.Value == null) {
				Logger.Debug ("DoHighlight: null pointer error for '{0}'." , hit.Key);
				return;
			}
			
			if (Manager.Find(hit.Key) == null) {
				Logger.Debug ("DoHighlight: '{0}' links to non-existing note." , hit.Key);
				return;
			}
			
			Note hit_note = (Note) hit.Value;

			if (String.Compare (hit.Key.ToString(), hit_note.Title.ToString(), true ) != 0) { // == 0 if same string  
				Logger.Debug ("DoHighlight: '{0}' links wrongly to note '{1}'." , hit.Key, hit_note.Title);
				return;
			}
			
			if (hit_note == this.Note)
				return;

			Gtk.TextIter title_start = start;
			title_start.ForwardChars (hit.Start);

			Gtk.TextIter title_end = start;
			title_end.ForwardChars (hit.End);

			// Only link against whole words/phrases
			if ((!title_start.StartsWord () && !title_start.StartsSentence ()) ||
			                (!title_end.EndsWord() && !title_end.EndsSentence()))
				return;

			// Don't create links inside URLs
			if (Note.TagTable.HasLinkTag (title_start))
				return;

			Logger.Debug ("Matching Note title '{0}' at {1}-{2}...",
			            hit.Key,
			            hit.Start,
			            hit.End);

			Buffer.RemoveTag (Note.TagTable.BrokenLinkTag, title_start, title_end);
			Buffer.ApplyTag (Note.TagTable.LinkTag, title_start, title_end);
		}