Tutorial: Automating script breakdowns with Notion CSV sync

Film Production Hub is my Notion based workspace for organizing prep and shoot, and is available to purchase on the Notion Marketplace. You can read a tutorial for setting that up here. I’ve now added another tool to that system: An app for iOS called Notion CSV sync, which allows for more advanced syncing of CSV data into Notion databases. This post takes you through using the app to add and update script breakdowns in the Film Production Hub.

Buy Notion CSV sync from the App Store for iPhone, iPad and Mac
 

The most boring part of starting the prep in my Notion system is typing in all the details for every scene in the script. Final Draft-files (FDX) are stored in an XML-based format, which is actually very convenient if you want to automate that process. It means that I can teach a computer to automatically extract information from the scene headers – like scene number, INT/EXT, location and time of day.

Notion already supports importing datasets like this as CSV-files. But the CSV-import to Notion is very basic. It allows you to merge a CSV-file into an existing database, but you cannot update information with new versions of the script, and it does not support related databases.

This is what my app tries to mitigate.

 

Preparing the script

To import your script, you need to get the Final Draft file. PDF won’t do. To convert the FDX into CSV, I use ChatGPT for now, but will definitely consider a dedicated app in future. You can also customize this to your own liking, but here is a prompt to get you started:

 

I’m attaching a Final Draft .FDX file. Please treat it as XML and follow these rules very precisely.

GOAL

Create a downloadable CSV with one row per scene and these columns:

- "Scene" (scene number)

- "Location"

- "Time of Day"

- "INT/EXT"

- "Description" (the first three sentences of the scene’s body text)

- "Page Count" (converted to decimals)

SCENE DETECTION

- A scene is defined by a <Paragraph> element with Type="Scene Heading".

- Use the value of the "Number" attribute on that <Paragraph> as the "Scene" value (e.g. "1", "1A", "39B").

- Page count is found in the <SceneProperties> element as "Length" (e.g. "4/8", "1 2/8").

- Any scene with the <OmittedScene> element should not pull any more information. Just leave the scene number and the word "OMITTED" in the "Description" column.

HOW TO READ THE SCENE HEADING

Very important:

- Scene headings are often split across multiple <Text> children inside the same <Paragraph>.

- You MUST concatenate ALL <Text> child nodes of the Scene Heading <Paragraph>, in document order, to get the full heading string.

- Example XML:

<Paragraph Type="Scene Heading" Number="1">

<Text>int. </Text>

<Text>ali-bygget</Text>

<Text> - morgen </Text>

</Paragraph>

- Full heading string to parse: "int. ali-bygget - morgen"

INT/EXT

- From the full heading string, detect whether it is interior, exterior, or both.

- Use these rules (case-insensitive):

- If it contains "INT", set "INT/EXT" to "INT".

- If it contains "EXT", set "INT/EXT" to "EXT".

- If it contains both (e.g. "INT./EXT.", "EXT./INT.", "I/E"), set "INT/EXT" to "INT;EXT".

- Do NOT use the raw heading as Location; parse INT/EXT separately.

LOCATION

- Start from the full concatenated heading string.

- Strip off the INT/EXT prefix, including variants like:

- "INT. ", "EXT. ", "INT./EXT. ", "EXT./INT. ", "I/E. ", "E/I. ", etc.

- Then split the remaining string on "-" characters.

- The last "-" segment is usually the time-of-day; everything before that is the Location.

- Remove any leading/trailing spaces around the Location.

- Example:

- Heading: "INT. ali-bygget - morgen"

- INT/EXT: "INT"

- Location: "ali-bygget"

- Time of Day (see rules below) is derived from "morgen".

- Heading: "EXT. Stortinget, trailer - dag"

- INT/EXT: "EXT"

- Location: "Stortinget, trailer"

- If, after removing INT/EXT and time-of-day, nothing is left, set Location to an empty string or "Unknown" (but still do the attempt).

TIME OF DAY

- Work from the full heading string (concatenated Text children).

- Map any time words to one of these four buckets:

- "Daylight"

- "Night"

- "Low sun"

- "Twilight"

- Suggested mapping (case-insensitive):

- "NATT", "NIGHT", "NITE", "MIDNIGHT", "LATE NIGHT" → "Night"

- "DAWN", "DUSK", "TWILIGHT" → "Twilight"

- "MORGEN", "FORMIDDAG", "ETTERMIDDAG", "KVELD",

"MORNING", "EVENING", "SUNRISE", "SUNSET", "GOLDEN HOUR",

"EARLY MORNING", "EARLY EVENING", "LATE AFTERNOON"

→ "Low sun"

- "DAG", "DAY", "DAYTIME", "AFTERNOON" → "Daylight"

- If no time-of-day word is found, default to "Daylight".

DESCRIPTION (FIRST THREE SENTENCES)

- The Description must be taken from the scene’s actual text (action and dialogue), not from the scene heading.

- For each scene, collect all Paragraphs after its Scene Heading, up until (but not including) the next Paragraph with Type="Scene Heading".

- For these Paragraphs, concatenate their text (again: concatenate ALL <Text> children inside each Paragraph).

- From that full body text, extract the first three sentences, where sentences end on ".", "!" or "?".

