[geany/geany] f22707: Improve Asciidoc title parsing

elextr git-noreply at xxxxx
Thu Jan 23 10:07:37 UTC 2014


Branch:      refs/heads/master
Author:      elextr <elextr at gmail.com>
Committer:   elextr <elextr at gmail.com>
Date:        Thu, 23 Jan 2014 10:07:37 UTC
Commit:      f227076dc425052b85091e495b04f6d5b7a3f965
             https://github.com/geany/geany/commit/f227076dc425052b85091e495b04f6d5b7a3f965

Log Message:
-----------
Improve Asciidoc title parsing

1) Prevent parsing titles inside delimited blocks
2) Always detect -- lines as open block delimiters not titles
3) Support single line titles


Modified Paths:
--------------
    tagmanager/ctags/asciidoc.c

Modified: tagmanager/ctags/asciidoc.c
94 files changed, 61 insertions(+), 33 deletions(-)
===================================================================
@@ -89,24 +89,6 @@ static void makeAsciidocTag (const vString* const name, const int kind)
 }
 
 
-/* checks if str is all the same character */
-static boolean issame(const char *str)
-{
-	char first = *str;
-
-	while (*str)
-	{
-		char c;
-
-		str++;
-		c = *str;
-		if (c && c != first)
-			return FALSE;
-	}
-	return TRUE;
-}
-
-
 static int get_kind(char c)
 {
 	int i;
@@ -150,42 +132,88 @@ static int utf8_strlen(const char *buf, int buf_len)
 }
 
 
-static void findAsciidocTags (void)
+static void findAsciidocTags(void)
 {
-	vString *name = vStringNew ();
+	vString *name = vStringNew();
 	const unsigned char *line;
+	unsigned char in_block = '\0';  /* holds the block marking char or \0 if not in block */
 
 	nestingLevels = nestingLevelsNew();
 
-	while ((line = fileReadLine ()) != NULL)
+	while ((line = fileReadLine()) != NULL)
 	{
 		int line_len = strlen((const char*) line);
 		int name_len_bytes = vStringLength(name);
 		int name_len = utf8_strlen(vStringValue(name), name_len_bytes);
 
 		/* if the name doesn't look like UTF-8, assume one-byte charset */
-		if (name_len < 0)
-			name_len = name_len_bytes;
-
-		/* underlines must be +-2 chars FIXME detect single line titles */
-		if (line_len > 2 && line_len >= name_len - 2 && line_len <= name_len + 2 &&
-			name_len > 0 && ispunct(line[0]) && issame((const char*) line))
+		if (name_len < 0) name_len = name_len_bytes;
+		
+		/* if its a title underline, or a delimited block marking character */
+		if (line[0] == '=' || line[0] == '-' || line[0] == '~' ||
+			line[0] == '^' || line[0] == '+' || line[0] == '.' ||
+			line[0] == '*' || line[0] == '_' || line[0] == '/')
 		{
-			char c = line[0];
-			int kind = get_kind(c);
-
-			if (kind >= 0)
+			int n_same;
+			for (n_same = 1; line[n_same] == line[0]; ++n_same);
+			
+			/* is it a two line title or a delimited block */
+			if (n_same == line_len)
+			{
+				/* if in a block, can't be block start or title, look for block end */
+				if (in_block)
+				{
+					if (line[0] == in_block) in_block = '\0';
+				}
+				
+				/* if its a =_~^+ and the same length +-2 as the line before then its a title */
+				/* (except in the special case its a -- open block start line) */
+				else if ((line[0] == '=' || line[0] == '-' || line[0] == '~' ||
+							line[0] == '^' || line[0] == '+') &&
+						line_len <= name_len + 2 && line_len >= name_len - 2 &&
+						!(line_len == 2 && line[0] == '-'))
+				{
+					int kind = get_kind((char)(line[0]));
+					if (kind >= 0)
+					{
+						makeAsciidocTag(name, kind);
+						continue;
+					}
+				}
+				
+				/* else if its 4 or more /+-.*_= (plus the -- special case) its a block start */
+				else if (((line[0] == '/' || line[0] == '+' || line[0] == '-' ||
+						   line[0] == '.' || line[0] == '*' || line[0] == '_' ||
+						   line[0] == '=') && line_len >= 4 )
+						 || (line[0] == '-' && line_len == 2))
+				{
+					in_block = line[0];
+				}
+			}
+			
+			/* otherwise is it a one line title */
+			else if (line[0] == '=' && n_same <= 5 && isspace(line[n_same]) &&
+					!in_block)
 			{
+				int kind = n_same - 1;
+				int start = n_same;
+				int end = line_len - 1;
+				while (line[end] == line[0])--end;
+				while (isspace(line[start]))++start;
+				while (isspace(line[end]))--end;
+				vStringClear(name);
+				vStringNCatS(name, (const char*)(&(line[start])), end - start + 1);
+				vStringTerminate(name);
 				makeAsciidocTag(name, kind);
 				continue;
 			}
 		}
-		vStringClear (name);
+		vStringClear(name);
 		if (! isspace(*line))
 			vStringCatS(name, (const char*) line);
 		vStringTerminate(name);
 	}
-	vStringDelete (name);
+	vStringDelete(name);
 	nestingLevelsFree(nestingLevels);
 }
 



--------------
This E-Mail was brought to you by github_commit_mail.py (Source: https://github.com/geany/infrastructure).


More information about the Commits mailing list