asjqkkkk/markdown_widget

Custom Tag (())

thomastthai opened this issue · 9 comments

Firstly, this is my favorite markdown widget for Flutter — excellent work, especially v3.0 support!

Secondly, how would you implement a custom tag like (()) that can have a database ID in between like ((zA27sX)) and print the title of that record in place of that tag with the ID?

Hi @thomastthai , thanks for your question
Perhaps you need to implement a InlineSyntax or a BlockSyntax that can convert ((xxx)) to a Markdown Element with a tag, then you need to implement a SpanNode which has the same tag
and then you can do what you want to do
But I don't kown how to use RegExp, if you are good at this, you can implement by yourself, or have a look at #77

@asjqkkkk, thanks for your suggestions. I'm new to Dart/Flutter. Let me make sure I understand you correctly as there is similar jargon between Flutter, HTML, and markdown.

Perhaps you need to implement a InlineSyntax or a BlockSyntax

Do you mean implement an InlineSyntax or BlockSyntax in the Dart markdown package?

that can convert ((xxx)) to a Markdown Element with a tag

I'm confused by what you mean. As I understand, examples of Markdown Elements are **bold**, and _italic_. Wouldn't ((xxx)) be a custom Markdown Element?

When you say tag, are you referring MarkdownTag like the ones in enum MarkdownTag {} in `lib\config\config? If not, would you give me an example of what you mean by tag?

#77 is helpful.

Thank you very much for your time.

Hi @thomastthai , I write a sample to explain what I said, I spent some time to learn the simple use of RegExp .

There is the result:
image

And you can checkout br_test_syntax branch to watch the code, there is the core code: db.dart

@asjqkkkk, thank you for responding with code that answered my questions. The code was very helpful.

br_test_syntax branch was downloaded but failed to compile after executing flutter pub get and flutter run with the following warnings and errors:

Warning: The plugin url_launcher_android requires Android SDK version 33.
For more information about build configuration, see https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
One or more plugins require a higher Android SDK version.
Fix this issue by adding the following to C:\Users\Thomas\Programming\Flutter\markdown_widget-br_test_syntax\example\android\app\build.gradle:
android {
  compileSdkVersion 33
  ...
}

Warning: Mapping new ns http://schemas.android.com/repository/android/common/02 to old ns http://schemas.android.com/repository/android/common/01
Warning: Mapping new ns http://schemas.android.com/repository/android/generic/02 to old ns http://schemas.android.com/repository/android/generic/01
Warning: Mapping new ns http://schemas.android.com/sdk/android/repo/addon2/02 to old ns http://schemas.android.com/sdk/android/repo/addon2/01
Warning: Mapping new ns http://schemas.android.com/sdk/android/repo/addon2/03 to old ns http://schemas.android.com/sdk/android/repo/addon2/01
Warning: Mapping new ns http://schemas.android.com/sdk/android/repo/repository2/02 to old ns http://schemas.android.com/sdk/android/repo/repository2/01
Warning: Mapping new ns http://schemas.android.com/sdk/android/repo/repository2/03 to old ns http://schemas.android.com/sdk/android/repo/repository2/01

Warning: Mapping new ns http://schemas.android.com/sdk/android/repo/repository2/03 to old ns http://schemas.android.com/sdk/android/repo/repository2/01
Warning: Mapping new ns http://schemas.android.com/sdk/android/repo/sys-img2/03 to old ns http://schemas.android.com/sdk/android/repo/sys-img2/01
Warning: Mapping new ns http://schemas.android.com/sdk/android/repo/sys-img2/02 to old ns http://schemas.android.com/sdk/android/repo/sys-img2/01
Warning: unexpected element (uri:"", local:"extension-level"). Expected elements are <{}codename>,<{}layoutlib>,<{}api-level>
Warning: unexpected element (uri:"", local:"base-extension"). Expected elements are <{}codename>,<{}layoutlib>,<{}api-level>
e: C:/Users/Thomas/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-common/1.5.31/43331609c7de811fed085e0dfd150874b157c32/kotlin-stdlib-common-1.5.31.jar!/META-INF/kotlin-stdlib-common.kotlin_module: Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.5.1, expected version is 1.1.15.
e: C:/Users/Thomas/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jdk7/1.5.30/525f5a7fa6d7790a571c07dd24214ed2dda352fe/kotlin-stdlib-jdk7-1.5.30.jar!/META-INF/kotlin-stdlib-jdk7.kotlin_module: Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.5.1, expected version is 1.1.15.
e: C:/Users/Thomas/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib-jdk8/1.5.30/5fd47535cc85f9e24996f939c2de6583991481b0/kotlin-stdlib-jdk8-1.5.30.jar!/META-INF/kotlin-stdlib-jdk8.kotlin_module: Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.5.1, expected version is 1.1.15.
e: C:/Users/Thomas/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.5.31/6628d61d0f5603568e72d2d5915d2c034b4f1c55/kotlin-stdlib-1.5.31.jar!/META-INF/kotlin-stdlib.kotlin_module: Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.5.1, expected version is 1.1.15.
e: C:/Users/Thomas/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-coroutines-android/1.5.2/d246a704a55b7bddb79407cce4348890eaa341d9/kotlinx-coroutines-android-1.5.2.jar!/META-INF/kotlinx-coroutines-android.kotlin_module: Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.5.1, expected version is 1.1.15.
e: C:/Users/Thomas/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlinx/kotlinx-coroutines-core-jvm/1.5.2/f4cc07a50437659e0043e7da762809a46932b6a0/kotlinx-coroutines-core-jvm-1.5.2.jar!/META-INF/kotlinx-coroutines-core.kotlin_module: Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.5.1, expected version is 1.1.15.
e: C:/Users/Thomas/.gradle/caches/transforms-2/files-2.1/8a3486c4f5eff1822e6e6c25c4684c4e/window-java-1.0.0-beta04/jars/classes.jar!/META-INF/window-java_release.kotlin_module: Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.5.1, expected version is 1.1.15.
e: C:/Users/Thomas/.gradle/caches/transforms-2/files-2.1/b627b77626e82d98a86773348976e091/jetified-window-1.0.0-beta04/jars/classes.jar!/META-INF/window_release.kotlin_module: Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.5.1, expected version is 1.1.15.

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:compileDebugKotlin'.
> Compilation error. See log for more details

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 2m 49s
┌─ Flutter Fix ────────────────────────────────────────────────────────────────────────────────────┐
│ [!] Your project requires a newer version of the Kotlin Gradle plugin.                           │
│ Find the latest version on https://kotlinlang.org/docs/gradle.html#plugin-and-versions, then     │
│ update                                                                                           │
│ C:\Users\Thomas\Programming\Flutter\markdown_widget-br_test_syntax\example\android\build.gradle: │
│ ext.kotlin_version = '<latest-version>'                                                          │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘
Exception: Gradle task assembleDebug failed with exit code 1
Exited (sigterm)

Fixing the warnings and errors

Upgraded Android SDK from 31 to 33:

android {
    compileSdkVersion 33

    sourceSets {
        main.java.srcDirs += 'src/main/kotlin'
    }

Upgraded kotlin from 1.3.50 to 1.8.0 in example > android > build.gradle:

buildscript {
    ext.kotlin_version = '1.8.0'
    repositories {
        google()
        jcenter()
    }
...

Recompile and test again

$ flutter run
Launching lib\main.dart on SM A326U in debug mode...

FAILURE: Build failed with an exception.

* Where:
Build file 'C:\Users\Thomas\Programming\Flutter\markdown_widget-br_test_syntax\example\android\app\build.gradle' line: 25

* What went wrong:
┌─ Flutter Fix ────────────────────────────────────────────────────────────────────────────────────────┐
│ [!] Your project needs to upgrade Gradle and the Android Gradle plugin.                              │
│                                                                                                      │
│ To fix this issue, replace the following content:                                                    │
│ C:\Users\Thomas\Programming\Flutter\markdown_widget-br_test_syntax\example\android\build.gradle:     │
│     - classpath 'com.android.tools.build:gradle:<current-version>'                                   │
│     + classpath 'com.android.tools.build:gradle:7.1.2'                                               │
│ C:\Users\Thomas\Programming\Flutter\markdown_widget-br_test_syntax\example\android\gradle\wrapper\gr │
│ adle-wrapper.properties:                                                                             │
│     - https://services.gradle.org/distributions/gradle-<current-version>-all.zip                     │
│     + https://services.gradle.org/distributions/gradle-7.4-all.zip                                   │
└──────────────────────────────────────────────────────────────────────────────────────────────────────┘
Exception: Gradle task assembleDebug failed with exit code 1

Upgrade Gradle and the Android Gradle plugin:

In the file example\android\build.gradle changed 3.5.0 to 7.1.2:

...
    dependencies {
        classpath 'com.android.tools.build:gradle:7.1.2'
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
}
...

In the file example\android\gradle\wrapper\gradle-wrapper.properties, change gradle-6.7-all.zip to gradle-7.4-all.zip.

#Fri Jun 23 08:50:38 CEST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip 

Compile and try again

$ flutter run
Launching lib\main.dart on SM A326U in debug mode...
Warning: Mapping new ns http://schemas.android.com/repository/android/common/02 to old ns http://schemas.android.com/repository/android/common/01
Warning: Mapping new ns http://schemas.android.com/repository/android/generic/02 to old ns http://schemas.android.com/repository/android/generic/01
Warning: Mapping new ns http://schemas.android.com/sdk/android/repo/addon2/02 to old ns http://schemas.android.com/sdk/android/repo/addon2/01
Warning: Mapping new ns http://schemas.android.com/sdk/android/repo/addon2/03 to old ns http://schemas.android.com/sdk/android/repo/addon2/01
Warning: Mapping new ns http://schemas.android.com/sdk/android/repo/repository2/02 to old ns http://schemas.android.com/sdk/android/repo/repository2/01
Warning: Mapping new ns http://schemas.android.com/sdk/android/repo/repository2/03 to old ns http://schemas.android.com/sdk/android/repo/repository2/01
Warning: Mapping new ns http://schemas.android.com/sdk/android/repo/sys-img2/03 to old ns http://schemas.android.com/sdk/android/repo/sys-img2/01
Warning: Mapping new ns http://schemas.android.com/sdk/android/repo/sys-img2/02 to old ns http://schemas.android.com/sdk/android/repo/sys-img2/01
Warning: unexpected element (uri:"", local:"extension-level"). Expected elements are <{}codename>,<{}layoutlib>,<{}api-level>
Warning: unexpected element (uri:"", local:"base-extension"). Expected elements are <{}codename>,<{}layoutlib>,<{}api-level>

FAILURE: Build failed with an exception.

* What went wrong:
A problem was found with the configuration of task ':app:checkDebugManifest' (type 'CheckManifest').    
  - In plugin 'com.android.build.gradle.api.AndroidBasePlugin' type 'com.android.build.gradle.internal.tasks.CheckManifest' property 'manifest' has @Input annotation used on property of type 'File'.

    Reason: A property of type 'File' annotated with @Input cannot determine how to interpret the file. 

    Possible solutions:
      1. Annotate with @InputFile for regular files.
      2. Annotate with @InputDirectory for directories.
      3. If you want to track the path, return File.absolutePath as a String and keep @Input.

    Please refer to https://docs.gradle.org/7.4/userguide/validation_problems.html#incorrect_use_of_input_annotation for more details about this problem.

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 25s
Running Gradle task 'assembleDebug'...                             27.8s
Exception: Gradle task assembleDebug failed with exit code 1

I'll work on getting through the new errors and update.

Update

Update Android Studio to the latest Electric Eel version, just in case.

Update the file example > android > build.gradle dependencies for com.android.tools.build:gradle to 7.4.0:

...
    dependencies {
        classpath 'com.android.tools.build:gradle:7.4.0' # <-- Update to 7.4.0
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
    }
...

Update the file example > android > gradle > wrapper > gradle-wrapper.properties distributionUrl to gradle-7.5-all.zip:

distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip # <---

Update the file example > android > app > build.gradle defaultConfig section to have minSdkVersion 21:

...
defaultConfig {
        // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
        applicationId "com.example.example"
        minSdkVersion 21 // <---
        targetSdkVersion 31
        versionCode flutterVersionCode.toInteger()
        versionName flutterVersionName
    }
...

In the file example > android > app > src > main > AndroidManifest.xml, added android:exported="true" as a param for <activity> section:

...
<activity
            android:name=".MainActivity"
            android:exported="true"
            android:launchMode="singleTop"
...

Clean up and recompile again:

$ flutter clean && flutter pub get && flutter run --debug

And at long last, the app finally compiled!

While other markdown elements are translated properly, the ((xxx)) isn't translating like you showed with your screen captures.

Screenshot_20230127-112408

Screenshot_20230127-112350

The previous screenshot that showed incorrect ((xxx)) rendering were from an Android phone.

When rendering to Chrome and Windows, the ((xxx)) renders properly as seen below:

Chrome:

image

Windows:

image

And at long last, the app finally compiled!

While other markdown elements are translated properly, the ((xxx)) isn't translating like you showed with your screen captures.

Hi @thomastthai , I konw what happened, beacause I used markdown_page.dart to show the result of markdown data on Mobile, and I didn't add DBSyntaxDBNode to markdown_page.dart's MarkdownWidget because this is a test branch, you can add it by yourself, and it will work properly
image

image

image

Thank you for the reply, @asjqkkkk! The ((xxx)) shows correctly on Android now. I made the same changes earlier after reviewing your test/db_test.dart file but didn't have a chance to follow up.

Screenshot_20230127-192022

These custom markdown elements will give people more flexibility with customization.

sorry

how can I parse nested custom tag just like ((xxx((yyy))zzz)), and if there is \n in text contents how can I parse it.