MCPcopy Create free account
hub / github.com/pymupdf/PyMuPDF / make_table_from_bbox

Function make_table_from_bbox

src/table.py:164–220  ·  view source on GitHub ↗

Detect table structure within a given rectangle.

(textpage, word_rects, rect)

Source from the content-addressed store, hash-verified

162
163
164def make_table_from_bbox(textpage, word_rects, rect):
165 """Detect table structure within a given rectangle."""
166 cells = [] # table cells as (x0,y0,x1,y1) tuples
167
168 # calls fz_find_table_within_bounds
169 block = get_table_dict_from_rect(textpage, rect)
170 # No table structure found if not a grid block
171 if block.get("type") != mupdf.FZ_STEXT_BLOCK_GRID:
172 return cells
173 bbox = pymupdf.Rect(block["bbox"]) # resulting table bbox
174
175 # lists of (pos,uncertainty) tuples
176 xpos = sorted(block["xpos"], key=lambda x: x[0])
177 ypos = sorted(block["ypos"], key=lambda y: y[0])
178
179 # maximum uncertainties in x and y directions
180 xmaxu, ymaxu = block["max_uncertain"]
181
182 # Modify ypos to remove uncertain positions, and y positions
183 # that cut through words.
184 nypos = []
185 for y, yunc in ypos:
186 if yunc > 0: # allow no uncertain y values
187 continue
188 if intersects_words_h(bbox, y, word_rects):
189 continue # allow no y that cuts through words
190 if nypos and (y - nypos[-1] < 3):
191 nypos[-1] = y # snap close positions
192 else:
193 nypos.append(y)
194
195 # New max y uncertainty: 35% of remaining y positions.
196 # Omit x positions that intersect too many words, otherwise
197 # only remove x for the affected cells.
198 ymaxu = max(0, round((len(nypos) - 2) * 0.35))
199
200 # Exclude x positions with too high uncertainty
201 # (we allow more uncertainty in x direction)
202 nxpos = [x[0] for x in xpos if x[1] <= ymaxu]
203 if bbox.x1 > nxpos[-1] + 3:
204 nxpos.append(bbox.x1) # ensure right table border
205
206 # Compose cells from the remaining x and y positions.
207 for i in range(len(nypos) - 1):
208 row_box = pymupdf.Rect(bbox.x0, nypos[i], bbox.x1, nypos[i + 1])
209 # Sub-select words in this row and sort them by left coordinate
210 row_words = sorted(
211 [r for r in word_rects if rect_in_rect(r, row_box)], key=lambda r: r.x0
212 )
213 # Sub-select x values that do not cut through words
214 this_xpos = [x for x in nxpos if not any(r.x0 < x < r.x1 for r in row_words)]
215 for j in range(len(this_xpos) - 1):
216 cell = pymupdf.Rect(this_xpos[j], nypos[i], this_xpos[j + 1], nypos[i + 1])
217 if not cell.is_empty: # valid cell
218 cells.append(tuple(cell))
219 # Add new table to TableFinder tables
220 return cells
221

Callers 1

find_tablesFunction · 0.85

Calls 5

get_table_dict_from_rectFunction · 0.85
intersects_words_hFunction · 0.85
rect_in_rectFunction · 0.85
getMethod · 0.45
appendMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…