Markdown and Automation Experiments with 1Writer

In preparing my reviews of iOS 9 and the iPad Pro, I noticed that my writing process was being slowed down by the lack of multitasking support in my text editor of choice, Editorial. For the past couple of weeks, I’ve been trying to move some of my Editorial scripts and workflows to 1Writer, with interesting results and potential for the future.

I have written about Editorial at length on MacStories, and I still find Ole Zorn’s text editor to provide the most powerful combination of Markdown and plain text automation that’s ever been created on iOS. Over the years, I’ve put together hundreds of workflows thanks to Editorial’s visual actions and Python scripting; while some of them were made for fun and intellectual curiosity, the majority of them helped me save time when doing actual work for this website, Relay FM, and Club MacStories. There is no other app with the same feature set and rich Markdown support of Editorial.

Since iOS 9, however, I’ve been wondering whether part of Editorial’s automation could be taken somewhere else, possibly in another app that offered full integration with iOS 9 multitasking. I may have several workflows in Editorial, but I only use a tiny fraction of them on a daily basis for regular work on this website. I’d rather use a text editor that excels at a subset of Markdown workflows and integrates with iOS 9 than a single text editor with every imaginable workflow without proper iOS 9 integration.

It was this realization that pushed me to give 1Writer another look. I first bought the app years ago, but because I had no excuse to explore the world outside of Editorial, I didn’t try to recreate any workflows in it. This time around, I was motivated to rebuild the core of my setup in 1Writer, so I took a deep dive into the app’s automation engine.

Things will likely change again once Editorial supports iOS 9, but in the meantime I’ve developed an appreciation for 1Writer’s design and features that helped me understand the app better.

JavaScript Automation

Unlike Editorial, 1Writer doesn’t have a bookmarks bar to pin your most used workflows to the top, and, more importantly, it doesn’t come with its own Python interpreter or visual actions for text automation. Instead, 1Writer can be extended via JavaScript, which allows you to create custom actions based on JS’ standard features as well as objects exclusive to the app.

1Writer’s biggest advantage over other non-Editorial text editors, in fact, is the ability to access many of the app and editor’s functionalities with JavaScript. The app supports five custom JavaScript objects that you can intermix with regular JavaScript to automate Markdown and more:

editor – Interact with the text editor. This lets you get and set a document’s text, get ranges and selections, replace selections, and perform file operations.

app – This objects includes methods to interact with the app itself. There isn’t a lot of choice here compared to Editorial or Pythonista, but you can launch URLs, get and set the clipboard, and see if a script is being activated from the app’s extension.

ui – Automated user interaction. Again, not as full-featured as the crazy custom interfaces of Editorial, but you can show alerts programmatically, display success and error messages, bring up input fields to enter text, and even display lists of multiple items with associated functions.

http – Perform HTTP requests, including GET and POST requests.

webBrowser – This object allows you to interact with the app’s built-in web browser, which doesn’t have tabs like Editorial’s browser and isn’t based on the new Safari View Controller web views of iOS 9. You can also show HTML code in the browser.

Editing JavaScript code for custom action is a task better done in Coda 2.

Because they’re based on standard JavaScript, these objects and methods can be used in conjunction with regular JS. For instance, 1Writer doesn’t provide its own methods for regular expressions, but you can use traditional RegExp objects with, say, text passed by the app’s editor object, which communicates directly with the text editing interface. For more details, you can check out 1Writer’s online documentation.

1Writer lacks the breadth of Editorial’s visual workflow building and custom integrations through Python. I can’t access the native Twitter and keychain features of iOS with 1Writer, and the app’s JavaScript doesn’t bring the same level of access to the text editor that is available in Ole Zorn’s Python-based apps.

For my more advanced Markdown and web automation, I believe I’ll always end up using Editorial; not even Workflow gets close to the possibilities opened by Python and text manipulation of Editorial.

But, with its JavaScript actions and limited custom objects, 1Writer can replicate my essential Markdown workflows that I use on a daily basis, with an important difference. By being able to use 1Writer alongside other apps with Split View on iOS 9, I’m finding myself depending on fewer workflows. Using two apps at the same time has enabled me to cut down the number of steps required to reduce time spent editing, researching material, or publishing articles to WordPress.

