#!/usr/bin/env python3
"""Detect the footnote separator rule on each page by looking for a long run
of dark pixels. Far more reliable than guessing from line spacing, since
single-spaced text also appears in block quotes and verse."""

import os as _os
# resolve paths relative to this archive rather than the machine it was built on
_ROOT = _os.path.dirname(_os.path.dirname(_os.path.abspath(__file__)))
ARCHIVE = _ROOT
_DATA = _os.path.join(_ROOT, 'data')
import glob, json, os, re
import numpy as np
from PIL import Image

out = {}
for path in sorted(glob.glob('/tmp/img/p-*.pgm')):
    pno = int(re.search(r'p-(\d+)', path).group(1))
    a = np.asarray(Image.open(path), dtype=np.uint8)
    h, w = a.shape
    dark = a < 160                      # ink
    # longest horizontal dark run per row, cheaply: count dark px per row and
    # require they be contiguous-ish by checking span vs count
    counts = dark.sum(axis=1)
    cand = []
    for y in np.nonzero(counts > 150)[0]:
        xs = np.nonzero(dark[y])[0]
        # a rule is one solid run; measure the longest contiguous dark run
        d = np.diff(xs)
        breaks = np.nonzero(d > 3)[0]
        starts = np.concatenate(([0], breaks + 1))
        ends = np.concatenate((breaks, [len(xs) - 1]))
        runs = [(int(xs[e] - xs[s] + 1), int(xs[s])) for s, e in zip(starts, ends)]
        run_len, run_x0 = max(runs)
        if run_len >= 170:                            # solid horizontal rule
            cand.append((int(y), int(counts[y]), run_x0, run_len))
    # a rule is in the lower half of the page and is the topmost such run there
    low = [c for c in cand if c[0] > h * 0.45]
    out[pno] = {'h': h, 'w': w, 'rule_y': low[0][0] if low else None,
                'rules': low[:4]}

json.dump(out, open('/tmp/rules.json', 'w'))
found = [p for p, v in out.items() if v['rule_y']]
print(f"pages with a footnote rule detected: {len(found)}")
print(sorted(found))
