From 0e7a4deaec24d2d1bab8b883d43dc431748fc39f Mon Sep 17 00:00:00 2001 From: "James R. Barlow" Date: Sat, 3 Mar 2018 02:51:45 -0800 Subject: [PATCH] hocr: add baseline function, hocr doc link --- ocrmypdf/hocrtransform.py | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/ocrmypdf/hocrtransform.py b/ocrmypdf/hocrtransform.py index 9e87f1d3..258274d9 100755 --- a/ocrmypdf/hocrtransform.py +++ b/ocrmypdf/hocrtransform.py @@ -49,12 +49,16 @@ class HocrTransform(): """ A class for converting documents from the hOCR format. For details of the hOCR format, see: - http://docs.google.com/View?docid=dfxcv4vc_67g844kf + http://kba.cloud/hocr-spec/ """ def __init__(self, hocrFileName, dpi): self.dpi = dpi self.boxPattern = re.compile(r'bbox((\s+\d+){4})') + self.baselinePattern = re.compile(r''' + baseline \s+ + ([\-\+]?\d*\.?\d*) \s+ # +/- decimal float + ([\-\+]?\d+) # +/- int''', re.VERBOSE) self.hocr = ElementTree.parse(hocrFileName) @@ -117,6 +121,16 @@ class HocrTransform(): out = Rect._make(int(coords[n]) for n in range(4)) return out + def baseline(self, element): + """ + Returns a tuple containing the baseline slope and intercept. + """ + if 'title' in element.attrib: + matches = self.baselinePattern.search(element.attrib['title']) + if matches: + return float(matches.group(1)), int(matches.group(2)) + return (0, 0) + def pt_from_pixel(self, pxl): """ Returns the quantity in PDF units (pt) given quantity in pixels @@ -215,14 +229,16 @@ class HocrTransform(): if invisibleText: text.setTextRenderMode(3) # Invisible (indicates OCR text) + baseline = self.baseline(line) + if abs(baseline[0]) < 0.005: + baseline = (0, baseline[1]) + text.setTextOrigin(pt_line.x1, self.height - pt_line.y2) elements = line.findall( ".//%sspan[@class='%s']" % (self.xmlns, elemclass)) - for n, elem in enumerate(elements): + for elem in elements: elemtxt = self._get_element_text(elem).rstrip() - elemtxt = self.replace_unsupported_chars(elemtxt) - if len(elemtxt) == 0: continue