Below, I’ve put together a collection of Editorial workflows I’ve recreated with JavaScript in 1Writer. These are the workflows that let me quickly edit and post items to MacStories1 every day, and they’re the ones I absolutely need to have in an automated fashion in my text editor. Without these tools, I would go insane trying to perform the same actions manually every time. You’ll also find some observations about 1Writer when using the actions in practice, notes on built-in features, and my plan for the future of working with Markdown on my iPhone and iPad.

Adding and Reopening Markdown Links

In every post I publish on MacStories, there’s at least one link that points readers somewhere else. I prefer inline Markdown links over reference-style ones as I like to see the URL I’m linking to while I’m reading a paragraph, and I find the hyperlink to be one of the greatest inventions of the open web. I link profusely whenever possible.

For two years, I’ve relied on an Editorial workflow that makes text selected in the editor an inline link based on the webpage that is active in the in-app browser. I have used that workflow thousands of times and it has saved me hours I would have spent manually typing the link syntax in a document each time. You can download it here if you want.

1Writer has a built-in web browser, but it’s not as good as Editorial’s. As I mentioned above, it doesn’t have multiple tabs, but it also can’t assign actions as bookmarks to run on the current webpage, and it can’t execute JavaScript on the contents of a webpage (so you could, for example, access text that is selected in the 1Writer browser and convert it from HTML to Markdown). However, despite its shortcomings, I haven’t found myself using 1Writer’s browser at all: if I have to look at a browser and a text editor concurrently, I can now put Safari and 1Writer in Split View.

Copying a URL from Safari and making it an inline link in 1Writer.

After years of writing in Editorial and swiping back and forth between the text editor and the built-in browser, adjusting to a shared browser-editor setup required some change in habits on my end. I’m still learning to remember that I have this ability thanks to iOS 9; the iPad Pro is facilitating this change with its superior multitasking experience. 1Writer and Safari running simultaneously on my iPad haven’t only allowed me to more easily reference web material when writing – they also offer an easier way to add inline links.

On iOS 9, 1Writer features a series of buttons in the iPad’s Shortcut Bar that let you perform actions in the text editor. One of these is a Link button that can add a link at the insertion point in a document or transform selected text in a Markdown link.

By default, tapping the Link button offers two choices: you can type a link’s text and URL manually, or you can link to another document in 1Writer. If you’ve already copied a link, though, 1Writer will display a third option to add a link from your clipboard, which is ideal for text selections.

When I’m editing a piece in 1Writer2, I can invoke Safari, put the two apps in Split View, and, as I go through my edits, copy a link in Safari, select some text in 1Writer, tap the link icon, and have a link ready in the document. This takes a second, and it benefits from the new shortcut to copy URLs in iOS 9: just tap & hold the address bar in Safari to show a Copy button.

The ability to view a browser next to a Markdown document is useful for obvious reasons, and 1Writer’s ‘From Clipboard’ link option works well with Safari. I can see future MacStories reviews and articles benefitting from a way to pin Safari next to the text editor.

After I’m done editing and adding links, it’s not uncommon for me to double check a link I’ve inserted in the document to make sure it is the best link I can use. In Editorial, I’ve built a workflow that finds all URLs for the current line and displays them in a list for me to open in the browser. Unfortunately, 1Writer doesn’t have a drop-in action like Editorial’s Extract URLs, which meant that I needed to write my own JavaScript to filter links contained in the current line (a paragraph of a document).

I didn’t want to use someone else’s regular expression to match URLs in a string of text, so I decided to write my own to match the inline Markdown link syntax for normal URLs as well as image URLs. It was a good exercise to learn a bit of JavaScript; plus, I had fun debugging the script in Coda and building a flexible regex for any occasion.

The result is Reopen Link, a custom JavaScript action that scans the current line (doesn’t have to be selected) for inline links and that lets you pick one to reopen its URL in Safari. It works best for paragraphs heavy in inline links so you don’t have to carefully select them, and it’s a joy to use in Split View. You can download it here.

The action works by grabbing the entire text of the line where the cursor is, scanning it for matches to the regex I created, and displaying results in a list. An error message is displayed if no links are found. The regular expression is designed to match Markdown image links and inline links, with and without alt attributes or link titles. Different parts of a link are captured with groups, but this action only uses the second group to collect URLs and list them. Feel free to modify everything and do something else with capturing groups.

