diff --git a/.gitignore b/.gitignore index a086e7d..6b82f59 100644 --- a/.gitignore +++ b/.gitignore @@ -84,3 +84,5 @@ lint/outputs/ lint/tmp/ # lint/reports/ .DS_Store +*.salive +.idea/ diff --git a/.idea/.name b/.idea/.name deleted file mode 100644 index 5fa2316..0000000 --- a/.idea/.name +++ /dev/null @@ -1 +0,0 @@ -Syntax Highlighter \ No newline at end of file diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml deleted file mode 100644 index e6010f2..0000000 --- a/.idea/codeStyles/Project.xml +++ /dev/null @@ -1,123 +0,0 @@ - - - - - - - - - -
- - - - xmlns:android - - ^$ - - - -
-
- - - - xmlns:.* - - ^$ - - - BY_NAME - -
-
- - - - .*:id - - http://schemas.android.com/apk/res/android - - - -
-
- - - - .*:name - - http://schemas.android.com/apk/res/android - - - -
-
- - - - name - - ^$ - - - -
-
- - - - style - - ^$ - - - -
-
- - - - .* - - ^$ - - - BY_NAME - -
-
- - - - .* - - http://schemas.android.com/apk/res/android - - - ANDROID_ATTRIBUTE_ORDER - -
-
- - - - .* - - .* - - - BY_NAME - -
-
-
-
- - -
-
\ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml deleted file mode 100644 index 79ee123..0000000 --- a/.idea/codeStyles/codeStyleConfig.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/compiler.xml b/.idea/compiler.xml deleted file mode 100644 index b589d56..0000000 --- a/.idea/compiler.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml deleted file mode 100644 index e73ee34..0000000 --- a/.idea/deploymentTargetDropDown.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml deleted file mode 100644 index a5f05cd..0000000 --- a/.idea/jarRepositories.xml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml deleted file mode 100644 index 8d81632..0000000 --- a/.idea/kotlinc.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - \ No newline at end of file diff --git a/.idea/migrations.xml b/.idea/migrations.xml deleted file mode 100644 index f8051a6..0000000 --- a/.idea/migrations.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml deleted file mode 100644 index 8978d23..0000000 --- a/.idea/misc.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/README.md b/README.md index bd94ef0..10262bd 100644 --- a/README.md +++ b/README.md @@ -5,6 +5,8 @@ yet _NOT_ another android syntax highlighter (YNAASH) Explore well established web based syntax highlighter like [PrismJS](https://prismjs.com/) and [highlight.js](https://highlightjs.org/), and showcase how anybody can quickly incorporate these into their project by following some examples provided here. +This project provides examples for **Android Legacy Views**, **Fragments**, and **Jetpack Compose** implementations. + > The intention is **NOT** to create another library project that gets abandoned over time. Feel free to copy parts of code that is necessary for you to add syntax highlighting support to your app. @@ -38,7 +40,7 @@ If you need a library, you may look into following existing projects - [2. Use HTML+CSS+JS Asset](#2-use-htmlcssjs-asset) - [3. Load the static HTML on `WebView`](#3-load-the-static-html-on-webview) - [Example App Screenshots](#screenshot) -- [Building your own Fragment or Custom View](#building-your-own-fragment-or-custom-view) +- [Building your own Fragment, Custom View, or Composable](#building-your-own-fragment-custom-view-or-composable) - [Custom View](#custom-view) - [PrismJS Template Function](#prismjs-template-function) - [Creating custom syntax highlighter WebView](#creating-custom-syntax-highlighter-webview) @@ -46,6 +48,9 @@ If you need a library, you may look into following existing projects - [Fragment](#fragment) - [Create custom Syntax Highlighter Fragment](#create-custom-syntax-highlighter-fragment) - [Using the Syntax Highlighter Fragment](#using-the-syntax-highlighter-fragment) + - [Jetpack Compose](#jetpack-compose) + - [SyntaxHighlighter Composable](#syntaxhighlighter-composable) + - [Using the SyntaxHighlighter Composable](#using-the-syntaxhighlighter-composable) ## Under the hood Here is how you would have syntax highlighting using any modern JavaScript library. @@ -104,7 +109,7 @@ Here is a screenshot taken from a demo static html page that has syntax highligh | ![device-2020-07-18-092715](https://user-images.githubusercontent.com/99822/87853541-fc52d700-c8d8-11ea-9dc6-2d4c624f3b74.png) | ![device-2020-07-18-092727](https://user-images.githubusercontent.com/99822/87853542-fceb6d80-c8d8-11ea-9641-4ecf927b5a01.png) | ![device-2020-07-18-092736](https://user-images.githubusercontent.com/99822/87853543-fe1c9a80-c8d8-11ea-9e11-c9779202368e.png) | | --- | --- | --- | -## Building your own Fragment or Custom View +## Building your own Fragment, Custom View, or Composable Ideally, there should be a modular component or custom-view that you **re-use** syntax highlighting with dynamic content. For that having a `Fragment` or custom `View` is ideal. @@ -277,3 +282,93 @@ val fragment = SyntaxHighlighterFragment.newInstance( > See [PrismJsDemoActivity.kt](https://github.com/hossain-khan/android-syntax-highlighter/blob/main/example/src/main/java/dev/hossain/ynaash/example/ui/demoprismjs/PrismJsDemoActivity.kt) > source code for full example. + +## Jetpack Compose +Jetpack Compose support is available for modern Android development. The `SyntaxHighlighter` composable provides a Compose-friendly way to display syntax highlighted code by wrapping the proven WebView-based implementation. + +### SyntaxHighlighter Composable +The `SyntaxHighlighter` composable leverages `AndroidView` to integrate the existing `SyntaxHighlighterWebView` into Compose UI. This approach maintains compatibility with the established PrismJS functionality while providing a modern Compose interface. + +```kotlin +@Composable +fun SyntaxHighlighter( + sourceCode: String, + language: String, + showLineNumbers: Boolean = false, + modifier: Modifier = Modifier +) { + AndroidView( + modifier = modifier, + factory = { context -> + SyntaxHighlighterWebView(context).apply { + bindSyntaxHighlighter( + formattedSourceCode = sourceCode, + language = language, + showLineNumbers = showLineNumbers + ) + } + }, + update = { webView -> + webView.bindSyntaxHighlighter( + formattedSourceCode = sourceCode, + language = language, + showLineNumbers = showLineNumbers + ) + } + ) +} +``` + +> See [SyntaxHighlighterComposable.kt](https://github.com/hossain-khan/android-syntax-highlighter/blob/main/highlighter/src/main/java/dev/hossain/ynaash/compose/SyntaxHighlighterComposable.kt) +> for the complete implementation. + +### Using the SyntaxHighlighter Composable +From your Compose UI, you can use the `SyntaxHighlighter` composable directly in your layouts: + +```kotlin +@Composable +fun MyScreen() { + Column { + Text("Code Example") + + Card( + modifier = Modifier + .fillMaxWidth() + .height(300.dp) + ) { + SyntaxHighlighter( + sourceCode = "data class Student(val name: String, val age: Int)", + language = "kotlin", + showLineNumbers = true, + modifier = Modifier.fillMaxSize() + ) + } + } +} +``` + +**Dependencies required for Compose support:** + +Add the following to your module's `build.gradle`: + +```kotlin +android { + buildFeatures { + compose true + } + composeOptions { + kotlinCompilerExtensionVersion '1.5.15' + } +} + +dependencies { + implementation platform('androidx.compose:compose-bom:2024.12.01') + implementation 'androidx.compose.ui:ui' + implementation 'androidx.compose.ui:ui-tooling-preview' + implementation 'androidx.compose.material3:material3' + implementation 'androidx.activity:activity-compose:1.9.3' +} +``` + +> See [PrismJsComposeDemoActivity.kt](https://github.com/hossain-khan/android-syntax-highlighter/blob/main/example/src/main/java/dev/hossain/ynaash/example/ui/demoprismjs/PrismJsComposeDemoActivity.kt) +> for a complete working example. diff --git a/build.gradle b/build.gradle index 7c43e03..b03e75a 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:8.7.2' + classpath 'com.android.tools.build:gradle:8.5.2' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" // NOTE: Do not place your application dependencies here; they belong @@ -47,6 +47,11 @@ ext { // https://developer.android.com/jetpack/androidx/releases/lifecycle archComponentVersion = '2.8.7' + // Jetpack Compose dependencies + // -------------------------------------------------- + // https://developer.android.com/jetpack/compose/bom + composeBomVersion = '2024.12.01' + composeCompilerVersion = '1.5.15' // Unit test dependencies // -------------------------------------------------- diff --git a/example/build.gradle b/example/build.gradle index 17c0740..88ddf66 100644 --- a/example/build.gradle +++ b/example/build.gradle @@ -1,6 +1,7 @@ plugins { id 'com.android.application' id 'kotlin-android' + id("org.jetbrains.kotlin.plugin.compose") version "2.0.21" } android { @@ -9,6 +10,11 @@ android { buildFeatures { viewBinding true buildConfig true + compose true + } + + composeOptions { + kotlinCompilerExtensionVersion rootProject.ext.composeCompilerVersion } defaultConfig { @@ -56,6 +62,13 @@ dependencies { // - https://developer.android.com/jetpack/androidx/releases/recyclerview implementation "androidx.recyclerview:recyclerview:1.3.2" + // Jetpack Compose BOM + implementation platform("androidx.compose:compose-bom:${rootProject.ext.composeBomVersion}") + implementation 'androidx.compose.ui:ui' + implementation 'androidx.compose.ui:ui-tooling-preview' + implementation 'androidx.compose.material3:material3' + implementation 'androidx.activity:activity-compose:1.9.3' + // Timber for logging implementation "com.jakewharton.timber:timber:5.0.1" diff --git a/example/src/main/AndroidManifest.xml b/example/src/main/AndroidManifest.xml index c64c3e2..1cce606 100644 --- a/example/src/main/AndroidManifest.xml +++ b/example/src/main/AndroidManifest.xml @@ -23,6 +23,9 @@ + \ No newline at end of file diff --git a/example/src/main/java/dev/hossain/ynaash/example/ui/MainActivity.kt b/example/src/main/java/dev/hossain/ynaash/example/ui/MainActivity.kt index 59edae2..c6b0c26 100644 --- a/example/src/main/java/dev/hossain/ynaash/example/ui/MainActivity.kt +++ b/example/src/main/java/dev/hossain/ynaash/example/ui/MainActivity.kt @@ -7,6 +7,7 @@ import androidx.appcompat.app.AppCompatActivity import dev.hossain.ynaash.example.R import dev.hossain.ynaash.example.ui.demohighlightjs.HighlightJsDemoActivity import dev.hossain.ynaash.example.ui.demoprismjs.PrismJsDemoActivity +import dev.hossain.ynaash.example.ui.demoprismjs.PrismJsComposeDemoActivity /** * Main activity to showcase both fragment based and custom view based syntax highlighting. @@ -23,5 +24,9 @@ class MainActivity : AppCompatActivity() { findViewById