summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Smith <jules@op59.net>2020-09-01 15:50:19 +0100
committerJulian Smith <jules@op59.net>2020-09-01 15:50:19 +0100
commit3d2eb3182db0451272e428ceb93ed36e118e09fb (patch)
tree377b12f6b81a4815685e15d1a24db5417a3bb80c
parentaeb5f7f0cb3c3fc569519a99c1d3caad60a9efc1 (diff)
cosmetic cleanup, including removal of trailing whitespace.
-rw-r--r--extract.c408
-rw-r--r--extract.h41
2 files changed, 297 insertions, 152 deletions
diff --git a/extract.c b/extract.c
index e17e1db..a03334b 100644
--- a/extract.c
+++ b/extract.c
@@ -3,11 +3,6 @@ Extracts text paragraphs from low-level XML representation of text spans, e.g.
as generated by 'mutool.py draw -F raw', and creates .docx file containing the
text paragraphs.
-Build and test with:
- ./scripts/ptodoc.py
-
-Run with -h or --help to see help.
-
Unless otherwise stated, all functions return 0 on success or -1 with errno
set.
*/
@@ -27,9 +22,16 @@ set.
#include <string.h>
#include <sys/stat.h>
+static const float g_pi = 3.14159265;
/* Simple printf-style debug output. */
-void (extract_outf)(const char* file, int line, const char* fn, int ln, const char* format, ...)
+void (extract_outf)(
+ const char* file, int line,
+ const char* fn,
+ int ln,
+ const char* format,
+ ...
+ )
{
va_list va;
if (ln) {
@@ -138,7 +140,7 @@ void extract_string_free(extract_string_t* string)
int extract_string_catl(extract_string_t* string, const char* s, int s_len)
{
char* chars = realloc(string->chars, string->chars_num + s_len + 1);
- if (!chars) return -1;
+ if (!chars) return -1;
memcpy(chars + string->chars_num, s, s_len);
chars[string->chars_num + s_len] = 0;
string->chars = chars;
@@ -198,7 +200,7 @@ typedef struct {
char* name;
xml_attribute_t* attributes;
int attributes_num;
- extract_string_t text;
+ extract_string_t text;
} xml_tag_t;
/* Returns pointer to value of specified attribute, or NULL if not found. */
@@ -216,7 +218,11 @@ static char* xml_tag_attributes_find(xml_tag_t* tag, const char* name)
/* Finds float value of specified attribute, returning error if not found. We
use atof() and don't check for non-numeric attribute value. */
-static int xml_tag_attributes_find_float(xml_tag_t* tag, const char* name, float* o_out)
+static int xml_tag_attributes_find_float(
+ xml_tag_t* tag,
+ const char* name,
+ float* o_out
+ )
{
const char* value = xml_tag_attributes_find(tag, name);
if (!value) {
@@ -227,7 +233,11 @@ static int xml_tag_attributes_find_float(xml_tag_t* tag, const char* name, float
return 0;
}
-static int xml_tag_attributes_find_int(xml_tag_t* tag, const char* name, int* o_out)
+static int xml_tag_attributes_find_int(
+ xml_tag_t* tag,
+ const char* name,
+ int* o_out
+ )
{
const char* value = xml_tag_attributes_find(tag, name);
if (!value) {
@@ -341,7 +351,7 @@ static FILE* xml_pparse_init(const char* path, const char* first_line)
size_t first_line_len = strlen(first_line);
buffer = malloc(first_line_len + 1);
if (!buffer) goto end;
-
+
ssize_t n = fread(buffer, first_line_len, 1 /*nmemb*/, in);
if (n != 1) {
extract_outf("error: fread() failed. n=%zi. path='%s'", n, path);
@@ -541,7 +551,10 @@ static int s_sign(float x)
/* Unused but usefult o keep code here. */
#if 0
/* Returns zero if *lhs and *rhs are equal, otherwise +/- 1. */
-static int extract_matrix_cmp(const extract_matrix_t* lhs, const extract_matrix_t* rhs)
+static int extract_matrix_cmp(
+ const extract_matrix_t* lhs,
+ const extract_matrix_t* rhs
+ )
{
int ret;
ret = s_sign(lhs->a - rhs->a); if (ret) return ret;
@@ -556,7 +569,10 @@ static int extract_matrix_cmp(const extract_matrix_t* lhs, const extract_matrix_
/* Returns zero if first four members of *lhs and *rhs are equal, otherwise
+/-1. */
-static int extract_matrix_cmp4(const extract_matrix_t* lhs, const extract_matrix_t* rhs)
+static int extract_matrix_cmp4(
+ const extract_matrix_t* lhs,
+ const extract_matrix_t* rhs
+ )
{
int ret;
ret = s_sign(lhs->a - rhs->a); if (ret) return ret;
@@ -739,7 +755,7 @@ static int docx_char_truncate_if(extract_string_t* content, char c)
return 0;
}
-
+/* Like system() but takes printf-style format and args. */
static int systemf(const char* format, ...)
{
char* command;
@@ -755,10 +771,10 @@ static int systemf(const char* format, ...)
}
int extract_docx_create(
- extract_string_t* content,
- const char* path_template,
- const char* path_out,
- int preserve_dir
+ extract_string_t* content,
+ const char* path_template,
+ const char* path_out,
+ int preserve_dir
)
{
assert(path_out);
@@ -788,7 +804,8 @@ int extract_docx_create(
goto end;
}
- extract_outfx("Unzipping template document '%s' to tempdir: %s", path_template, path_tempdir);
+ extract_outfx("Unzipping template document '%s' to tempdir: %s",
+ path_template, path_tempdir);
e = systemf("unzip -q -d %s %s", path_tempdir, path_template);
if (e) {
extract_outf("Failed to unzip %s into %s",
@@ -797,7 +814,10 @@ int extract_docx_create(
goto end;
}
- if (local_asprintf(&word_document_xml, "%s/word/document.xml", path_tempdir) < 0) goto end;
+ if (local_asprintf(
+ &word_document_xml,
+ "%s/word/document.xml",
+ path_tempdir) < 0) goto end;
extract_outfx("Reading tempdir's word/document.xml object");
f = fopen(word_document_xml, "r");
@@ -823,13 +843,14 @@ int extract_docx_create(
extract_outfx("Writing tempdir's word/document.xml file");
f = fopen(word_document_xml, "w");
if (!f) {
- extract_outf("error: Failed to open .docx for writing: %s", word_document_xml);
+ extract_outf("error: Failed to open .docx for writing: %s",
+ word_document_xml);
goto end;
}
if (0
- || fwrite(original, original_pos - original, 1 /*nmemb*/, f) == 0
- || fwrite(content->chars, content->chars_num, 1 /*nmemb*/, f) == 0
- || fwrite(original_pos, strlen(original_pos), 1 /*nmemb*/, f) == 0
+ || fwrite(original, original_pos - original, 1 /*nmemb*/, f) != 1
+ || fwrite(content->chars, content->chars_num, 1 /*nmemb*/, f) != 1
+ || fwrite(original_pos, strlen(original_pos), 1 /*nmemb*/, f) != 1
|| fclose(f) < 0
) {
extract_outf("error: Failed to write to: %s", word_document_xml);
@@ -921,7 +942,14 @@ const char* extract_span_string(extract_span_t* span)
extract_string_cat(&ret, buffer);
int i;
for (i=0; i<span->chars_num; ++i) {
- snprintf(buffer, sizeof(buffer), " i=%i {x=%f adv=%f}", i, span->chars[i].x, span->chars[i].adv);
+ snprintf(
+ buffer,
+ sizeof(buffer),
+ " i=%i {x=%f adv=%f}",
+ i,
+ span->chars[i].x,
+ span->chars[i].adv
+ );
extract_string_cat(&ret, buffer);
}
extract_string_cat(&ret, ": ");
@@ -947,10 +975,14 @@ const char* extract_span_string2(extract_span_t* span)
return ret.chars;
}
-/* Appends new extract_char_t a extract_span_t with .ucs=c and all other fields zeroed. */
+/* Appends new extract_char_t to an extract_span_t with .ucs=c and all other
+fields zeroed. */
static int extract_span_append_c(extract_span_t* span, int c)
{
- extract_char_t* items = realloc(span->chars, sizeof(*items) * (span->chars_num + 1));
+ extract_char_t* items = realloc(
+ span->chars,
+ sizeof(*items) * (span->chars_num + 1)
+ );
if (!items) return -1;
span->chars = items;
extract_char_t* item = &span->chars[span->chars_num];
@@ -1048,21 +1080,28 @@ static const char* extract_paragraph_string(extract_paragraph_t* paragraph)
extract_string_cat(&ret, extract_line_string2(paragraph->lines[0]));
if (paragraph->lines_num > 1) {
extract_string_cat(&ret, "..");
- extract_string_cat(&ret, extract_line_string2(paragraph->lines[paragraph->lines_num-1]));
+ extract_string_cat(
+ &ret,
+ extract_line_string2(paragraph->lines[paragraph->lines_num-1])
+ );
}
}
return ret.chars;
}
/* Returns first line in paragraph. */
-static extract_line_t* extract_paragraph_line_first(const extract_paragraph_t* paragraph)
+static extract_line_t* extract_paragraph_line_first(
+ const extract_paragraph_t* paragraph
+ )
{
assert(paragraph->lines_num);
return paragraph->lines[0];
}
/* Returns last line in paragraph. */
-static extract_line_t* extract_paragraph_line_last(const extract_paragraph_t* paragraph)
+static extract_line_t* extract_paragraph_line_last(
+ const extract_paragraph_t* paragraph
+ )
{
assert(paragraph->lines_num);
return paragraph->lines[ paragraph->lines_num-1];
@@ -1108,7 +1147,11 @@ float extract_span_adv_total(extract_span_t* span)
}
/* Returns distance between end of <a> and beginning of <b>. */
-static float spans_adv(extract_span_t* a_span, extract_char_t* a, extract_char_t* b)
+static float spans_adv(
+ extract_span_t* a_span,
+ extract_char_t* a,
+ extract_char_t* b
+ )
{
float delta_x = b->x - a->x;
float delta_y = b->y - a->y;
@@ -1119,12 +1162,22 @@ static float spans_adv(extract_span_t* a_span, extract_char_t* a, extract_char_t
}
/* Returns 1 if lines have same wmode and are at the same angle, else 0. */
-static int lines_are_compatible(extract_line_t* a, extract_line_t* b, float angle_a, int verbose)
+static int lines_are_compatible(
+ extract_line_t* a,
+ extract_line_t* b,
+ float angle_a,
+ int verbose
+ )
{
if (a == b) return 0;
if (!a->spans || !b->spans) return 0;
- if (extract_line_span_first(a)->wmode != extract_line_span_first(b)->wmode) return 0;
- if (extract_matrix_cmp4(&extract_line_span_first(a)->ctm, &extract_line_span_first(b)->ctm)) {
+ if (extract_line_span_first(a)->wmode != extract_line_span_first(b)->wmode) {
+ return 0;
+ }
+ if (extract_matrix_cmp4(
+ &extract_line_span_first(a)->ctm,
+ &extract_line_span_first(b)->ctm
+ )) {
if (verbose) {
extract_outf("ctm's differ:");
extract_outf(" %f %f %f %f %f %f",
@@ -1155,35 +1208,36 @@ static int lines_are_compatible(extract_line_t* a, extract_line_t* b, float angl
}
-/* Creates representation of extract_span_t's that consists of a list of extract_line_t's, with
-each extract_line_t containins pointers to a list of extract_span_t's.
+/* Creates representation of extract_span_t's that consists of a list of
+extract_line_t's, with each extract_line_t containins pointers to a list of
+extract_span_t's.
We only join spans that are at the same angle and are aligned.
On entry:
Original value of *o_lines and *o_lines_num are ignored.
- <spans> points to array of <spans_num> extract_span_t*'s, each pointing to a
- extract_span_t.
+ <spans> points to array of <spans_num> extract_span_t*'s, each pointing to
+ an extract_span_t.
On exit:
If we succeed, we return 0, with *o_lines pointing to array of *o_lines_num
- extract_line_t*'s, each pointing to a extract_line_t.
+ extract_line_t*'s, each pointing to an extract_line_t.
Otherwise we return -1 with errno set. *o_lines and *o_lines_num are
undefined.
*/
static int make_lines(
- extract_span_t** spans,
- int spans_num,
- extract_line_t*** o_lines,
- int* o_lines_num
+ extract_span_t** spans,
+ int spans_num,
+ extract_line_t*** o_lines,
+ int* o_lines_num
)
{
int ret = -1;
- /* Make a extract_line_t for each span. Then we will join some of these extract_line_t's
- together before returning. */
+ /* Make an extract_line_t for each span. Then we will join some of these
+ extract_line_t's together before returning. */
int lines_num = spans_num;
extract_line_t** lines = NULL;
@@ -1205,7 +1259,7 @@ static int make_lines(
lines[a]->spans[0] = spans[a];
extract_outfx("initial line a=%i: %s", a, extract_line_string(lines[a]));
}
-
+
int num_compatible = 0;
/* For each line, look for nearest aligned line, and append if found. */
@@ -1228,7 +1282,7 @@ static int make_lines(
float angle_a = extract_span_angle(span_a);
if (verbose) extract_outf("a=%i angle_a=%lf ctm=%s: %s",
a,
- angle_a * 180/3.1415926,
+ angle_a * 180/g_pi,
extract_matrix_string(&span_a->ctm),
extract_line_string2(line_a)
);
@@ -1259,7 +1313,6 @@ static int make_lines(
}
num_compatible += 1;
- const float pi = 3.14159265;
/* Find angle between last glyph of extract_span_a and first glyph of
extract_span_b. This detects whether the lines are lined up with each other
@@ -1276,16 +1329,20 @@ static int make_lines(
extract_span_char_last(span_a)->y,
extract_span_char_first(span_b)->x,
extract_span_char_first(span_b)->y,
- angle_a * 180 / pi,
- angle_a_b * 180 / pi
+ angle_a * 180 / g_pi,
+ angle_a_b * 180 / g_pi
);
}
/* Might want to relax this when we test on non-horizontal lines.
*/
const float angle_tolerance_deg = 1;
- if (fabs(angle_a_b - angle_a) * 180/pi <= angle_tolerance_deg) {
+ if (fabs(angle_a_b - angle_a) * 180 / g_pi <= angle_tolerance_deg) {
/* Find distance between end of extract_line_a and beginning of extract_line_b. */
- float adv = spans_adv(span_a, extract_span_char_last(span_a), extract_span_char_first(span_b));
+ float adv = spans_adv(
+ span_a,
+ extract_span_char_last(span_a),
+ extract_span_char_first(span_b)
+ );
if (verbose) extract_outf("nearest_adv=%lf. angle_a_b=%lf adv=%lf",
nearest_adv,
angle_a_b,
@@ -1304,8 +1361,8 @@ static int make_lines(
extract_span_char_last(span_a)->y,
extract_span_char_first(span_b)->x,
extract_span_char_first(span_b)->y,
- angle_a_b * 180/pi,
- angle_a * 180/pi,
+ angle_a_b * 180 / g_pi,
+ angle_a * 180 / g_pi,
span_a->trm.a,
span_a->trm.b
);
@@ -1313,8 +1370,8 @@ static int make_lines(
}
if (nearest_line) {
- /* extract_line_a and nearest_line are aligned so we can move extract_line_b's spans on
- to the end of extract_line_a. */
+ /* extract_line_a and nearest_line are aligned so we can move
+ extract_line_b's spans on to the end of extract_line_a. */
b = nearest_line_b;
if (verbose) extract_outf("found nearest line. a=%i b=%i", a, b);
extract_span_t* span_b = extract_line_span_first(nearest_line);
@@ -1344,7 +1401,10 @@ static int make_lines(
extract_outf(" a: %s", extract_span_string(span_a));
extract_outf(" b: %s", extract_span_string(span_b));
}
- extract_char_t* p = realloc(span_a->chars, (span_a->chars_num + 1) * sizeof(extract_char_t));
+ extract_char_t* p = realloc(
+ span_a->chars,
+ (span_a->chars_num + 1) * sizeof(extract_char_t)
+ );
if (!p) goto end;
span_a->chars = p;
extract_char_t* item = &span_a->chars[span_a->chars_num];
@@ -1387,7 +1447,8 @@ static int make_lines(
}
extract_span_t** s = realloc(
line_a->spans,
- sizeof(extract_span_t*) * (line_a->spans_num + nearest_line->spans_num)
+ sizeof(extract_span_t*)
+ * (line_a->spans_num + nearest_line->spans_num)
);
if (!s) goto end;
line_a->spans = s;
@@ -1407,7 +1468,7 @@ static int make_lines(
if (b > a) {
/* We haven't yet tried appending any spans to nearest_line, so
- the new extended extract_line_a needs checking again. */
+ the new extended line_a needs checking again. */
a -= 1;
}
extract_outfx("new line is:\n %s", extract_line_string2(line_a));
@@ -1429,7 +1490,9 @@ static int make_lines(
}
lines_num = to;
extract_line_t** l = realloc(lines, sizeof(extract_line_t*) * lines_num);
- assert(l); /* Should always succeed because we're not increasing allocation size. */
+ /* Should always succeed because we're not increasing allocation size. */
+ assert(l);
+
lines = l;
*o_lines = lines;
@@ -1454,7 +1517,7 @@ static int make_lines(
}
-/* Returns max font size of all extract_span_t's in a extract_line_t. */
+/* Returns max font size of all extract_span_t's in an extract_line_t. */
static float extract_line_font_size_max(extract_line_t* line)
{
float size_max = 0;
@@ -1471,7 +1534,7 @@ static float extract_line_font_size_max(extract_line_t* line)
-/* Find distance between parallel lines extract_line_a and extract_line_b, both at <angle>.
+/* Find distance between parallel lines line_a and line_b, both at <angle>.
_-R
_-
@@ -1490,14 +1553,21 @@ respectively.
AQB is a right angle. We need to find AQ.
*/
-static float extract_line_distance(float ax, float ay, float bx, float by, float angle)
+static float extract_line_distance(
+ float ax,
+ float ay,
+ float bx,
+ float by,
+ float angle
+ )
{
float dx = bx - ax;
float dy = by - ay;
-
+
return dx * sin(angle) + dy * cos(angle);
}
+
/* A comparison function for use with qsort(), for sorting paragraphs within a
page. */
static int paragraphs_cmp(const void* a, const void* b)
@@ -1533,36 +1603,37 @@ static int paragraphs_cmp(const void* a, const void* b)
return 0;
}
+
/* Creates a representation of extract_line_t's that consists of a list of
-paragraph_t's.
+extract_paragraph_t's.
We only join lines that are at the same angle and are adjacent.
On entry:
Original value of *o_paragraphs and *o_paragraphs_num are ignored.
- <lines> points to array of <lines_num> extract_line_t*'s, each pointing to a
- extract_line_t.
+ <lines> points to array of <lines_num> extract_line_t*'s, each pointing to
+ a extract_line_t.
On exit:
On sucess, returns zero, *o_paragraphs points to array of *o_paragraphs_num
- extract_paragraph_t*'s, each pointing to a extract_paragraph_t. In the array, extract_paragraph_t's
- with same angle are sorted.
+ extract_paragraph_t*'s, each pointing to an extract_paragraph_t. In the
+ array, extract_paragraph_t's with same angle are sorted.
On failure, returns -1 with errno set. *o_paragraphs and *o_paragraphs_num
are undefined.
*/
static int make_paragraphs(
- extract_line_t** lines,
- int lines_num,
- extract_paragraph_t*** o_paragraphs,
- int* o_paragraphs_num
+ extract_line_t** lines,
+ int lines_num,
+ extract_paragraph_t*** o_paragraphs,
+ int* o_paragraphs_num
)
{
int ret = -1;
extract_paragraph_t** paragraphs = NULL;
- /* Start off with a extract_paragraph_t for each extract_line_t. */
+ /* Start off with an extract_paragraph_t for each extract_line_t. */
int paragraphs_num = lines_num;
paragraphs = malloc(sizeof(*paragraphs) * paragraphs_num);
if (!paragraphs) goto end;
@@ -1599,11 +1670,11 @@ static int make_paragraphs(
extract_line_t* line_a = extract_paragraph_line_last(paragraph_a);
float angle_a = extract_line_angle(line_a);
-
+
int verbose = 0;
- /* Look for nearest extract_paragraph_t that could be appended to extract_paragraph_a.
- */
+ /* Look for nearest extract_paragraph_t that could be appended to
+ paragraph_a. */
int b;
for (b=0; b<paragraphs_num; ++b) {
extract_paragraph_t* paragraph_b = paragraphs[b];
@@ -1623,8 +1694,9 @@ static int make_paragraphs(
float by = extract_line_item_first(line_b)->y;
float distance = extract_line_distance(ax, ay, bx, by, angle_a);
if (verbose) {
- extract_outf("angle_a=%lf a=(%lf %lf) b=(%lf %lf) delta=(%lf %lf) distance=%lf:",
- angle_a * 180 / 3.1415926,
+ extract_outf(
+ "angle_a=%lf a=(%lf %lf) b=(%lf %lf) delta=(%lf %lf) distance=%lf:",
+ angle_a * 180 / g_pi,
ax, ay,
bx, by,
bx - ax,
@@ -1652,7 +1724,9 @@ static int make_paragraphs(
if (nearest_paragraph) {
extract_line_t* line_b = extract_paragraph_line_first(nearest_paragraph);
(void) line_b; /* Only used in extract_outfx(). */
- float line_b_size = extract_line_font_size_max(extract_paragraph_line_first(nearest_paragraph));
+ float line_b_size = extract_line_font_size_max(
+ extract_paragraph_line_first(nearest_paragraph)
+ );
if (nearest_paragraph_distance < 1.5 * line_b_size) {
if (verbose) {
extract_outf(
@@ -1666,8 +1740,12 @@ static int make_paragraphs(
);
extract_outf(" %s", extract_paragraph_string(paragraph_a));
extract_outf(" %s", extract_paragraph_string(nearest_paragraph));
- extract_outf("paragraph_a ctm=%s", extract_matrix_string(&paragraph_a->lines[0]->spans[0]->ctm));
- extract_outf("paragraph_a trm=%s", extract_matrix_string(&paragraph_a->lines[0]->spans[0]->trm));
+ extract_outf("paragraph_a ctm=%s",
+ extract_matrix_string(&paragraph_a->lines[0]->spans[0]->ctm)
+ );
+ extract_outf("paragraph_a trm=%s",
+ extract_matrix_string(&paragraph_a->lines[0]->spans[0]->trm)
+ );
}
/* Join these two extract_paragraph_t's. */
extract_span_t* a_span = extract_line_span_last(line_a);
@@ -1682,12 +1760,16 @@ static int make_paragraphs(
}
int a_lines_num_new = paragraph_a->lines_num + nearest_paragraph->lines_num;
- extract_line_t** l = realloc(paragraph_a->lines, sizeof(extract_line_t*) * a_lines_num_new);
+ extract_line_t** l = realloc(
+ paragraph_a->lines,
+ sizeof(extract_line_t*) * a_lines_num_new
+ );
if (!l) goto end;
paragraph_a->lines = l;
int i;
for (i=0; i<nearest_paragraph->lines_num; ++i) {
- paragraph_a->lines[paragraph_a->lines_num + i] = nearest_paragraph->lines[i];
+ paragraph_a->lines[paragraph_a->lines_num + i]
+ = nearest_paragraph->lines[i];
}
paragraph_a->lines_num = a_lines_num_new;
@@ -1697,7 +1779,8 @@ static int make_paragraphs(
paragraphs[nearest_paragraph_b] = NULL;
num_joins += 1;
- extract_outfx("have joined paragraph a=%i to snearest_paragraph_b=%i",
+ extract_outfx(
+ "have joined paragraph a=%i to snearest_paragraph_b=%i",
a,
nearest_paragraph_b
);
@@ -1710,8 +1793,11 @@ static int make_paragraphs(
}
}
else {
- extract_outfx("Not joining paragraphs. nearest_paragraph_distance=%lf extract_line_b_size=%lf",
- nearest_paragraph_distance, extract_line_b_size);
+ extract_outfx(
+ "Not joining paragraphs. nearest_paragraph_distance=%lf extract_line_b_size=%lf",
+ nearest_paragraph_distance,
+ extract_line_b_size
+ );
}
}
}
@@ -1727,13 +1813,22 @@ static int make_paragraphs(
}
extract_outfx("paragraphs_num=%i => %i", paragraphs_num, to);
paragraphs_num = to;
- extract_paragraph_t** p = realloc(paragraphs, sizeof(extract_paragraph_t*) * paragraphs_num);
- assert(p); /* Should always succeed because we're not increasing allocation size. */
+ extract_paragraph_t** p = realloc(
+ paragraphs,
+ sizeof(extract_paragraph_t*) * paragraphs_num
+ );
+ /* Should always succeed because we're not increasing allocation size. */
+ assert(p);
+
paragraphs = p;
/* Sort paragraphs so they appear in correct order, using paragraphs_cmp().
*/
- qsort(paragraphs, paragraphs_num, sizeof(extract_paragraph_t*), paragraphs_cmp);
+ qsort(
+ paragraphs,
+ paragraphs_num,
+ sizeof(extract_paragraph_t*), paragraphs_cmp
+ );
*o_paragraphs = paragraphs;
*o_paragraphs_num = paragraphs_num;
@@ -1801,8 +1896,8 @@ static void extract_page_free(extract_page_t* page)
free(page->paragraphs);
}
-/* Appends new empty extract_span_ to a extract_page_t; returns NULL with errno set on error.
-*/
+/* Appends new empty extract_span_ to an extract_page_t; returns NULL with
+errno set on error. */
static extract_span_t* extract_page_span_append(extract_page_t* page)
{
extract_span_t* span = malloc(sizeof(*span));
@@ -1810,7 +1905,10 @@ static extract_span_t* extract_page_span_append(extract_page_t* page)
span->font_name = NULL;
span->chars = NULL;
span->chars_num = 0;
- extract_span_t** s = realloc(page->spans, sizeof(*s) * (page->spans_num + 1));
+ extract_span_t** s = realloc(
+ page->spans,
+ sizeof(*s) * (page->spans_num + 1)
+ );
if (!s) {
free(span);
return NULL;
@@ -1827,9 +1925,11 @@ void extract_document_init(extract_document_t* document)
document->pages_num = 0;
}
-/* Appends new empty extract_page_t to a extract_document_t; returns NULL with errno set on
+/* Appends new empty extract_page_t to an extract_document_t; returns NULL with errno set on
error. */
-static extract_page_t* extract_document_page_append(extract_document_t* document)
+static extract_page_t* extract_document_page_append(
+ extract_document_t* document
+ )
{
extract_page_t* page = malloc(sizeof(extract_page_t));
if (!page) return NULL;
@@ -1839,7 +1939,10 @@ static extract_page_t* extract_document_page_append(extract_document_t* document
page->lines_num = 0;
page->paragraphs = NULL;
page->paragraphs_num = 0;
- extract_page_t** pages = realloc(document->pages, sizeof(extract_page_t*) * (document->pages_num + 1));
+ extract_page_t** pages = realloc(
+ document->pages,
+ sizeof(extract_page_t*) * (document->pages_num + 1)
+ );
if (!pages) {
free(page);
return NULL;
@@ -1867,9 +1970,9 @@ void extract_document_free(extract_document_t* document)
/* Does preliminary processing of the end of the last spen in a page; intended
to be called as we load span information.
-Looks at last two extract_char_t's in last extract_span_t of <page>, and either leaves
-unchanged, or removes space in last-but-one position, or moves last extract_char_t into
-a new extract_span_t. */
+Looks at last two extract_char_t's in last extract_span_t of <page>, and either
+leaves unchanged, or removes space in last-but-one position, or moves last
+extract_char_t into a new extract_span_t. */
static int extract_page_span_end_clean(extract_page_t* page)
{
int ret = -1;
@@ -1884,7 +1987,8 @@ static int extract_page_span_end_clean(extract_page_t* page)
return 0;
}
- float font_size = extract_matrix_expansion(span->trm) * extract_matrix_expansion(span->ctm);
+ float font_size = extract_matrix_expansion(span->trm)
+ * extract_matrix_expansion(span->ctm);
point_t dir;
if (span->wmode) {
@@ -1902,7 +2006,7 @@ static int extract_page_span_end_clean(extract_page_t* page)
float err_x = (char_[-1].pre_x - x) / font_size;
float err_y = (char_[-1].pre_y - y) / font_size;
-
+
if (span->chars_num >= 2 && span->chars[span->chars_num-2].ucs == ' ') {
int remove_penultimate_space = 0;
if (err_x < -span->chars[span->chars_num-2].adv / 2
@@ -1911,9 +2015,11 @@ static int extract_page_span_end_clean(extract_page_t* page)
remove_penultimate_space = 1;
}
if ((char_[-1].pre_x - char_[-2].pre_x) / font_size < char_[-1].adv / 10) {
- extract_outfx("removing penultimate space because space very narrow:"
- "char_[-1].pre_x-char_[-2].pre_x=%f font_size=%f extract_char_[-1].adv=%f",
- extract_char_[-1].pre_x-char_[-2].pre_x,
+ extract_outfx(
+ "removing penultimate space because space very narrow:"
+ "char_[-1].pre_x-char_[-2].pre_x=%f font_size=%f"
+ " extract_char_[-1].adv=%f",
+ extract_char_[-1].pre_x - char_[-2].pre_x,
font_size,
char_[-1].adv
);
@@ -1924,7 +2030,8 @@ static int extract_page_span_end_clean(extract_page_t* page)
character. We discard previous space character - these
sometimes seem to appear in the middle of words for some
reason. */
- extract_outfx("removing space before final char in: %s", extract_span_string(span));
+ extract_outfx("removing space before final char in: %s",
+ extract_span_string(span));
span->chars[span->chars_num-2] = span->chars[span->chars_num-1];
span->chars_num -= 1;
extract_outfx("span is now: %s", extract_span_string(span));
@@ -1936,7 +2043,9 @@ static int extract_page_span_end_clean(extract_page_t* page)
previous characters, so split into two spans. This often
splits text incorrectly, but this is corrected later when
we join spans into lines. */
- extract_outfx("Splitting last char into new span. font_size=%f dir.x=%f char[-1].pre=(%f, %f) err=(%f, %f): %s",
+ extract_outfx(
+ "Splitting last char into new span. font_size=%f dir.x=%f"
+ " char[-1].pre=(%f, %f) err=(%f, %f): %s",
font_size,
dir.x,
extract_char_[-1].pre_x,
@@ -1963,9 +2072,9 @@ static int extract_page_span_end_clean(extract_page_t* page)
}
int extract_read_spans_raw(
- const char* path,
+ const char* path,
extract_document_t* document,
- int autosplit
+ int autosplit
)
{
int ret = -1;
@@ -1973,8 +2082,12 @@ int extract_read_spans_raw(
FILE* in = NULL;
extract_document_init(document);
int num_spans = 0;
- int num_spans_split = 0; /* Num extra spns from extract_page_span_end_clean(). */
- int num_spans_autosplit = 0; /* Num extra spans from autosplit=1. */
+
+ /* Num extra spns from extract_page_span_end_clean(). */
+ int num_spans_split = 0;
+
+ /* Num extra spans from autosplit=1. */
+ int num_spans_autosplit = 0;
xml_tag_t tag;
xml_tag_init(&tag);
@@ -2043,10 +2156,10 @@ int extract_read_spans_raw(
extract_span_t* span = extract_page_span_append(page);
if (!span) goto end;
-
+
if (s_matrix_read(xml_tag_attributes_find(&tag, "ctm"), &span->ctm)) goto end;
if (s_matrix_read(xml_tag_attributes_find(&tag, "trm"), &span->trm)) goto end;
-
+
char* f = xml_tag_attributes_find(&tag, "font_name");
if (!f) {
extract_outf("Failed to find attribute 'font_name'");
@@ -2081,19 +2194,23 @@ int extract_read_spans_raw(
extract_outf("Expected <char> but tag.name='%s'", tag.name);
goto end;
}
-
+
float char_pre_x;
float char_pre_y;
if (xml_tag_attributes_find_float(&tag, "x", &char_pre_x)) goto end;
if (xml_tag_attributes_find_float(&tag, "y", &char_pre_y)) goto end;
-
+
if (autosplit && char_pre_y - offset_y != 0) {
- extract_outfx("autosplit: extract_char_pre_y=%f offset_y=%f", extract_char_pre_y, offset_y);
- float e = span->ctm.e + span->ctm.a * (char_pre_x-offset_x) + span->ctm.b * (char_pre_y-offset_y);
- float f = span->ctm.f + span->ctm.c * (char_pre_x-offset_x) + span->ctm.d * (char_pre_y-offset_y);
+ extract_outfx("autosplit: extract_char_pre_y=%f offset_y=%f",
+ extract_char_pre_y, offset_y);
+ float e = span->ctm.e + span->ctm.a * (char_pre_x-offset_x)
+ + span->ctm.b * (char_pre_y - offset_y);
+ float f = span->ctm.f + span->ctm.c * (char_pre_x-offset_x)
+ + span->ctm.d * (char_pre_y - offset_y);
offset_x = char_pre_x;
offset_y = char_pre_y;
- extract_outfx("autosplit: changing ctm.{e,f} from (%f, %f) to (%f, %f)",
+ extract_outfx(
+ "autosplit: changing ctm.{e,f} from (%f, %f) to (%f, %f)",
span->ctm.e,
span->ctm.f,
e, f
@@ -2112,30 +2229,34 @@ int extract_read_spans_raw(
}
span->ctm.e = e;
span->ctm.f = f;
- extract_outfx("autosplit: extract_char_pre_y=%f offset_y=%f", extract_char_pre_y, offset_y);
+ extract_outfx("autosplit: extract_char_pre_y=%f offset_y=%f",
+ extract_char_pre_y, offset_y);
}
-
+
if (extract_span_append_c(span, 0 /*c*/)) goto end;
extract_char_t* char_ = &span->chars[ span->chars_num-1];
char_->pre_x = char_pre_x - offset_x;
char_->pre_y = char_pre_y - offset_y;
if (char_->pre_y) {
- extract_outfx("char_->pre=(%f %f)", char_->pre_x, char_->pre_y);
+ extract_outfx("char_->pre=(%f %f)",
+ char_->pre_x, char_->pre_y);
}
char_->x = span->ctm.a * char_->pre_x + span->ctm.b * char_->pre_y;
char_->y = span->ctm.c * char_->pre_x + span->ctm.d * char_->pre_y;
if (xml_tag_attributes_find_float(&tag, "adv", &char_->adv)) goto end;
-
+
if (xml_tag_attributes_find_int(&tag, "ucs", &char_->ucs)) goto end;
char trm[64];
snprintf(trm, sizeof(trm), "%s", extract_matrix_string(&span->trm));
char_->x += span->ctm.e;
char_->y += span->ctm.f;
-
- extract_outfx("ctm=%s trm=%s ctm*trm=%f pre=(%f %f) => xy=(%f %f) [orig xy=(%f %f)]",
+
+ extract_outfx(
+ "ctm=%s trm=%s ctm*trm=%f pre=(%f %f) =>"
+ " xy=(%f %f) [orig xy=(%f %f)]",
extract_matrix_string(&span->ctm),
trm,
span->ctm.a * span->trm.a,
@@ -2143,7 +2264,7 @@ int extract_read_spans_raw(
extract_char_->x, extract_char_->y,
x, y
);
-
+
int page_spans_num_old = page->spans_num;
if (extract_page_span_end_clean(page)) goto end;
span = page->spans[page->spans_num-1];
@@ -2153,9 +2274,10 @@ int extract_read_spans_raw(
}
xml_tag_free(&tag);
}
- extract_outf("page=%i page->num_spans=%i", document->pages_num, page->spans_num);
+ extract_outf("page=%i page->num_spans=%i",
+ document->pages_num, page->spans_num);
}
-
+
extract_outf("num_spans=%i num_spans_split=%i num_spans_autosplit=%i",
num_spans,
num_spans_split,
@@ -2182,7 +2304,8 @@ int extract_read_spans_raw(
static float matrices_to_font_size(extract_matrix_t* ctm, extract_matrix_t* trm)
{
- float font_size = extract_matrix_expansion(*trm) * extract_matrix_expansion(*ctm);
+ float font_size = extract_matrix_expansion(*trm)
+ * extract_matrix_expansion(*ctm);
/* Round font_size to nearest 0.01. */
font_size = (int) (font_size * 100 + 0.5) / 100.0;
return font_size;
@@ -2192,7 +2315,11 @@ static float matrices_to_font_size(extract_matrix_t* ctm, extract_matrix_t* trm)
points to zero-terminated content, allocated by realloc().
spacing: if true, we insert extra vertical space between paragraphs. */
-static int paragraphs_to_content(extract_document_t* document, extract_string_t* content, int spacing)
+static int paragraphs_to_content(
+ extract_document_t* document,
+ extract_string_t* content,
+ int spacing
+ )
{
int ret = -1;
@@ -2213,7 +2340,10 @@ static int paragraphs_to_content(extract_document_t* document, extract_string_t*
&& ctm_prev
&& paragraph->lines_num
&& paragraph->lines[0]->spans_num
- && extract_matrix_cmp4(ctm_prev, &paragraph->lines[0]->spans[0]->ctm)
+ && extract_matrix_cmp4(
+ ctm_prev,
+ &paragraph->lines[0]->spans[0]->ctm
+ )
) {
/* Extra vertical space between paragraphs that were at
different angles in the original document. */
@@ -2233,7 +2363,9 @@ static int paragraphs_to_content(extract_document_t* document, extract_string_t*
for (s=0; s<line->spans_num; ++s) {
extract_span_t* span = line->spans[s];
ctm_prev = &span->ctm;
- float font_size_new = matrices_to_font_size(&span->ctm, &span->trm);
+ float font_size_new = matrices_to_font_size(
+ &span->ctm, &span->trm
+ );
if (!font_name
|| strcmp(span->font_name, font_name)
|| span->font_bold != font_bold
@@ -2247,7 +2379,13 @@ static int paragraphs_to_content(extract_document_t* document, extract_string_t*
font_bold = span->font_bold;
font_italic = span->font_italic;
font_size = font_size_new;
- if (docx_run_start(content, font_name, font_size, font_bold, font_italic)) goto end;
+ if (docx_run_start(
+ content,
+ font_name,
+ font_size,
+ font_bold,
+ font_italic
+ )) goto end;
}
int si;
@@ -2256,7 +2394,7 @@ static int paragraphs_to_content(extract_document_t* document, extract_string_t*
int c = extract_char_->ucs;
if (0) {}
-
+
/* Escape XML special characters. */
else if (c == '<') docx_char_append_string(content, "&lt;");
else if (c == '>') docx_char_append_string(content, "&gt;");
@@ -2318,8 +2456,8 @@ static int paragraphs_to_content(extract_document_t* document, extract_string_t*
*content points to zero-terminated content, allocated by realloc(). */
int extract_document_to_docx_content(
extract_document_t* document,
- extract_string_t* content,
- int spacing
+ extract_string_t* content,
+ int spacing
)
{
int ret = -1;
diff --git a/extract.h b/extract.h
index 150a609..1d663d3 100644
--- a/extract.h
+++ b/extract.h
@@ -5,7 +5,15 @@ Unless otherwise stated, all functions return 0 on success or -1 with errno
set.
*/
-void extract_outf(const char* file, int line, const char* fn, int ln, const char* format, ...);
+/* Simple debug output. */
+void (extract_outf)(
+ const char* file, int line,
+ const char* fn,
+ int ln,
+ const char* format,
+ ...
+ )
+;
#define extract_outf(format, ...) (extract_outf)(__FILE__, __LINE__, __FUNCTION__, 1 /*ln*/, format, ##__VA_ARGS__)
#define extract_outfx(format, ...)
@@ -71,7 +79,7 @@ typedef struct extract_span_t
typedef struct
{
extract_span_t** spans;
- int spans_num;
+ int spans_num;
} extract_line_t;
/* A list of lines that are aligned and adjacent to each other so as to form a
@@ -79,27 +87,27 @@ paragraph. */
typedef struct
{
extract_line_t** lines;
- int lines_num;
+ int lines_num;
} extract_paragraph_t;
/* A page. */
typedef struct
{
- extract_span_t** spans;
- int spans_num;
+ extract_span_t** spans;
+ int spans_num;
/* .lines[] eventually points to items in .spans. */
- extract_line_t** lines;
- int lines_num;
+ extract_line_t** lines;
+ int lines_num;
/* .paragraphs[] eventually points to items in .lines. */
extract_paragraph_t** paragraphs;
- int paragraphs_num;
+ int paragraphs_num;
} extract_page_t;
typedef struct {
extract_page_t** pages;
- int pages_num;
+ int pages_num;
} extract_document_t;
void extract_document_init(extract_document_t* document);
@@ -122,8 +130,8 @@ int extract_read_spans_raw(
*content points to zero-terminated content, allocated by realloc(). */
int extract_document_to_docx_content(
extract_document_t* document,
- extract_string_t* content,
- int spacing
+ extract_string_t* content,
+ int spacing
);
/*
@@ -142,12 +150,11 @@ preserve_dir:
Returns 0 on success or -1 with errno set.
-We use the 'zip' and 'unzip' commands.
+Uses the 'zip' and 'unzip' commands internally.
*/
-
int extract_docx_create(
- extract_string_t* content,
- const char* path_template,
- const char* path_out,
- int preserve_dir
+ extract_string_t* content,
+ const char* path_template,
+ const char* path_out,
+ int preserve_dir
);