This action solves an annoying problem for me: I don’t like selecting URLs with the native iOS selection controls, and 1Writer doesn’t have built-in methods to extract URLs from the current line. It took a bit of work, but I’m happy with the results. When I’m editing a post, I can bring up the action sheet, tap Reopen, and I’m presented with a list of links so I can choose one and send it back to Safari on the other side of the screen.

Launching Actions

A note on launching actions in 1Writer: the app doesn’t have a bookmarks bar on top of the editor, and the only way to view actions is through a modal popup that lists custom actions below default ones such as Copy and Open In.

Running actions in 1Writer.

It’s not the fastest way to launch actions that are supposed to save you time, and I think they should be more prominent in the UI. Thankfully, you can trigger the Actions popup from the Shortcut Bar3 (share icon) or from the copy & paste menu of iOS. I’d like to see 1Writer get the ability to pin individual actions to the Shortcut Bar, assign keyboard shortcuts to them, or maybe even pin actions to the sides of a document (there’s plenty of space on the iPad Pro).

Images and Lists

In Editorial, I had to create my own workflows to insert a Markdown image link and turn selected lines into an unordered list. In 1Writer, both features are available by default with buttons in the Shortcut Bar (or the extended keyboard row if you prefer to use that one). The list button does what you expect – if I had to nitpick, I’d like the app to use asterisks instead of dashes for unordered lists, but I’m not here to argue about our favorite flavors of Markdown.

For images, 1Writer lets you either take or add photos from your library, or enter a link. If you pick an image, it gets uploaded to one of the app’s supported services (Dropbox, CloudApp, Evernote, and Droplr) and its public link is inserted in the document. If you already have an image URL, the syntax for a Markdown image link is entered in the document so you can type any possible alt text and paste your link.

The built-in shortcut for image links works, but I’m probably going to write my own action for inserting links. I don’t like having to paste links manually inside parentheses, and writing JavaScript to replicate my Editorial workflow for this task should be easy.

It would be nice if 1Writer supported more blogging-focused upload services for media such as Rackspace Cloud Files (what I use) and Amazon S3. External integrations (not just for publishing, but to generate image URLs) would definitely make for an IAP I’d buy in a heartbeat.

Linked Posts with Blockquotes

This workflow isn’t strictly related to 1Writer, and it’s been customized for my specific needs, but I thought it could still be useful for some people.

When I create linked posts for the site, I want to be able to select some text in the browser and generate a text file with a quoted selection and the original webpage’s title as the file name. Because 1Writer doesn’t let me access the contents of a webpage programmatically, I created a workflow that uses Pythonista and Workflow in Safari4 to create the template file I want when I need to prepare a linked post.

Making progress on new iPad blogging workflow based on Split View for linked posts (1Writer, Workflow, Pythonista) pic.twitter.com/Hme8LHHncB

— Federico Viticci (@viticci) November 14, 2015

You can find the workflow here, and the Pythonista script on GitHub. As I showed on Twitter a few days ago, the workflow is meant to be used in Split View with Safari next to 1Writer. Here’s what it does:

Gets selected text from Safari;

The Workflow extension passes the HTML version of selected text to Pythonista;

Pythonista converts HTML to Markdown using html2text;

The Split View layout is restored with Safari and 1Writer;

A new file is automatically created in 1Writer, using the title of the webpage as file name and a blockquote of Safari’s selection in the body text.

Note: If the original webpage is a relay.fm URL, Workflow reformats the content to the style I prefer. This is just for me and it’s designed for how I like to link to podcast episodes on MacStories. You can delete the conditional block because you likely won’t need it.

The original article I want to link to (left) and the automated, converted draft (right).

You may be wondering why involving Pythonista at all when the Workflow extension can return HTML for selections in Safari or pass plain text to 1Writer via a URL scheme. The reason is that I like to keep formatting of an original article intact when I link to it on MacStories (that includes text styles and hyperlinks), and I try to avoid HTML mixed with Markdown as much as possible. I want the file behind each linked post to be completely in Markdown and I don’t want to lose any formatting the original author included in their post. The only way to do this automatically is to use both Pythonista and Workflow. If Workflow added support for html2text in an action, I could avoid using a Python script.

