summaryrefslogtreecommitdiff
path: root/support/texlab/crates/bibutils_sys/src/pages.c
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2019-12-03 03:01:24 +0000
committerNorbert Preining <norbert@preining.info>2019-12-03 03:01:24 +0000
commitb8d4bb76703bcb15578e2b23c5d256532180b894 (patch)
treebedd1df7a00521a2bd986b3c0289d6556a59e39b /support/texlab/crates/bibutils_sys/src/pages.c
parent02e4625a78a5029e8b5dc2a4ec70193b232f497e (diff)
CTAN sync 201912030301
Diffstat (limited to 'support/texlab/crates/bibutils_sys/src/pages.c')
-rw-r--r--support/texlab/crates/bibutils_sys/src/pages.c87
1 files changed, 87 insertions, 0 deletions
diff --git a/support/texlab/crates/bibutils_sys/src/pages.c b/support/texlab/crates/bibutils_sys/src/pages.c
new file mode 100644
index 0000000000..b972b1f25f
--- /dev/null
+++ b/support/texlab/crates/bibutils_sys/src/pages.c
@@ -0,0 +1,87 @@
+/*
+ * pages.c
+ *
+ * Copyright (c) Chris Putnam 2016-2019
+ *
+ * Program and source code released under GPL verison 2
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "is_ws.h"
+#include "utf8.h"
+#include "pages.h"
+
+/* extract_range()
+ *
+ * Handle input strings like:
+ *
+ * "1-15"
+ * " 1 - 15 "
+ * " 1000--- 1500"
+ * " 1 <<em-dash>> 10"
+ * " 107 111"
+ */
+static void
+extract_range( str *input, str *begin, str *end )
+{
+ /* -30 is the first character of a UTF8 em-dash and en-dash */
+ const char terminators[] = { ' ', '-', '\t', '\r', '\n', -30, '\0' };
+ const char *p;
+
+ str_empty( begin );
+ str_empty( end );
+
+ if ( input->len==0 ) return;
+
+ p = skip_ws( str_cstr( input ) );
+ while ( *p && !strchr( terminators, *p ) )
+ str_addchar( begin, *p++ );
+
+ p = skip_ws( p );
+
+ while ( *p=='-' ) p++;
+ while ( utf8_is_emdash( p ) ) p+=3;
+ while ( utf8_is_endash( p ) ) p+=3;
+
+ p = skip_ws( p );
+
+ while ( *p && !strchr( terminators, *p ) )
+ str_addchar( end, *p++ );
+}
+
+int
+pages_add( fields *bibout, char *outtag, str *invalue, int level )
+{
+ int fstatus, status = 1;
+ str start, stop;
+
+ str_init( &start );
+ str_init( &stop );
+
+ extract_range( invalue, &start, &stop );
+
+ if ( str_memerr( &start ) || str_memerr( &stop ) ) {
+ status = 0;
+ goto out;
+ }
+
+ if ( start.len>0 ) {
+ fstatus = fields_add( bibout, "PAGES:START", str_cstr( &start ), level );
+ if ( fstatus!=FIELDS_OK ) {
+ status = 0;
+ goto out;
+ }
+ }
+
+ if ( stop.len>0 ) {
+ fstatus = fields_add( bibout, "PAGES:STOP", str_cstr( &stop ), level );
+ if ( fstatus!=FIELDS_OK ) status = 0;
+ }
+
+out:
+ str_free( &start );
+ str_free( &stop );
+ return status;
+}
+