Script/workflow to replace backslashes within image(...)?

I accidentally upgraded my Typst install to 0.15 when 99% done with a book X^P

Now all my Windows-pasted Paths are popping errors because of the breaking-change in 0.15.x disallowing backslashes. I have something like 50 image(...) functions containing windows-style paths.

1st question: script to replace “\”

one-time need just to handle the transition:

Has anyone made a script (Python, .bat etc.), or has a RegEx search string (eg. for VSCode find+replace), or a Typst rule etc., that can

  • Find \ only within an image(...) function?
  • Replace with /

I can make it myself, maybe even AI it, just seeing if anyone has already done this - I assume it’ll be helpful for others.

Must only do the find-and-replace within image(...) functions or it’ll break forced line-breaks (also \ in Typst code).


2nd related question: windows workflow

for going-forward in Windows-based typsetting in VSCode:

My workflow to add a figure in MS Windows/VS Code was to right-click the image file in Windows Explorer and Copy as Path, then paste this into Typst, then delete the C:/... to make it a relative path like ./media/picsofbunnies/cutebunny1.jpg etc.

Does anyone have a way to paste a *nix-compliant filepath directly on Windows+VSCode? To avoid manually converting all backslashes - certainly a solution, just annoying and error-prone. (On MacOS I have an Automator Service in Finder that “copies UNIX path” - I don’t think it’s that easy to add this functionality to Windows, maybe requires a 3rd party program?)

Or again maybe there is a Typst-native way (eg. Typst function I can use) to allow backslashes within image(...) functions only.

1 Like

A few ways to do so:

  • Use Tinymist features:

    • Drag-and-drop
    • Type image("") and use the completion menu
  • Use VS Code builtin features:

    1. Open VS Code settings and set explorer.copyRelativePathSeparator to /
    2. Select the file in the sidebar, right click, and copy relative path (Ctrl+K, Ctrl+Shift+C)
3 Likes

One-time Python Script

Gemini created a working python script that worked well for fixing my back-slashes.

Only one of my 6 files had an error after running this:

Oneimage(....alt="had alt-text had \"escaped\" quotation marks), which it erroneously changed to forward-slashes, generating an expected comma error, which I had to manually fix. Worked properly on the other 64 images/figures.

Here’s the Python script for you; enter your filenames at the bottom of the script, place it in your doc’s directory and run it:

# -*- coding: utf-8 -*-
"""
Gemini prompt:
make me a python script that will replace all backslashes \ with forward slashes /, only within an image() function's arguments, in text files containing Typst code.  Make the python function accept a List of filepaths, and it'll iterate through each file and perform the find-and-replacement.
"""

import re
from pathlib import Path
from typing import List

def fix_typst_image_paths(filepaths: List[str]) -> None:
    """
    Iterates through a list of file paths, finds Typst image() functions,
    and replaces all backslashes '\\' with forward slashes '/' within their arguments.
    """
    # Regex breakdown:
    # (image\s*\() -> Matches 'image(' with any optional spaces
    # (.*?)        -> Non-greedily captures everything inside the parentheses
    # (\))         -> Matches the closing parenthesis
    # flags=re.DOTALL ensures it works even if your image() arguments span multiple lines
    image_pattern = r'(image\s*\()(.*?)(\))'
    
    for filepath in filepaths:
        path = Path(filepath)
        
        if not path.is_file():
            print(f"⚠️ File not found, skipping: {path}")
            continue
            
        try:
            # Read the original file content
            content = path.read_text(encoding='utf-8')
            
            def replace_slashes(match):
                opening = match.group(1)
                arguments = match.group(2)
                closing = match.group(3)
                
                # Swap the slashes inside the argument block
                fixed_arguments = arguments.replace('\\', '/')
                return f"{opening}{fixed_arguments}{closing}"
            
            # re.subn returns a tuple: (updated_text, number_of_subs_made)
            updated_content, count = re.subn(image_pattern, replace_slashes, content, flags=re.DOTALL)
            
            if count > 0:
                # Save changes back to the file
                path.write_text(updated_content, encoding='utf-8')
                print(f"✅ Successfully updated {count} image path(s) in: {path.name}")
            else:
                print(f"ℹ️ No backslashes found in image() functions for: {path.name}")
                
        except Exception as e:
            print(f"❌ Error processing {path.name}: {e}")

# --- Example Usage ---
if __name__ == "__main__":
    # Provide the list of target Typst files here
    files_to_fix = [
        "Chapter1.typ",
        "Chapter2.typ",
        "Chapter3.typ",
        "Chapter4.typ",
        "Chapter5.typ",
    ]
    
    print("Starting Typst image path normalization...\n")
    fix_typst_image_paths(files_to_fix)
    print("\nProcessing complete.")

Thanks, the VSCode settings works perfectly - didn’t know there was a setting for that!