With this setup, I can work with Safari and 1Writer simultaneously, creating dynamic templates for linked posts in two seconds when I want to link to a webpage on MacStories. However, there’s also another way to capture webpage information and convert it to Markdown with 1Writer.

1Writer has a powerful share extension that, if used in Safari, can create a new file prefilled with a Markdown version of text selected in the browser. The share extension’s template is customizable: by combining placeholders for the webpage title, URL, and selected text with any arbitrary plain text (Settings > Share Extension > Template), you can set up the extension to create files for content captured in Safari.

And here’s the best part: after capturing text with the share extension but before saving its contents to the main app, you can execute JavaScript actions in the extension’s editor. Using the same objects and methods available to app actions (with some limitations), you can create actions to automate some parts of the text editor from the extension – you can even create actions that only execute if the app is running in the extension.5

Capturing content with the 1Writer share extension from Safari (left).

To demonstrate this, I created a New Linked action that reformats content captured from the 1Writer extension. The original selection from Safari is automatically converted to Markdown by the extension, and I chose to set the extension’s template to include a Markdown blockquote and an inline link for the current webpage at the top of the document.

The inline link is a trick to work around the extension template’s inability to set a custom name for a file created by the extension. I would like the 1Writer extension to use a webpage’s title as the file name whenever I capture content from Safari, but there’s no such option in the Settings – the app uses a timestamp instead.

To circumvent this limitation, I insert an inline link as the first line of the file, manually copy and paste the title in the title bar or rename the new file, then use the same regular expression I created to reopen links (see how capturing groups did come in handy?) to remove the first line from the file and set the iOS clipboard to the URL of the webpage. This way, I can save a linked post template from Safari to 1Writer, open the app, and add the link somewhere in the document with the Link button of the Shortcut Bar.

The ability to convert Markdown, customize templates, and run JavaScript actions in the 1Writer extension is great, and I bet that lots of users will use it as their primary way to create files based on something they found in Safari. For me, limitations of template settings, JavaScript, and the extension itself make the process less ideal than my Workflow/Pythonista setup. I can’t set a custom name for a new file beforehand, there’s no method to rename a file created by extension before saving it, you can’t launch URLs via JavaScript in the extension, and if you run the extension alongside 1Writer itself in Split View, the app won’t update the file list to show you the file created by the extension.6

For now, I’m going to keep using Workflow and Pythonista to create linked posts in 1Writer with Markdown automation. But, if you don’t need automation or use MultiMarkdown tags at the top of the file to set document metadata, the extension is fantastic, and its ability to customize the template and run JavaScript outside of the host app is genius. I’d love to see a bit more flexibility in the 1Writer extension. If that happens, I won’t have to use separate workflows for linked posts anymore.

You can download my New Linked action here.

Jump to Section

One of my favorite details of Editorial is a menu to quickly navigate to Markdown sections inside a document. By tapping on a file’s name in the title bar, Editorial opens a list of all Markdown headers found in the current file. Sadly, this isn’t possible in 1Writer, which slows me down when I have to jump across sections in long documents.

Fortunately, Phillip Gruneich has come up with an action that scans the document for headers, shows them in a list, and lets you tap one to jump to it. It’s not as fast to activate as Editorial’s title bar popup, but it gets the job done.

You can download Phillip’s action here.

Adding App Store Links

Also from Phillip, I adapted an action to generate and insert affiliate links for App Store content to fit my needs a little better.

When I have to link to an app from the Store, I can run this action to look up an app on the iTunes API and get a Markdown link with the affiliate URL into the document. Everything happens behind the scenes and all you have to do is select the type of app you need to find (iPhone, iPad, or Mac) and pick it from a list of results. 1Writer developer Ngoc Luu himself did all the work on the iTunes API code, which works very well.

The only parameters you have to change in the action are the affiliate token and the campaign tracking code, which I put right at the top as two variables.

I modified the action to work if some text is selected in the editor. If I select the name of an app I want to link to in my document, I don’t want to type the app’s name again when searching for its link; in my action, 1Writer displays a text field prefilled with the selected app name. If everything looks good, you can just tap Continue7 and the action will look up the app’s name for you. If you’re adding a link for selected text that isn’t an app’s name, you can delete the prefilled text with one tap and type it manually. If nothing is selected, the action creates an inline link with no anchor text. It works either way.

