Building Impress.js presentations with your Android phone
Modifying Teddy Hyde to support Impress.js
First, did you know Teddy Hyde is now 100% open source? Get on GitHub.
What if you had an advanced code editor for your mobile device? One which offered editing right into your GitHub repository? An editor which offered intelligent support for Jekyll blogging and swipe to preview of markdown files, and which supported safe login using oAuth? An editor which was extremely extensible, either by using snippets of JSON (which modify the editor dynamically), or modifying the source code for the application itself? You do! Teddy Hyde gives you all these things.
Teddy Hyde has offered “Hyde Transforms” for a long time now: snippets of JSON embedded in your repository which extend this little editor for Android. Extensions look like extra menu items when you are in edit mode. If you wanted to have a shortcut for entering in YouTube embed code, Teddy Hyde could be extended to show a menu “Embed YouTube” which upon selection would then prompt you for the YouTube “short code” (the unique code you see at the end of each YouTube URL). After you enter this short code into the dialog, Teddy Hyde can then interpolate this value into a larger snippet of text, pasting in the entire embed code, perhaps even with an embed targetting mobile devices and another for desktop.
Teddy Hyde is a general purpose GitHub editor, but it is very effective in editing Jekyll blogs. This post will make a lot more sense if you have a Jekyll blog. And, you should understand the basics of layouts, which are wrapper files which a rendered around your markdown files.
Since Teddy Hyde is now open source, I wanted to take this opportunity to show how to build Impress.js presentations using Teddy Hyde using hyde transforms. To be clear, you could do this now using the existing hyde transforms. But, as of this writing, when you use JSON snippets to extend your editor, the extensions don’t have any sense of context. To be more clear, any menu item you add using “Hyde Transforms” is added regardless of the file type. The problem with this, of course, is that if you have more than a few extensions, your menu quickly gets crowded. What would be much better is to only show certain menu items when a file extension or template name matches. Specifically here, it would be great to only load extensions for Impress.js type files if the user were editing posts using a layout called “impress”. I’ll demonstrate how to do this in this post.
Here is how it looks in the editor. Notice the first file which uses the “post” layout does not have the hyde transforms menu item, but when we select a file which uses the “impress” layout, then the menu item is enabled.
Getting the source code and setting up your developer environment
First, get the source code. Then, make sure you have the Android tool chain installed and Java as well. I recommend installing Java from Oracle; Apple seems to be getting more and more hostile towards Java on OSX. You also need to install gradle: I found gradle 1.11 to work well with the current sources and gradle build files, but YMMV.
You’ll also need to add a local.properties file. This file specifies
the path to the Android SDK. I used
brew (a package manager for
OSX), so running cat to display my file looks gives me this:
bash-3.2$ cat local.properties sdk.dir=/usr/local/Cellar/android-sdk/22.2.1
Once everything is installed and setup run this command:
$ gradle assembleDebug
You’ll should see some status output indicating Gradle is downloading the necessary components from Maven, and then building the sources:
... Download http://repo1.maven.org/maven2/org/apache/commons/commons-lang3/3.2/commons-lang3-3.2.jar Download http://repo1.maven.org/maven2/com/squareup/retrofit/retrofit/1.3.0/retrofit-1.3.0.jar Download http://repo1.maven.org/maven2/com/squareup/picasso/picasso/2.1.1/picasso-2.1.1.jar Download http://repo1.maven.org/maven2/org/apache/httpcomponents/httpclient/4.0.1/httpclient-4.0.1.jar Download http://repo1.maven.org/maven2/org/apache/httpcomponents/httpcore/4.0.1/httpcore-4.0.1.jar WARNING: Dependency org.apache.httpcomponents:httpclient:4.0.1 is ignored for release as it may be conflicting with the internal version provided by Android. In case of problem, please repackage it with jarjar to change the class packages :TeddyHyde:compileDebugNdk :TeddyHyde:preBuild :TeddyHyde:preDebugBuild :TeddyHyde:checkDebugManifest :TeddyHyde:preReleaseBuild :TeddyHyde:prepareComAndroidSupportAppcompatV71901Library :TeddyHyde:prepareDebugDependencies :TeddyHyde:compileDebugAidl ... :TeddyHyde:packageDebug :TeddyHyde:assembleDebug BUILD SUCCESSFUL
Great, we can now edit to our heart’s content.
As we are proper developers, we create a feature branch on which to do our work, and then we start by adding a test case to prove that what we build works.
$ git checkout -b add_support_for_contextual_transforms
We’ll write a test based on our login.features test. This test will login, and then attempt to load the new hyde transformation file, verifying that the menu is enabled only when we use an “Impress.js” template.
Sigh. Again, this does not work. There is a bug with Calabash for Android which prevents jumping into console mode and which prevented me from completing these tests. Are you interested in helping to fix these tests?
You’ll want to put this inside the
_layouts directory in your Jekyll
And, then a sample Markdown file which has content for an impress.js presentation could look like this:
This will sit inside your
_posts directory (make sure to honor the
filename conventions of YYYY-mm-dd-title-with-spaces-converted-to-hyphens.md).
You can see the markdown uses HTML code which Impress.js uses to render the presentation and provide keyboard navigation and animations. But, this HTML is complicated to remember, and especially error prone if we were to add it using our mobile device. Let’s add “Hyde Transforms” to extend our editor and make this simpler.
We want Teddy Hyde to provide menus which allow us to insert the correct HTML into our presentation; it is not complicated to write Impress.js presentations, but typing in a bunch of HTML tags from our mobile phone keyboard is tedious. Using menu item macros we can quickly paste in the correct markup and then concentrate on the content inside each slide. Teddy Hyde already supports adding items to the menu using “Hyde Transforms.” What we don’t have is a way to selectively enable those menu items only when we are editing Impress.js files. How do we know it is an Impress.js file? Well, if we are editing Jekyll blogs, then each post or page should have a snippet of YAML (called YAML Front Matter, or YFM) which specifies the layout to use when rendering the file. If we assume that layouts called “impress” are for Impress.js presentations, then we could enable the menu items only when we see that file type. We don’t currently have a way to do this, so let’s add this to Teddy Hyde.
I am big proponent of writing tests. And, Teddy Hyde does not have the test coverage I want it to have. There are some tests in the TeddyHyde/tests/src/com/EditorHyde/app/ directory, but they don’t work. It was possible at one point to run them from the command line using a command like this:
javac -cp ./TeddyHyde/build/classes/debug:testing/lib/junit-4.11.jar:testing/lib/hamcrest-core-1.3.jar TeddyHyde/tests/src/com/EditorHyde/app/FormatterTest.java java -cp ./TeddyHyde/build/classes/debug:testing/lib/junit-4.11.jar:testing/lib/hamcrest-core-1.3.jar:TeddyHyde/tests/src org.junit.runner.JUnitCore com.EditorHyde.app.FormatterTest
They don’t work now. Are you interested in getting them working? Are you interested in getting them to work within gradle by writing an addition to the build.gradle file?
So, let’s drive blind and make these changes without writing working test coverage. We’ll still add tests to make sure we record the expectations of our changes.
Modifying the code
The way our Hyde transforms work is that we create a file inside any
Jekyll repository. This file should be located at the path
_hyde/transforms.json. If we have this file there, then once we load
up the repository, we load this file and convert them into
“transforms” which are menu items which insert some kind of textual
code. This is an example of a
These extensions add menu items when you are editing any file which will insert HTML code for a “colored image” (and prompts you for that color), or to insert a snippet of AngularJS code.
We want to make these extensions context sensitive, meaning, know when we are editing an Impress.JS presentation and only show those menu items then. Let’s say it will look like this:
So, we’ve added the context attribute, and we’ve bumped the version number. Let’s make some changes. We’ll need to change the MarkupUtilities.java file, the ScreenSlideActivity.java file, and the Transform.java file.
Explaining a little more about these files: the ScreenSlideActivity.java file is the code which builds out an editor for us: it shows the markdown file contents, has menu items for adding markdown, and has our “Hyde Transforms.” It also supports “swipe to preview” such that you can swipe to the right and generate HTML from your Markdown to see what it all looks like. The MarkupUtilities.java file is performs string manipulation on markdown files: things like retrieving the YAML Front Matter, stripping the YFM off, and processing the file for interpolated content. Finally, the Transform.java file is the class which encapsulates a transformation.
Basically, we’ll add some code which retrieves the template from the YAML Front Matter inside any markdown file, then compares that template against the tempate the transform uses (if available). If they are a match, then we enable the menu item. There is quite a bit of code here, so best to review it on GitHub
If we use
layout: "impress" in our template, and then have these transforms loaded,
we’ll only see that option listed. More importantly, hopefully this post shows you
how you can start modifying Teddy Hyde.
blog comments powered by Disqus