thennothinghappened / HtmlText

Simple HTML renderer for Compose Multiplatform
MIT License
6 stars 1 forks source link

No CSS support #1

Open qc5926 opened 6 months ago

qc5926 commented 6 months ago

一部分情况下会有带行内样式的html标签,在转换这部分标签时如何保留并应用样式

thennothinghappened commented 6 months ago

Heya, just seen this. I only know english unfortunately so I've had to translate to read this - Could you give a quick example of what you mean? This library has some pretty big limitations as it was pretty much just made for my own purposes and published in case it'd be useful to others - namely it uses a FlowRow to display everything rather that using AnnotatedString as it should. This does mean that there's some issues with how text wraps and often inline tags like to split themselves to newlines rather than breaking the text:

Some text <b>and some bold text</b>!

...Should look like:

Some text and some bold text!

...But can end up displayed as:

Some text  and some bold text!

Is this the issue you're running into?

When I've got time again (eventually) I do plan to rewrite it to use that instead - the reason I hadn't was the whole placeholder mechanism is a bit finicky.

qc5926 commented 6 months ago

Sorry, my English is not very good, I will just describe my problem briefly.

Some text <span style="color: red; font-size: 24px;"><strong>This is red 24 pixel text</strong></span>

should look like:

Some text This is red 24 pixel text

This is the main problem I want to solve. The line break problem you mentioned above also exists.

thennothinghappened commented 6 months ago

Ah CSS - That's also something I'd like this library to support down the line but I haven't got around to it unfortunately. It might be worthwhile when I give it a proper rewrite allowing the user of the lib to define their own element types, could have a CompositionLocal that stores a configuration where you can pass in a map of tag names to @Composables or something like that - but your options for this in the current version is unfortunately just opening up the source for it and creating your own elements that have pre-defined style information.

thennothinghappened commented 6 months ago

If you're just working in Jetpack Compose I might point you toward just using a WebView if that's an option. You get full HTML and CSS support there, and it's just static content supported in HtmlText anyway so you're not losing much by using the dedicated option in comparison. I'm not sure if any better libraries have developed multiplatform-wise though since I threw this together, but I'd suggest having a look around there in case the HTML situation in JB-Compose has got a bit better since I last checked.

I'll be needing a proper HTML component soon-ish for accompanying the rewrite of the app it was for in the first place, so down the line if you're still needing this I might have something better by then, but no promises!

qc5926 commented 6 months ago

Thank you very much for your patient explanation. I will try some other methods. I also hope that you can complete it as soon as possible. I have always needed it.

thennothinghappened commented 6 months ago

Heya, back again!

I've just rewritten a big part of the library in response to this lol.

Hopefully v1.3.0 can tide you over with customisation until I can find time to properly rewrite it with all the fancy stuff.

https://github.com/thennothinghappened/HtmlText/releases/tag/1.3.0

You can now create custom elements, so if you wanted to be able to colour elements you could now do something like this:

private enum class NamedColor(val color: Color) {
    Red(Color.Red),
    Green(Color.Green),
    Blue(Color.Blue)
    // ...
}

/**
 * A colourable HTML element, using an attribute `color` to set its content's colour.
 */
val HtmlColorable = HtmlElementRenderer { element, modifier ->

    val color = element.attr("color")
        .takeIf { it.isNotBlank() }
        ?.lowercase()
        ?.let { NamedColor.entries.find { entry -> entry.name.lowercase() == it } }
        ?.color
        ?: LocalContentColor.current

    ProvideTextStyle(TextStyle(color = color)) {
        HtmlChildRenderer(element, modifier)
    }

}

// ...Then in your App() composable or similar:
val originalTagMap = LocalHtmlTextTagMap.current
val extendedTagMap = remember {
    originalTagMap.extend(
        "colorable" to HtmlColorable
    )
}

CompositionLocalProvider(LocalHtmlTextTagMap provides extendedTagMap) {
    HtmlText(document)
}

Far from a great solution, but better than nothing I hope :)