Workflow for Publishing Blogs From iPad using Bear and Hugo
Ever since I bought myself an iPad mini, I wanted to use it more and more trying my hardest to justify the purchase. But that is not to say it is a bad device or anything, but I could just blog normally using my laptop. But… that’s just not as interesting. So here is a slightly contrived way to blog directly from iPad using the Bear app, a toy server and Github pages.
TL;DR
I use Bear app for iPadOS for writing the blog in markdown and export the “Textbundle” file to a Linode box using ssh (more on this later) and then parse and clean the Textbundle file and push static files to Github. I host the website using Github pages. Do let me know if you want me to automate this full process and provide it as a clean service.
Oh and b.t.w, I used this method to publish this blog!
Alternatives
If I had to use my iPad for blogging, I found these alternatives during my research
- Ulysses: Looked like this app was more serious and was equally pricey too. It does support direct publishing to many platforms like Ghost, Medium and Wordpress. I didn’t choose this for the price.
- Evernote: I didn’t explore this option fully but I didn’t like the look of the app as much as I liked Bear.
- Blogging platform apps like Wordpress for iOS: I really wanted markdown and from my experience, ̇Wordpress is really clunky so I didn’t go for this
- Bear app but with direct Wordpress publishing: This would have been alright but unfortunately the pre-formatted code didn’t render properly for me
I do concede that this method is slightly more complicated but it gives you maximum flexibility but with some initial fixed costs.
The procedure
These are the (almost) complete steps I took for publishing directly from iPad
Shortcuts app and SSH
The Bear app is amazing in that it can export to the Textbundle format. Which is essentially a markdown file bundled with the assets. Next, I needed to use this file and do some parsing.
It took me a while to realise this but you can actually create a shortcut in the shortcuts app that accepts a file and then transfer it to your server.
The file is provided through stdin
so just do cat /dev/stdin > /filename.extension
.
So I got the cheapest box from Linode and tested this shortcut. Once you have created this shortcut, it will appear in the export
section in Bear app (under three dots).
.
Parsing Textbundle
I would have really loved some out of the box textbundle support for blogging but unfortunately I could not find any. So I decided to write some trivial Python code to split the Textbundle file into the Markdown and Assets folders for use in Hugo.
The media urls in the markdown from the textbundle file are relative to the assets
folder. Hugo needs all these assets folders to be in one static
folder. After moving the assets
folder to static
we need to update the urls in the markdown file as well. This function will look for urls and insert the replaceUrl
in it.
For more clarity: we need to replace 
with 
. I cook up a new replacedUrl for each blog.
We need to be careful with the regex though, we have to do it line by line else the regex breaks. I don’t know why, perhaps something to do with the word “greedy”, I need to read up on regexes :(
def replaceUrlPaths(directory, replaceUrl):
with open(directory, "r") as f1:
replaced_lines = []
for line in f1.readlines():
subbed = re.sub(r'(?:\[(.*?)\]\((.*?)\))', r"[\1](/1606729577//{}/\2)".format(replaceUrl), line)
replaced_lines.append(subbed)
return replaced_lines
These replaced lines now have the proper url. We now have to write these lines in the content/posts
directory of the Hugo site.
To use the tagging metadata in the markdown file and to populate the “front matter” for the Hugo markdown file, I used this method
def createNewHugoPost(replaced_lines, dir_, post_name):
#I make sure to put tags always in the second line
tags = replaced_lines[1].split(' ')
tags = '[' + ','.join(['"' + tag.strip().strip("#") + '"' for tag in tags]) + ']'
with open(dir_, "w") as f:
#front matter stuff
f.write("---\n")
f.write('title: "{}"\n'.format(post_name))
f.write('date: {}\n'.format(str(datetime.datetime.now())))
f.write('tags: {}\n'.format(tags))
f.write('draft: false\n')
f.write("---\n")
f.writelines(replaced_lines[2:])
print("wrote lines to " + dir_)
return post_name
I know there’s probably a better way to do this, but I just couldn’t find it. This works well enough though.
I also wrote code to move the assets
folder into the static
folder for Hugo and some trivial git commit
and git push
for Github static pages, but I’ll omit it for brevity.
That’s it!
Just press the shortcut (“bear test” for me, we are still in development phase after all!) and we are done!
Improvements
This experiment could work without renting a server but I really wanted the root terminal access for experimenting and exploring. I’ll figure out how to use Github actions in the future and maybe update this post. Could save a few bucks through this. Nevertheless, a toy server can come to use sometime, who knows!