Make links live again

This commit is contained in:
David Baer
2017-01-23 00:14:41 -05:00
parent 549a6cbab7
commit eb62727ff9
3 changed files with 43 additions and 1 deletions

View File

@@ -44,6 +44,7 @@ typedef enum {
TOK_UNICODE, TOK_UNICODE,
TOK_STAR, TOK_STAR,
TOK_REF, TOK_REF,
TOK_URL,
/* /*
TOK_DASH, TOK_DASH,
TOK_OPEN_DOUBLE_QUOTE, TOK_OPEN_DOUBLE_QUOTE,
@@ -84,6 +85,21 @@ latinChar(uint32_t ch) {
return (ch <= 0xff) || extendedPunctuation(ch); return (ch <= 0xff) || extendedPunctuation(ch);
} }
inline int
httpAt(Tokenizer tokenizer) {
return ((tolower(tokenizer->txt[tokenizer->byteIndex]) == 'h') &&
(tolower(tokenizer->txt[tokenizer->byteIndex + 1]) == 't') &&
(tolower(tokenizer->txt[tokenizer->byteIndex + 2]) == 't') &&
(tolower(tokenizer->txt[tokenizer->byteIndex + 3]) == 'p') &&
((tokenizer->txt[tokenizer->byteIndex + 4] == ':') &&
(tokenizer->txt[tokenizer->byteIndex + 5] == '/') &&
(tokenizer->txt[tokenizer->byteIndex + 6] == '/')) ||
((tolower(tokenizer->txt[tokenizer->byteIndex + 4]) == 's') &&
(tokenizer->txt[tokenizer->byteIndex + 5] == ':') &&
(tokenizer->txt[tokenizer->byteIndex + 6] == '/') &&
(tokenizer->txt[tokenizer->byteIndex + 7] == '/')));
}
static Token static Token
nextToken(Tokenizer tokenizer) { nextToken(Tokenizer tokenizer) {
int startIndex = tokenizer->byteIndex; int startIndex = tokenizer->byteIndex;
@@ -125,12 +141,30 @@ nextToken(Tokenizer tokenizer) {
result.toktype = TOK_REF; result.toktype = TOK_REF;
result.toktext = strndup(tokenizer->txt + idStart, idEnd - idStart); result.toktext = strndup(tokenizer->txt + idStart, idEnd - idStart);
return result; return result;
} else if (httpAt(tokenizer)) {
int endIndex = 0;
while ((ch != 0) && (ch != ' ') && (ch != '\r') && (ch != '\n')) {
utf8Advance(tokenizer);
ch = utf8CharAt(tokenizer);
}
if (tokenizer->txt[tokenizer->byteIndex - 1] == '.') {
/* heuristic: url doesn't end in . */
endIndex = --tokenizer->byteIndex;
} else {
endIndex = tokenizer->byteIndex;
}
result.toktype = TOK_URL;
result.toktext = strndup(tokenizer->txt + startIndex, endIndex - startIndex);
return result;
} else if (latinChar(ch)) { } else if (latinChar(ch)) {
while ((ch != 0) && latinChar(ch) && (ch != '*')) { while ((ch != 0) && latinChar(ch) && (ch != '*')) {
utf8Advance(tokenizer); utf8Advance(tokenizer);
ch = utf8CharAt(tokenizer); ch = utf8CharAt(tokenizer);
if (ch == '^') { if (ch == '^') {
if (tokenizer->txt[tokenizer->byteIndex + 1] == '{') break; if (tokenizer->txt[tokenizer->byteIndex + 1] == '{') break;
} else if (httpAt(tokenizer)) {
break;
} }
} }
result.toktype = TOK_TEXT; result.toktype = TOK_TEXT;
@@ -181,6 +215,8 @@ int formatText(const char* txt, FormatElement** dst, CitationRecordQueue* citati
t = FORMAT_GREEK; t = FORMAT_GREEK;
} else if (tok.toktype == TOK_UNICODE) { } else if (tok.toktype == TOK_UNICODE) {
t = FORMAT_UNICODE; t = FORMAT_UNICODE;
} else if (tok.toktype == TOK_URL) {
t = FORMAT_URL;
} else if (tok.toktype == TOK_REF) { } else if (tok.toktype == TOK_REF) {
t = FORMAT_CITATION; t = FORMAT_CITATION;
if (citationQPtr && !lookupCitation(*citationQPtr, tok.toktext)) { if (citationQPtr && !lookupCitation(*citationQPtr, tok.toktext)) {

View File

@@ -37,7 +37,8 @@ typedef enum {
FORMAT_STRONG, FORMAT_STRONG,
FORMAT_CITATION, FORMAT_CITATION,
FORMAT_GREEK, FORMAT_GREEK,
FORMAT_UNICODE FORMAT_UNICODE,
FORMAT_URL
} FormatElementType; } FormatElementType;
typedef struct FormatElement FormatElement; typedef struct FormatElement FormatElement;

View File

@@ -93,6 +93,11 @@ formatElementsToXML(
xmlNodePtr unicode = xmlNewNode(sermon_ns, "unicode"); xmlNodePtr unicode = xmlNewNode(sermon_ns, "unicode");
xmlAddChild(unicode, xmlNewText(a[i].elementContent.textContent)); xmlAddChild(unicode, xmlNewText(a[i].elementContent.textContent));
xmlAddChild(parentElement, unicode); xmlAddChild(parentElement, unicode);
} else if (a[i].elementType == FORMAT_URL) {
xmlNodePtr link = xmlNewNode(sermon_ns, "link");
xmlSetProp(link, "href", a[i].elementContent.textContent);
xmlAddChild(link, xmlNewText(a[i].elementContent.textContent));
xmlAddChild(parentElement, link);
} else if (a[i].elementType == FORMAT_CITATION) { } else if (a[i].elementType == FORMAT_CITATION) {
xmlNodePtr cite = xmlNewNode(sermon_ns, "cite"); xmlNodePtr cite = xmlNewNode(sermon_ns, "cite");
int num = findReferenceNumber(numReferences, sermonReferencesPtr, a[i].elementContent.textContent); int num = findReferenceNumber(numReferences, sermonReferencesPtr, a[i].elementContent.textContent);