- Join these three sentences with spaces and put that into the "Description" column.

- Do NOT rewrite or summarize the text; use the actual sentences as they appear in the script.

OUTPUT

- Produce a CSV file encoded as UTF-8.

- Columns: Scene, Location, Time of Day, INT/EXT, Description, Page Count.

- One row per scene in script order.

- Make the CSV available for download when you’re done.

 

Bringing the script into Notion

I’m going to assume you now have one CSV file generated by ChatGPT, in my case I’ve called the file “sample script.csv”. I also have a copy of my Film Production Hub set up in Notion, which I’ve named Notion CSV sync.

The first thing you need to do is to log into Notion in the Notion CSV app. You are authorizing the app to access your account, but this can of course be revoked at any time. You can also limit which projects it has access to.

Click “Connect to Notion” on the splash screen

After logging in, you’ll select which projects the app can access

Step 1

Once you’re logged in, you should head on over to the Sync tab, where you’ll be presented with a step by step interface to import your data. Step 1 is to select which database in Notion we should update. Because the Film Production Hub contains several databases that are interconnected, the first thing we need to do is to update the Locations database. When we later populate the Scene breakdown, it needs to find the Location in the Locations database, otherwise it will leave that field empty.

After logging in, you should go to the Sync tab

In the Sync tab, click Select Database

And then find your Locations database

Step 2

Step 2 is to navigate to the folder that contains the CSV file in Finder.

Click on Choose CSV File

Navigate to the file in Finder

You’ll see a quick preview of the data in the CSV file

Step 3

Next we need to map the columns correctly. The app needs to know which column from the CSV goes into what property in the selected Notion database. When adding locations, we need to map the “Location” CSV column to the “Name” property in the Notion database. The rest of the columns should be ignored.

Click Map Columns

Click the Location column

Map it to the Name property, and ignore the rest of the columns

Step 4

Step 4 is an optional step in the app, but very important for the Locations database. We need to use filtering to sort out duplicates, to avoid having several copies of locations that are used for more than one scene.

Click Add Row Filters

Select Remove Duplicates, and make sure the Location column is selected, and Case Sensitive is toggled on

Add New Entries

We are now ready to add entries to the Locations database. Make sure Add New Entries is the selected Sync Mode, and click Start Sync.

Select Add New Entries and Start Sync

Syncing should be reasonably fast, and hopefully complete successfully

The result should be a populated Locations database in your Notion project, without any duplicates

 

Rinse and repeat

Once that is done, we’re going to repeat the process to add the rest of the data to the Scene breakdown in Notion. Select the Scene breakdown database in Step 1, select the same CSV file in Step 2, and click the Edit button for column mapping.

Select the Scene breakdown database

Find the CSV file

Head into the column mapping

As you can see the columns are already correctly mapped because I’ve used the same names for columns in my CSV as the corresponding property in Scene breakdown database. If this is not the case, you have to manually map the columns correctly. Also note the warning on the Locations property, which we’ve mitigated by syncing the Locations database first. We don’t need to do any filtering, so just select Add New Entries, and click Start Sync.

Column mapping happens automatically if the columns have the same name as the Notion properties

Select Add New Entries and click Start Sync

My sample CSV only contains 21 scenes, your feature film likely has more

And that’s it! You should now also have a populated Scene breakdown in your Film Production Hub in Notion.

CSV successfully imported into the Scene breakdown, and ready to start the creative process

 

Updating with new script versions

What happens next is you’ve made a lot of nice plans in your Scene breakdown, and the script writer issues an updated script. This is where the Add & Update sync mode comes into play.

First you need to repeat the process with ChatGPT, creating a new CSV file of the new script. It might contain changes to existing scenes, it might contain some new scenes with A and B splits, and it might contain omitted scenes. You’ll need to update the Locations database first and the Scene breakdown after like last time. The process otherwise is more or less the same, but there is one thing you need to be aware of when updating the Scene breakdown.

Key column

The app needs a Key Column to know what information to update. We’ll select the Scene (scene number) column and property for this. When using the Add & Update sync mode, the app then checks if the information for a certain scene in the CSV is different from the information for the same scene in Notion, and then updates it with the new data. The work you did within the scene in Notion stays the same. All the scenes that don’t have changes stay the same. New scenes are then added as new entries in Notion, alongside the old ones.

I do recommend duplicating your project in Notion as a backup before attempting an Add & Update operation, just in case!

Click Key Column

Select Scene

Make sure columns are otherwise correctly mapped

Select Add & Update as sync mode

 

It’s a wrap!

So, that’s it! You now have a powerful tool to automate script breakdowns and updates in my Film Production Hub. You can also use the same app with whatever other system you have in Notion, maybe you’ve made your own template, or bought one from somebody else. The app is a universal tool that can be integrated into any Notion workflow that requires data entry and where CSV is an option as an intermediate.

I really wish I could do the same for schedule updates from Movie Magic, but haven’t figured out any way to get any useful format out of Movie Magic yet. PDF sadly is too difficult for me to reliably parse and create datasets from. But hit me up if you have an idea or suggestion!

I’ll most likely also create a separate app to do the FDX to CSV conversion, so stay tuned for updates!

Next
Next

The Sensor Post