Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9abc0f159c | ||
|
|
eb62727ff9 | ||
|
|
549a6cbab7 | ||
|
|
af79834d89 | ||
|
|
501d6c87c2 | ||
|
|
cbd16b6ab1 | ||
|
|
0f69fd7a8e |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -2,6 +2,7 @@ Makefile
|
||||
Makefile.in
|
||||
aclocal.m4
|
||||
autom4te.cache/
|
||||
compile
|
||||
config.h
|
||||
config.h.in
|
||||
config.h.in~
|
||||
@@ -22,3 +23,4 @@ stamp-h1
|
||||
ylwrap
|
||||
*.o
|
||||
*.core
|
||||
*.tar.gz
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ([2.69])
|
||||
AC_INIT([sermon], [1.0], [david.a.baer@gmail.com])
|
||||
AC_INIT([sermon], [1.1], [david.a.baer@gmail.com])
|
||||
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
|
||||
AC_CONFIG_SRCDIR([config.h.in])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
|
||||
48
sermon.1
Normal file
48
sermon.1
Normal file
@@ -0,0 +1,48 @@
|
||||
.Dd $Mdocdate: July 7 2016$
|
||||
.Dt SERMON 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm sermon
|
||||
.Nd converts sermon text markup to a variety of formats
|
||||
.Sh SYNOPSIS
|
||||
.Nm sermon
|
||||
.Op Fl hv
|
||||
.Op Fl a Ar author
|
||||
.Op Fl s Ar stylename
|
||||
.Op Fl o Ar output
|
||||
.Ar
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Nm
|
||||
utility converts sermon markup text into a variety of useful formats,
|
||||
including
|
||||
.Em HTML Ns
|
||||
,
|
||||
.Em ODT Ns
|
||||
, and
|
||||
.Em XSL-FO No Ns .
|
||||
.\" .Sh CONTEXT
|
||||
.\" For section 9 functions only.
|
||||
.\" .Sh IMPLEMENTATION NOTES
|
||||
.\" Not used in OpenBSD.
|
||||
.\" .Sh RETURN VALUES
|
||||
.\" For sections 2, 3, and 9 function return values only.
|
||||
.\" .Sh ENVIRONMENT
|
||||
.\" For sections 1, 6, 7, and 8 only.
|
||||
.\" .Sh FILES
|
||||
.\" .Sh EXIT STATUS
|
||||
.\" For sections 1, 6, and 8 only.
|
||||
.\" .Sh EXAMPLES
|
||||
.\" .Sh DIAGNOSTICS
|
||||
.\" For sections 1, 4, 6, 7, 8, and 9 printf/stderr messages only.
|
||||
.\" .Sh ERRORS
|
||||
.\" For sections 2, 3, 4, and 9 errno settings only.
|
||||
.\" .Sh SEE ALSO
|
||||
.\" .Xr foobar 1
|
||||
.\" .Sh STANDARDS
|
||||
.\" .Sh HISTORY
|
||||
.\" .Sh AUTHORS
|
||||
.\" .Sh CAVEATS
|
||||
.\" .Sh BUGS
|
||||
.\" .Sh SECURITY CONSIDERATIONS
|
||||
.\" Not used in OpenBSD.
|
||||
48
src/format.c
48
src/format.c
@@ -44,6 +44,7 @@ typedef enum {
|
||||
TOK_UNICODE,
|
||||
TOK_STAR,
|
||||
TOK_REF,
|
||||
TOK_URL,
|
||||
/*
|
||||
TOK_DASH,
|
||||
TOK_OPEN_DOUBLE_QUOTE,
|
||||
@@ -84,6 +85,21 @@ latinChar(uint32_t 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
|
||||
nextToken(Tokenizer tokenizer) {
|
||||
int startIndex = tokenizer->byteIndex;
|
||||
@@ -125,12 +141,30 @@ nextToken(Tokenizer tokenizer) {
|
||||
result.toktype = TOK_REF;
|
||||
result.toktext = strndup(tokenizer->txt + idStart, idEnd - idStart);
|
||||
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)) {
|
||||
while ((ch != 0) && latinChar(ch) && (ch != '*')) {
|
||||
utf8Advance(tokenizer);
|
||||
ch = utf8CharAt(tokenizer);
|
||||
if (ch == '^') {
|
||||
if (tokenizer->txt[tokenizer->byteIndex + 1] == '{') break;
|
||||
} else if (httpAt(tokenizer)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
result.toktype = TOK_TEXT;
|
||||
@@ -181,6 +215,8 @@ int formatText(const char* txt, FormatElement** dst, CitationRecordQueue* citati
|
||||
t = FORMAT_GREEK;
|
||||
} else if (tok.toktype == TOK_UNICODE) {
|
||||
t = FORMAT_UNICODE;
|
||||
} else if (tok.toktype == TOK_URL) {
|
||||
t = FORMAT_URL;
|
||||
} else if (tok.toktype == TOK_REF) {
|
||||
t = FORMAT_CITATION;
|
||||
if (citationQPtr && !lookupCitation(*citationQPtr, tok.toktext)) {
|
||||
@@ -223,15 +259,3 @@ void freeFormatElementArray(FormatElement* a, int length) {
|
||||
free(a);
|
||||
}
|
||||
|
||||
#ifdef FORMATTER_TEST
|
||||
#include <stdio.h>
|
||||
|
||||
const char* str = "My name in Chinese is \xe7\x86\x8a\xe5\xa4\xa7\xe8\xa1\x9b, or *xiong da wei*. My favorite Greek passage is \xe1\xbc\x90\xce\xbd \xe1\xbc\x80\xcf\x81\xcf\x87\xe1\xbf\x87 \xe1\xbc\xa6\xce\xbd \xe1\xbd\x81 \xce\xbb\xe1\xbd\xb9\xce\xb3\xce\xbf\xcf\x82.^{cite}";
|
||||
|
||||
int
|
||||
main() {
|
||||
FormatElement* lst;
|
||||
int l = formatText(str, &lst, NULL);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -37,7 +37,8 @@ typedef enum {
|
||||
FORMAT_STRONG,
|
||||
FORMAT_CITATION,
|
||||
FORMAT_GREEK,
|
||||
FORMAT_UNICODE
|
||||
FORMAT_UNICODE,
|
||||
FORMAT_URL
|
||||
} FormatElementType;
|
||||
|
||||
typedef struct FormatElement FormatElement;
|
||||
|
||||
@@ -73,7 +73,7 @@ uint32_t utf8CharAt(const utf8iterator* iter) {
|
||||
((uint32_t)(iter->txt[byteIndex] & 0x03) << 24);
|
||||
|
||||
} else if (((iter->txt[byteIndex] & 0xf7) == 0xfc) &&
|
||||
((iter->txt[byteIndex + 1]) & 0xc0 == 0x80) &&
|
||||
((iter->txt[byteIndex + 1] & 0xc0) == 0x80) &&
|
||||
((iter->txt[byteIndex + 2] & 0xc0) == 0x80) &&
|
||||
((iter->txt[byteIndex + 3] & 0xc0) == 0x80) &&
|
||||
((iter->txt[byteIndex + 4] & 0xc0) == 0x80) &&
|
||||
@@ -112,7 +112,7 @@ _next_offset(const utf8iterator* iter) {
|
||||
((iter->txt[byteIndex + 4] & 0xc0) == 0x80)) {
|
||||
return 5;
|
||||
} else if (((iter->txt[byteIndex] & 0xf7) == 0xfc) &&
|
||||
((iter->txt[byteIndex + 1]) & 0xc0 == 0x80) &&
|
||||
((iter->txt[byteIndex + 1] & 0xc0) == 0x80) &&
|
||||
((iter->txt[byteIndex + 2] & 0xc0) == 0x80) &&
|
||||
((iter->txt[byteIndex + 3] & 0xc0) == 0x80) &&
|
||||
((iter->txt[byteIndex + 4] & 0xc0) == 0x80) &&
|
||||
|
||||
33
src/xml.c
33
src/xml.c
@@ -1,3 +1,31 @@
|
||||
/*
|
||||
* xml.c - Create XML representation of sermon document
|
||||
* Copyright © 2017 David A. Baer
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the organization nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY David A. Baer ''AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL David A. Baer BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#include <libxml/tree.h>
|
||||
#include <string.h>
|
||||
#include "options.h"
|
||||
@@ -65,6 +93,11 @@ formatElementsToXML(
|
||||
xmlNodePtr unicode = xmlNewNode(sermon_ns, "unicode");
|
||||
xmlAddChild(unicode, xmlNewText(a[i].elementContent.textContent));
|
||||
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) {
|
||||
xmlNodePtr cite = xmlNewNode(sermon_ns, "cite");
|
||||
int num = findReferenceNumber(numReferences, sermonReferencesPtr, a[i].elementContent.textContent);
|
||||
|
||||
28
src/xml.h
28
src/xml.h
@@ -1,3 +1,31 @@
|
||||
/*
|
||||
* xml.h - create XML representation of sermon document
|
||||
* Copyright © 2017 David A. Baer
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the organization nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY David A. Baer ''AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL David A. Baer BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#ifndef _XML_H
|
||||
#define _XML_H
|
||||
|
||||
|
||||
Reference in New Issue
Block a user