Apply HTML to Wikipedia text
This commit is contained in:
parent
afaf7d7e73
commit
fc90fdb17d
@ -66,6 +66,8 @@ dependencies {
|
|||||||
|
|
||||||
implementation(libs.composecolorpicker)
|
implementation(libs.composecolorpicker)
|
||||||
|
|
||||||
|
implementation(libs.jsoup)
|
||||||
|
|
||||||
// Legacy dependencies
|
// Legacy dependencies
|
||||||
implementation(libs.androidx.transition)
|
implementation(libs.androidx.transition)
|
||||||
|
|
||||||
|
|||||||
@ -33,6 +33,7 @@ import de.mm20.launcher2.ui.component.ToolbarAction
|
|||||||
import de.mm20.launcher2.ui.ktx.toDp
|
import de.mm20.launcher2.ui.ktx.toDp
|
||||||
import de.mm20.launcher2.ui.launcher.search.website.WebsiteItem
|
import de.mm20.launcher2.ui.launcher.search.website.WebsiteItem
|
||||||
import de.mm20.launcher2.ui.locals.LocalFavoritesEnabled
|
import de.mm20.launcher2.ui.locals.LocalFavoritesEnabled
|
||||||
|
import de.mm20.launcher2.ui.utils.htmlToAnnotatedString
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun WikipediaItem(
|
fun WikipediaItem(
|
||||||
@ -72,7 +73,7 @@ fun WikipediaItem(
|
|||||||
)
|
)
|
||||||
Text(
|
Text(
|
||||||
modifier = Modifier.padding(vertical = 8.dp),
|
modifier = Modifier.padding(vertical = 8.dp),
|
||||||
text = wikipedia.text,
|
text = htmlToAnnotatedString(wikipedia.text),
|
||||||
style = MaterialTheme.typography.bodySmall
|
style = MaterialTheme.typography.bodySmall
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,105 @@
|
|||||||
|
package de.mm20.launcher2.ui.utils
|
||||||
|
|
||||||
|
import androidx.compose.ui.text.*
|
||||||
|
import androidx.compose.ui.text.font.FontFamily
|
||||||
|
import androidx.compose.ui.text.font.FontStyle
|
||||||
|
import androidx.compose.ui.text.font.FontWeight
|
||||||
|
import androidx.compose.ui.text.style.BaselineShift
|
||||||
|
import androidx.compose.ui.text.style.TextDecoration
|
||||||
|
import androidx.compose.ui.text.style.TextIndent
|
||||||
|
import androidx.compose.ui.unit.em
|
||||||
|
import org.jsoup.Jsoup
|
||||||
|
import org.jsoup.nodes.Element
|
||||||
|
import org.jsoup.nodes.TextNode
|
||||||
|
|
||||||
|
fun htmlToAnnotatedString(html: String): AnnotatedString {
|
||||||
|
val document = Jsoup.parse(html.replace("\n", ""))
|
||||||
|
return buildAnnotatedString {
|
||||||
|
addNodes(this, document)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val blockElements = arrayOf("p", "h1", "h2", "h3", "h4", "h5", "h6", "li", "pre")
|
||||||
|
|
||||||
|
private val inlineElements = arrayOf("i", "b", "strong", "em", "sup", "sub", "u", "s", "code", "br")
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param inParagraph: ParagraphStyles may not be nested, this parameter indicates if we are already inside a paragraph
|
||||||
|
*/
|
||||||
|
private fun addNodes(builder: AnnotatedString.Builder, element: Element, inParagraph: Boolean = false) {
|
||||||
|
val tagName = element.tag().normalName()
|
||||||
|
when {
|
||||||
|
blockElements.contains(tagName) -> {
|
||||||
|
val spanStyle = SpanStyle(
|
||||||
|
fontSize = when (tagName) {
|
||||||
|
"h1" -> 2.em
|
||||||
|
"h2" -> 1.75.em
|
||||||
|
"h3" -> 1.5.em
|
||||||
|
"h4" -> 1.25.em
|
||||||
|
"h5" -> 1.125.em
|
||||||
|
"h6" -> 1.em
|
||||||
|
else -> 1.em
|
||||||
|
},
|
||||||
|
fontWeight = if (tagName.matches(Regex("h[1-6]"))) FontWeight.Bold else FontWeight.Normal,
|
||||||
|
fontFamily = if (tagName == "pre") FontFamily.Monospace else null
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!inParagraph) {
|
||||||
|
builder.withStyle(ParagraphStyle(
|
||||||
|
textIndent = if (tagName == "li") TextIndent(0.em, 1.em) else TextIndent.None
|
||||||
|
)) {
|
||||||
|
withStyle(
|
||||||
|
spanStyle
|
||||||
|
) {
|
||||||
|
if (tagName == "li") builder.append(" • ")
|
||||||
|
children(builder, element, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
builder.append("\n")
|
||||||
|
builder.withStyle(
|
||||||
|
spanStyle
|
||||||
|
) {
|
||||||
|
if (tagName == "li") builder.append(" • ")
|
||||||
|
children(builder, element, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inlineElements.contains(tagName) -> {
|
||||||
|
builder.withStyle(
|
||||||
|
SpanStyle(
|
||||||
|
fontStyle = if (tagName == "i" || tagName == "em") FontStyle.Italic else FontStyle.Normal,
|
||||||
|
fontWeight = if (tagName == "b" || tagName == "strong") FontWeight.Bold else FontWeight.Normal,
|
||||||
|
textDecoration = when (tagName) {
|
||||||
|
"u" -> TextDecoration.Underline
|
||||||
|
"s" -> TextDecoration.LineThrough
|
||||||
|
else -> TextDecoration.None
|
||||||
|
},
|
||||||
|
baselineShift = when (tagName) {
|
||||||
|
"sup" -> BaselineShift.Superscript
|
||||||
|
"sub" -> BaselineShift.Subscript
|
||||||
|
else -> BaselineShift.None
|
||||||
|
},
|
||||||
|
fontFamily = if (tagName == "code") FontFamily.Monospace else null
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
if(tagName == "br") builder.append("\n")
|
||||||
|
children(builder, element, inParagraph)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
children(builder, element, inParagraph)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun children(builder: AnnotatedString.Builder, element: Element, inParagraph: Boolean) {
|
||||||
|
for (node in element.childNodes()) {
|
||||||
|
if (node is TextNode) {
|
||||||
|
builder.append(node.text())
|
||||||
|
}
|
||||||
|
if (node is Element) {
|
||||||
|
addNodes(builder, node, inParagraph)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -34,7 +34,7 @@ data class WikipediaGetPageImageResultQueryPageThumnail(
|
|||||||
)
|
)
|
||||||
|
|
||||||
interface WikipediaApi {
|
interface WikipediaApi {
|
||||||
@GET("w/api.php?action=query&generator=search&redirects=true&gsrlimit=1&explaintext=true&exchars=500&prop=extracts&exintro=true&format=json")
|
@GET("w/api.php?action=query&generator=search&redirects=true&gsrlimit=1&exchars=500&prop=extracts&exintro=true&format=json")
|
||||||
suspend fun search(@Query("gsrsearch") query: String): WikipediaSearchResult
|
suspend fun search(@Query("gsrsearch") query: String): WikipediaSearchResult
|
||||||
|
|
||||||
@GET("w/api.php?action=query&prop=pageimages&format=json")
|
@GET("w/api.php?action=query&prop=pageimages&format=json")
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user