|
1 | 1 | from collections import defaultdict |
2 | 2 | import os |
3 | 3 | import glob |
| 4 | +import subprocess |
4 | 5 | from typing import Any, DefaultDict, Dict, List, Tuple |
5 | 6 | import matplotlib.pyplot as plt |
6 | 7 | import numpy as np |
@@ -142,6 +143,55 @@ def parse_metadata(self, pdf_layouts: List[LTPage]) -> None: |
142 | 143 |
|
143 | 144 | self.layout_metadata = layout_metadata |
144 | 145 |
|
| 146 | + def retrive_figure_source_code( |
| 147 | + self, figure_layout_info: Dict[int, List[Block]] |
| 148 | + ) -> None: |
| 149 | + """Retrieves the source code of a figure using synctex. |
| 150 | +
|
| 151 | + Args: |
| 152 | + figure_layout_info (Dict[int, List[Block]]): A dictionary where the keys are page indices |
| 153 | + and the values are lists of Block objects representing the bounding boxes of figures on each page. |
| 154 | +
|
| 155 | + Returns: |
| 156 | + None |
| 157 | +
|
| 158 | + Note: |
| 159 | + use `synctex help edit` to view usage of synctex |
| 160 | + """ |
| 161 | + # paper_colored.tex is what we are working for |
| 162 | + tex_filename = os.path.basename(self.tex_file).replace( |
| 163 | + "paper_original", "paper_colored" |
| 164 | + ) |
| 165 | + pdf_filename = tex_filename.replace(".tex", ".pdf") |
| 166 | + with open(os.path.join(self.main_directory, tex_filename), "r") as file: |
| 167 | + content_lines = file.readlines() |
| 168 | + |
| 169 | + for page_index, blocks in figure_layout_info.items(): |
| 170 | + for block in blocks: |
| 171 | + bbox = block.bbox |
| 172 | + center_x, center_y = (bbox[0] + bbox[2]) / 2, (bbox[1] + bbox[3]) / 2 |
| 173 | + log.debug( |
| 174 | + f"page index: {page_index + 1}, center: ({center_x}, {center_y}), pdf filename: {pdf_filename}" |
| 175 | + ) |
| 176 | + # use synctex to retrieve the line index corresponding to the center of the bounding box |
| 177 | + result = subprocess.run( |
| 178 | + [ |
| 179 | + "synctex", |
| 180 | + "edit", |
| 181 | + "-o", |
| 182 | + f"{page_index + 1}:{center_x}:{center_y}:{pdf_filename}", |
| 183 | + "-d", |
| 184 | + self.main_directory, |
| 185 | + ], |
| 186 | + check=True, |
| 187 | + capture_output=True, |
| 188 | + text=True, |
| 189 | + ) |
| 190 | + # parse the output of synctex to get the source code |
| 191 | + line_index = result.stdout.split("\nLine:")[1].split("\n")[0] |
| 192 | + block.source_code = content_lines[int(line_index) - 1] |
| 193 | + log.debug(f"line index: {line_index}, source code: {block.source_code}") |
| 194 | + |
145 | 195 | def generate_figure_bb(self, pdf_layouts: List[LTPage]) -> Dict[int, List[Block]]: |
146 | 196 | """Generate bounding boxes for figures in a PDF layout using Pdfminer. |
147 | 197 |
|
@@ -173,6 +223,9 @@ def generate_figure_bb(self, pdf_layouts: List[LTPage]) -> Dict[int, List[Block] |
173 | 223 | ) |
174 | 224 | ) |
175 | 225 |
|
| 226 | + # find the corresponding source code to figure bounding box |
| 227 | + self.retrive_figure_source_code(layout_info) |
| 228 | + |
176 | 229 | # convert bounding boxes from PDF coordinate system to image coordinate system |
177 | 230 | self.transform(layout_info) |
178 | 231 | return layout_info |
|
0 commit comments