def _assemble(self, temp_output_dir: pathlib.Path, current_layout: Layout) -> pathlib.Path: collage_width = self.pagesize.width * current_layout.columns collage_height = self.pagesize.height * current_layout.rows if self.reverse_assembly: logging.debug("Reverse assembly chosen") start, end, step = reverse_pagerange(current_layout) page_range_for_pdflatex = list( reversed([(x, x + current_layout.columns - 1) for x in range(start, end, step)])) tuples = ["-".join(map(str, i)) for i in page_range_for_pdflatex] page_range = ",".join(tuples) else: begin = current_layout.first_page end_of_section = current_layout.columns * current_layout.rows end = current_layout.first_page + end_of_section - 1 page_range = f"{begin}-{end}" file_content = [ "\\batchmode\n", "\\documentclass[a4paper,]{article}\n", f"\\usepackage[papersize={{{collage_width}pt," f"{collage_height}pt}}]{{geometry}}\n", "\\usepackage[utf8]{inputenc}\n", "\\usepackage{pdfpages}\n", "\\begin{document}\n", f"\\includepdfmerge[nup={current_layout.columns}x{current_layout.rows}, " f"noautoscale=true, scale=1.0]" f"{{{str(self.input_filepath)},{page_range} }}\n", "\\end{document}\n", ] input_filepath = temp_output_dir / "texfile.tex" output_filename = f"output_{random_string()}" with input_filepath.open("w") as f: f.writelines(file_content) command = [ "pdflatex", "-interaction=nonstopmode", f"-jobname={output_filename}", f"-output-directory={temp_output_dir}", str(input_filepath), ] logging.debug("Sending command to pdflatex") try: subprocess.check_output(command, stderr=subprocess.STDOUT) except subprocess.CalledProcessError as e: raise errors.UsageError( "Error: pdflatex encountered a problem while " f"assembling the collage and had to abort:\n{e}") except FileNotFoundError as e: raise errors.UsageError( f"pdflatex or the output file was not found:\n{e}") return temp_output_dir / pathlib.Path(output_filename).with_suffix( ".pdf")
def write_chops(self, collage: pikepdf.Pdf, output_path: pathlib.Path) -> None: logger.info("Writing files...") try: collage.save(output_path) except OSError as e: raise errors.UsageError(f"An error occurred " f"while writing the output file:\n{e}")
def write_collage( self, temp_collage_paths: List[pathlib.Path], ) -> None: for counter, collage_path in enumerate(temp_collage_paths): new_outputpath = self.generate_new_outputpath( self.output_path, counter) try: temp_collage = pikepdf.Pdf.open(collage_path) temp_collage.save(new_outputpath) except OSError as e: raise errors.UsageError(f"An error occurred " f"while writing the collage:\n{e}") logger.info(f"Collage written to {new_outputpath}.")
def create_output_files( self, temp_collage_paths: List[pathlib.Path], input_properties: nobubo.assembly.NobuboInput, ) -> None: for counter, collage_path in enumerate(temp_collage_paths): try: collage = pikepdf.Pdf.open(collage_path) except OSError as e: raise errors.UsageError( "Could not open collage file for disassembly:" f"\n{e}.") new_outputpath = self.generate_new_outputpath( self.output_path, counter) logger.debug("Chopping up collage") chopped_up_files = self._create_output_files( collage, input_properties.pagesize, input_properties.layout[counter], ) logger.debug("Successfully chopped up the collage.\n") self.write_chops(chopped_up_files, new_outputpath) logger.info(f"Final pdf written to {new_outputpath}.\n")
def parse_cli_input_data( input_layout: List[Tuple[int, int, int]], reverse_assembly: bool, input_path: str, ) -> NobuboInput: try: with pikepdf.open(pathlib.Path(input_path)) as inputfile: logger.info(f"Received a pdf with {len(input_layout)} overview(s) " f"and {len(inputfile.pages)} pages.") # first page (getPage(0)) may contain overview, so get second one width, height = page_dimensions(inputfile.pages[1]) input_properties = NobuboInput( input_filepath=pathlib.Path(input_path), number_of_pages=len(inputfile.pages), pagesize=PageSize(width=width, height=height), layout=parse_input_layouts(input_layout), reverse_assembly=reverse_assembly, ) logger.debug(f"Parsed input properties: {input_properties}") except OSError as e: raise errors.UsageError(f"While reading the input pdf file, " f"this error occurred:\n{e}") return input_properties