How to export from Ulysses to Markdown

emma

Emma Goto πŸ™

Posted on September 26, 2021

How to export from Ulysses to Markdown

I use the Ulysses text editor to write all my posts. Converting them into Markdown files for my blog isn’t as easy as copy-pasting, especially when things like frontmatter and images are involved.

So here's the script I use to convert Ulysses files to Markdown.

  1. Right click a sheet in Ulysses and choose the Quick Export option. Choose the Textbundle format.
  2. Save the Textbundle folder to your desired location. I save it inside the scripts folder of my repository.
  3. Then run the following script to convert the Ulysses file to Markdown.
#!/usr/bin/env node

const { renameSync, unlink, rmdir } = require('fs');
const { join } = require('path');
const glob = require('glob');
const replace = require('replace-in-file');

const toFrontMatter = (title) =>
    `---
title: "${title}"
date: ${new Date().toISOString().substring(0, 10)}
tags: []
---`;

const ulysses = async () => {
    const file = glob.sync(
        join(process.cwd(), 'scripts', '**', '*.textbundle'),
    )[0];

    // Moves the .textbundle file to the /posts directory
    const slug = file.match(/\/([^\/]+).textbundle/)[1];
    const postsDirectory = join(process.cwd(), 'posts');
    let newFolder = `${postsDirectory}/${slug}`;
    renameSync(file, newFolder);

    // Move images out of assets folder
    const images = glob.sync(join(newFolder, 'assets', '*'));
    images.forEach((image) => {
        let imageName = image.match(/assets\/([^\/]+)/)[1];
        const newFolder = `${postsDirectory}/${slug}`;

        renameSync(image, `${newFolder}/${imageName}`);
    });

    // Remove redundant folder and files
    rmdir(`${newFolder}/assets`, () => {});
    unlink(`${newFolder}/info.json`, () => {});

    // Formats into frontmatter structure
    const headerRegex = /^# .*/g;
    const markdownPngRegex = /!\[.*\]\(assets.*png\)/g;

    const headerFn = (title) =>
        toFrontMatter(title.replace('# ', '').trim());
    const markdownPngFn = (line) => line.replace(/\(assets/, '(.');

    const options = {
        files: `${newFolder}/index.mdx`,
        from: [headerRegex, markdownPngRegex],
        to: [headerFn, markdownPngFn],
    };

    return replace(options);
};

ulysess();
Enter fullscreen mode Exit fullscreen mode

You can run the script directly with:

node ./scripts/ulysses.js
Enter fullscreen mode Exit fullscreen mode

Or you can add the script to your package.json file:

"scripts": {
    "uly": "./scripts/ulysses.js",
},
Enter fullscreen mode Exit fullscreen mode

And then run it with yarn uly.

How the Ulysses to Markdown script works

Exporting a Ulysses file as a Textbundle saves it with the following file structure:

scripts
    ulysses-to-markdown.textbundle
        info.json
        text.md
        assets
            image.png
Enter fullscreen mode Exit fullscreen mode

The script will rearrange it to look like this:

posts
    ulysses-to-markdown
        text.md
        image.png
Enter fullscreen mode Exit fullscreen mode

The original Markdown file, directly from Ulysses, will look like this:

# How to export from Ulysses to Markdown

Here's the content of the post. 

![](assets/image.png)
Enter fullscreen mode Exit fullscreen mode

And the script will convert it into this format:

---
title: "How to export from Ulysses to Markdown"
date: 2021-09-25
tags: []
---
Here's the content of the post. 

![](./image.png)
Enter fullscreen mode Exit fullscreen mode
πŸ’– πŸ’ͺ πŸ™… 🚩
emma
Emma Goto πŸ™

Posted on September 26, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

How to export from Ulysses to Markdown
ulysses How to export from Ulysses to Markdown

September 26, 2021