Announcements

Welcome to ACC Ideas! Please note not all ideas receive a response and top voted ideas will be considered for future development. Click HERE for more information on the feedback process. Thank you for your ideas!

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Create a list of markups automatically

Create a list of markups automatically

Build should provide a utility to create a list of markups automatically.  I love the markup feature, but when reviewing large drawing sets, it is very helpful to provide a list of all the markups as feedback to our A/E's for use a a checklist.  Adobe has this feature built in, but the PDF engine of Build does not add markups as a native PDF "comment". I grew tired of this lack of functionality so yesterday I used Grok AI to create a python script to do it for me.

 

  1. export the files with all markups and save on computer
  2. run program
  3. choose file saved in step 1 above
  4. choose location and name of file to save the output as (file generated is CSV file)
  5. when program finishes it will tell you.

NOTE: this program uses the fact that Build seems to use a particular font (Arial Unicode MS) for it's markups.  If the original drawings contained this font anywhere the output would be a mess. For this reason my program is not optimal. 

 

If a total non programmer like me can do it than a billion dollar company like autodesk can do it!

Here is the code: written in Python for windows 11, it can be compiled into a standalone executable.

 

 

import fitz  # PyMuPDF
import csv
import tkinter as tk
from tkinter import filedialog, ttk

def process_text(doc, font_name, progress):
    results = []
    for page_num, page in enumerate(doc):
        # Update progress
        progress['value'] = (page_num + 1) / len(doc) * 100
        progress_var.set(f"Processing page {page_num + 1} of {len(doc)}")
        root.update_idletasks()  # Update the GUI

        text_dict = page.get_text("dict")
        for block in text_dict["blocks"]:
            if "lines" in block:
                block_text = []
                for line in block["lines"]:
                    line_text = []
                    for span in line["spans"]:
                        if font_name in span["font"]:
                            line_text.append(span["text"])
                    if line_text:  # Only add if we found matching text in this line
                        block_text.append(''.join(line_text))
                if block_text:  # Only add this block to results if it contains matching text
                    results.append((' '.join(block_text), page_num + 1))
    return results

# Create the main window for the progress indicator
root = tk.Tk()
root.title("PDF Text Extraction Progress")
root.geometry("300x150")

# Progress Bar
progress = ttk.Progressbar(root, orient="horizontal", length=200, mode="determinate")
progress.pack(pady=20)

# Label for progress text
progress_var = tk.StringVar()
progress_label = tk.Label(root, textvariable=progress_var)
progress_var.set("Starting...")
progress_label.pack()

# Open file dialog for input PDF
input_file = filedialog.askopenfilename(
    title="Select PDF File",
    filetypes=[("PDF files", "*.pdf")]
)

if not input_file:
    print("No file selected. Exiting.")
    root.destroy()
    exit()

# Open file dialog for output CSV
output_file = filedialog.asksaveasfilename(
    title="Save CSV File",
    defaultextension=".csv",
    filetypes=[("CSV files", "*.csv")]
)

if not output_file:
    print("No output file selected. Exiting.")
    root.destroy()
    exit()

doc = fitz.open(input_file)
matches = process_text(doc, "ArialUnicodeMS", progress)

# Write results to CSV
with open(output_file, 'w', newline='', encoding='utf-8') as csvfile:
    csvwriter = csv.writer(csvfile)
    # Write header
    csvwriter.writerow(['Text', 'Page Number'])
    # Write data
    for text, page in matches:
        csvwriter.writerow([text, page])

# Update progress to 100% when done
progress['value'] = 100
progress_var.set("Finished!")
root.update_idletasks()

# Wait for user to close the window
root.protocol("WM_DELETE_WINDOW", root.quit)
root.mainloop()

print(f"CSV file '{output_file}' has been created with the results.")

 

 

 

 

2 Comments
lance.borst
Alumni
Status changed to: Gathering Support

Hi @timothy_stark 

Greatly appreciate the idea. We will look into these potentially options. An option currently available may be to incorporate Issues into your analysis. You have the ability to create custom Issues categories as well as new Issue and category types. These can also be utilized as templates to ensure consistency. 

timothy_stark
Participant

I believe "Issues" is not a proper solution.  If that was the solution than why do you have markups at all? The purpose of having markups is because this is how engineering has been done for hundreds of years.  The product should conform to norms, not make the users confirm to the product. Issues is just not a user friendly feature, especially during something like design reviews.  Once in construction I could see the GM or subcontractors using "Issues" because of the additional functionality that it affords.  Just my $0.02............

Can't find what you're looking for? Ask the community or share your knowledge.

Submit Idea