I could probably update the action to display a list for multiple campaign tracking codes, but one step at a time. For now, this action allows me to enter affiliate links for apps easily while I’m writing, and I managed to replicate an entire Editorial workflow in JavaScript.

You can download the action here.

Footnotes

MacStories readers know that I have a particular affection for footnotes, as I’m proud of the way we designed the footnote popover to behave with the redesign of our website last year.

When I have to add a footnote to an article, I use an Editorial workflow that asks me for a footnote label and some text, and which then takes care of scrolling to the bottom of the document, inserting the footnote, and scrolling back to where I was, pasting the footnote anchor. All this is done automatically, and I couldn’t work with my text editor in any other way at this point. Manual insertion is not an option.

It’s always about Myke.

I recreated my Editorial footnote workflow from scratch with JavaScript in 1Writer, keeping the same set of conditions and variables. Once triggered, the action asks for a footnote label, and if already being used in the document’s text, it stops with an error that tell you to pick a different label. If the footnote label isn’t in use by another footnote, the action lets you type some text (alas, no multiline text fields in 1Writer’s custom interfaces) and everything is inserted at the very bottom of the document. You can download the action here.

Seeing what a footnote is about without scrolling to it.

I also created an action that shows the footnote’s text if you don’t remember what it is about anymore and you’re too lazy to scroll. Unfortunately, 1Writer’s editor object doesn’t provide a way to select the closest word to the cursor like in Editorial, so you’ll have to manually select a footnote label before running the action. I’ll have to update this action to include a proper error message if results aren’t found.

You can download my Find Footnote action here.

1Writer’s Potential

1Writer is far from the power and customization of Editorial. Ole Zorn’s app is the undisputed king of Markdown automation on iOS, and nothing gets close to it. But, I found 1Writer to be a capable replacement for most of my daily Markdown needs, and the app has been updated to work on iOS 9 and the iPad Pro.

There’s a lot of room for improvement in 1Writer’s text editing features and JavaScript actions. In addition to expanding the automation engine with deeper access to the editor and the extension, 1Writer’s developer should consider find and replace support in the text editor, navigation for headers inside a document, and support for snippets and keyboard shortcuts to launch actions. The Shortcut Bar could be extended to host user-defined actions, and the built-in web browser could take advantage of more memory in the latest iOS devices for multiple tabs.

As far as making the app a sustainable business goes, I would explore the idea of charging users for additional integrations for uploads and publishing, and maybe make more specific JavaScript objects – such as actions to run upon exporting a file – or an in-app JavaScript editor with syntax highlighting and autocomplete – available as an optional premium. There is money to be made from pro users who find an app that meets their needs and want more from it.

1Writer has potential, and it surprised me because I didn’t expect to be able to recreate most of my Markdown automation in it. I don’t know if I’ll switch back to Editorial once it gets updated with iOS 9 integration and even more workflows, but I’ll keep using 1Writer for now. It’s a solid text editor with nice little touches that I haven’t mentioned in this article, and it’s on the right track to offer a versatile alternative to Editorial for Markdown power users.

1Writer is available on the App Store.

I’ve been using a beta Workflow action to post Markdown to WordPress. Hopefully, it’ll be released soon. ↩

By the way, I deactivated the app’s extra keyboard row and automatic full-screen mode. With the Shortcut Bar (and also with the large keyboard of the iPad Pro), I have essential shortcuts and keys right at my fingertips; I find full-screen mode mostly annoying as it hides the title bar, preventing me from quickly opening the sidebar to see all my documents. Both options can be turned off in the Settings. ↩

If the keyboard is hidden, you can tap a ‘More’ button in the bottom left corner of the editor. ↩

And in iOS 9.2, Safari View Controller too, which has been updated to provide webpage content to action extensions. ↩

There is a condition to test whether the editor has been activated from the extension and not from the full app. ↩

You’ll have to close and reopen the app for the file to show up (or exit Split View). ↩

Unfortunately, pressing Return in the text fields of custom UIs in 1Writer doesn’t map to ‘Continue’ in the popup, but it adds a new line in the editor. This should be fixed. ↩