DEV Community

Hossain Khan
Hossain Khan

Posted on • Originally published at Medium on

Source code syntax highlighting on Android — Taking full control

Source code syntax highlighting on Android — Taking full control

Android and it’s community has evolved a lot over past decade. Now a days we can find open-source libraries to do almost anything — Zoomable ImageView, CameraX, RecyclerView Sticky Header, Tooltip, and many more.

Photo by Shahadat Rahman on Unsplash

Syntax highlighting is one of them and there are few libraries for that too. If this is a solved problem, then why am I writing about another solution then?

Well, some of the libraries I have explored are outdated, and some of them might not be as feature rich. So, I wanted to explore how to do-it-myself and write about it so that anybody can take full advantage of well-know JavaScript libraries for syntax highlighting in their Android app.

👍 Pros

  • Complete control over how JS plugin is used in the app
  • Complete control over the Android code that renders it using WebView

👎 Cons

  • You need to have some understanding of web technologies, namely HTML, CSS and JavaScript
  • You need to build your own Android CustomView or Fragment to render highlighted syntax. (No worries — this is where this article comes in to help you do that _🤗)_

With the pros and cons in mind, lets explore some well-established and proven syntax highlighting libraries

  • PrismJS — Very light weight 2KB-100+KB with extensive plugin collection “Lightweight, robust, elegant syntax highlighting.
  • highlight.js — Fully loaded 25KB-100KB and simple syntax highlighting “Syntax highlighting for the Web”
  • Rainbow — Another popular lightweight 6KB-25KB highlighter “Rainbow is a code syntax highlighting library written in Javascript.

There are many more libraries that does the job, however for rest of the example I will be using PrismJS because of it’s highly modular nature. Note that, the process of using different library will be almost the same.

💡 TIP: All the example code provided here is available in great detail in the GitHub repository mentioned below👇.

Setting up PrismJS Template

We will be leveraging Android’sWebView to load syntax highlighting library with the source code that we want to be highlighted.

This setup is going to be specific to library of your choice. Since we are focusing on PrimsJS, we will follow it’s official guideline.

After you download the library JS and CSS file, you essentially need following HTML to render the highlighted source.

<!DOCTYPE html>
<html>
  <head>
    <link href="themes/prism.css" rel="stylesheet" />
    <script src="prism.js"></script>
  </head>
  <body>
    <pre><code class="language-kotlin">
    data class Student(val name: String)
    </code></pre>
  </body>
</html>

TIP: You can download different CSS theme, and you can choose list of language and plugin you want to support (eg. Kotlin, Show line number)

Put the downloaded files in your Android app’s assets directory, ideally in www subfolder, like — src/main/assets/www/

Now that we have a baseline for the template, next part is to convert it to Kotlin function that can take additional parameter to customize different plugin options. Here is template with some additional data needed for mobile.

fun prismJsHtmlContent (
    formattedSourceCode: String,
    language: String,
    showLineNumbers: Boolean = true
): String {
    return """<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <link href="www/prism.css" rel="stylesheet"/>
    <script src="www/prism.js"></script>
</head>
<body>
<pre class="${if ( showLineNumbers ) "line-numbers" else ""}">
<code class="language-${language}">${formattedSourceCode}</code>
</pre>
</body>
</html>
"""
}

Defining Syntax Highlighting Custom-View

Making your own custom view is a great way to enhance capabilities. In this case we want to make our custom-view extend from WebView so that we can load the template we just defined with source code at runtime.

package your.app.code

class SyntaxHighlighterWebView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : WebView (context, attrs, defStyleAttr) {
    companion object {
        private const val ANDROID_ASSETS_PATH = "file:///android_asset/"
    }

  // Our exposed function to show highlighted syntax
  fun bindSyntaxHighlighter (
        formattedSourceCode: String,
        language: String,
        showLineNumbers: Boolean = false
    ) {
        settings.javaScriptEnabled = true

         loadDataWithBaseURL(
            ANDROID_ASSETS_PATH /* baseUrl */,
            prismJsHtmlContent (
               formattedSourceCode, 
               language, 
               showLineNumbers
            ) /* html-data */,
            "text/html" /* mimeType */,
            "utf-8" /* encoding */,
            "" /* failUrl */
        )
    }
}

Using the Custom-View in App

Now that we have our SyntaxHighlighterWebView custom-view with bindSyntaxHighlighter() function, we can use it from Activity or Fragment layout.

All we need to do is use the view in XML layout like following:

<your.app.code.SyntaxHighlighterWebView
  android:id="@+id/syntax_highlighter_webview"
  android:layout_width="match_parent"
  android:layout_height="match_parent" />

And from your Activity or Fragment get reference to the view and bind the source code like following

val highlighter: SyntaxHighlighterWebView = findViewById(R.id.syntax_highlighter_webview)

highlighter.bindSyntaxHighlighter(
   formattedSourceCode = "data class Student(val name: String)",
   language = "kotlin",
   showLineNumbers = true
)

Highlighted Syntax Loaded via SyntaxHighlighterWebView

That’s it, once you load the app you should see highlighted syntax on the screen where you have put the custom-view.

All the example source code provided here is available in following GitHub repository. As bonus, I have also provided example of how to use highlight.js too.

If you find any issue, leave a comment here or report an issue at GitHub repository. Hope it helps somebody. ✌️

amardeshbd/android-syntax-highlighter

Set of screenshots taken from the demo app

Top comments (0)