It talks about combining multiple text notes into one. This is usually needed when converting AutoCAD details to Revit and that is what I am using it for. One thing that I would like to improve is adding a way to set the text box width. Currently it create a big long text box to fit all the text that you combine and then you have to zoom out and adjust the text box down. Below is an example of the long text box:
Is there a way to set a text box width for the new text box it creates? Here is the graph.
Thank you Nick. I was able to use the API and test it with just the Python code alone. When I select one text box, it works. When I select multiple text boxes it doesn’t work which makes sense because the code isn’t set up to handle a list, at least I think that’s why it won’t work. It also gives me an error when I put the Python code in my current graph. I tried using ChatGPT to tell me where to insert the code and it told me to put it where you see in the image. Here is a pic of my graph and where AI told me to put it.
Alternatively I explained to ChatGPT exactly what I wanted and it gave me this code which works! Any thoughts?
# Import Revit and Dynamo APIs
import clr
clr.AddReference('RevitServices')
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import TextNote, XYZ
# Input from Dynamo
textNotes = IN[0] # List of selected TextNote elements
boxWidth = IN[1] # Desired width of final text box
doc = DocumentManager.Instance.CurrentDBDocument
# Unwrap Revit elements
textNotesUnwrapped = [t.InternalElement for t in textNotes]
if not textNotesUnwrapped:
OUT = "No TextNotes selected."
else:
# Create a function to extract position (use Origin point of TextNote)
def get_position(note):
pos = note.Coord
return (round(-pos.Y, 4), round(pos.X, 4)) # Negative Y so highest appears first
# Sort text boxes: top to bottom (-Y), then left to right (X)
sortedNotes = sorted(textNotesUnwrapped, key=get_position)
# Combine text in sorted reading order
combinedText = "\n".join([note.Text for note in sortedNotes])
# Choose the top-left note to keep (first in sorted list)
keeperNote = sortedNotes[0]
notesToDelete = sortedNotes[1:]
# Start modifying in a transaction
TransactionManager.Instance.EnsureInTransaction(doc)
# Modify the keeper text note
keeperNote.Text = combinedText
keeperNote.Width = boxWidth
# Delete the others
for note in notesToDelete:
doc.Delete(note.Id)
TransactionManager.Instance.TransactionTaskDone()
OUT = keeperNote
You are correct. Your original code was setup for a single text note and was failing on a list. You can fix that by looping for each item in your list.
for textNote in textNotes:
textNote.Width = newWidth
ChatGPT did something similar by joining all the text notes into one and then adjusting the width by using a similar in-line notation.
combinedText = "\n".join([note.Text for note in sortedNotes])
In this case, the text is being looped through and added to a list before being joined back together. The part in brackets is the same as:
for note in sortedNotes:
newList.append(note.Text)