[Question] Can't seem to get SimpleTagHandler to work with custom html tags
See original GitHub issue- Markwon version: 4.3.1
Behaviour
I’ve been having trouble getting markwon to register iframe
tags, I’ve got bunch of html with some iframe that embed youtube content e.g. <iframe src="https://www.youtube.com/embed/luWcue3t2OU" width="640" height="360"></iframe>
I tried to debug the issue, by adding a breakpoint on getSpans
but the method never ran, suggesting that no iframe tags were found. The html is fairly plain, consisting of a few basic tags.
Here’s an example of the input taken from an rss feed:
<p class="p1"><img title="JUMP FORCE" src="https://img1.ak.crunchyroll.com/i/spire1/f0c009039dd9f8dff5907fff148adfca1587067000_full.jpg" alt="JUMP FORCE" width="640" height="362" /></p>
<p class="p2"> </p>
<p class="p1">Switch owners will soon get to take part in the ultimate <em>Shonen Jump </em>rumble. Bandai Namco announced plans to bring <strong><em>Jump Force </em></strong>to <strong>Switch</strong> as <strong><em>Jump Force Deluxe Edition</em></strong>, with a release set for sometime this year. This version will include all of the original playable characters and those from Character Pass 1, and <strong>Character Pass 2 is also in the works </strong>for all versions, starting with <strong>Shoto Todoroki from </strong><span style="color: #ff9900;"><a href="/my-hero-academia?utm_source=editorial_cr&utm_medium=news&utm_campaign=article_driven&referrer=editorial_cr_news_article_driven"><span style="color: #ff9900;"><strong><em>My Hero Academia</em></strong></span></a></span>.</p>
<p class="p2"> </p>
<p class="p1">Other than Todoroki, Bandai Namco hinted that the four other Character Pass 2 characters will hail from <span style="color: #ff9900;"><a href="/hunter-x-hunter?utm_source=editorial_cr&utm_medium=news&utm_campaign=article_driven&referrer=editorial_cr_news_article_driven"><span style="color: #ff9900;"><em>Hunter x Hunter</em></span></a></span>, <em>Yu Yu Hakusho</em>, <span style="color: #ff9900;"><a href="/bleach?utm_source=editorial_cr&utm_medium=news&utm_campaign=article_driven&referrer=editorial_cr_news_article_driven"><span style="color: #ff9900;"><em>Bleach</em></span></a></span>, and <span style="color: #ff9900;"><a href="/jojos-bizarre-adventure?utm_source=editorial_cr&utm_medium=news&utm_campaign=article_driven&referrer=editorial_cr_news_article_driven"><span style="color: #ff9900;"><em>JoJo's Bizarre Adventure</em></span></a></span>. Character Pass 2 will be priced at $17.99, and Todoroki launches this spring.<span class="Apple-converted-space"> </span></p>
<p class="p2"> </p>
<p class="p1"><iframe style="display: block; margin-left: auto; margin-right: auto;" src="https://www.youtube.com/embed/At1qTj-LWCc" frameborder="0" width="640" height="360"></iframe></p>
<p class="p2"> </p>
<p class="p1">Character Pass 2 promo:</p>
<p class="p2"> </p>
<p class="p1"><iframe style="display: block; margin-left: auto; margin-right: auto;" src="https://www.youtube.com/embed/CukwN6kV4R4" frameborder="0" width="640" height="360"></iframe></p>
<p class="p2"> </p>
<p class="p1"><a href="https://got.cr/PremiumTrial-NewsBanner4"><img style="display: block; margin-left: auto; margin-right: auto;" src="https://img1.ak.crunchyroll.com/i/spire4/78f5441d927cf160a93e037b567c2b1f1587067041_full.png" alt="" width="640" height="43" /></a></p>
<p class="p2"> </p>
<p class="p1">-------</p>
<p class="p1"><em>Joseph Luster is the Games and Web editor at </em><a href="http://www.otakuusamagazine.com/ME2/Default.asp"><em>Otaku USA Magazine</em></a><em>. You can read his webcomic, </em><a href="http://subhumanzoids.com/comics/big-dumb-fighting-idiots/">BIG DUMB FIGHTING IDIOTS</a><em> at </em><a href="http://subhumanzoids.com/"><em>subhumanzoids</em></a><em>. Follow him on Twitter </em><a href="https://twitter.com/Moldilox"><em>@Moldilox</em></a><em>.</em><span class="Apple-converted-space"> </span></p>
Reproduction
I have setup markwon as follows:
private val coreModule = module {
single {
Markwon.builder(androidApplication())
.usePlugin(HtmlPlugin.create())
.usePlugin(LinkifyPlugin.create())
.usePlugin(TagPlugin.create())
.usePlugin(
GlideImagesPlugin.create(
object : GlideImagesPlugin.GlideStore {
override fun cancel(target: Target<*>) {
Glide.with(androidApplication()).clear(target)
}
override fun load(drawable: AsyncDrawable): RequestBuilder<Drawable> {
return Glide.with(androidApplication()).load(drawable.destination)
.transform(
CenterCrop(),
RoundedCorners(
androidApplication().resources
.getDimensionPixelSize(
R.dimen.md_margin
)
)
).placeholder(R.drawable.ic_launcher_foreground)
}
}
)
)
.build()
}
}
class TagPlugin private constructor(): AbstractMarkwonPlugin() {
override fun configure(registry: MarkwonPlugin.Registry) {
registry.require(HtmlPlugin::class.java) {
it.addHandler(EmbedTagHandler.create())
it.addHandler(TagAlignmentHandler.create())
}
}
companion object {
fun create() = TagPlugin()
}
}
/**
* Allows us to handle iframes and extract images from it, we will only target youtube iframes
* to return a clickable image which should trigger the youtube
*
* <iframe src="https://www.youtube.com/embed/luWcue3t2OU" width="640" height="360" />
*/
class EmbedTagHandler private constructor() : SimpleTagHandler() {
private fun getVideoId(src: String) = src.split('/').last()
private fun getVideoUrl(src: String): String {
val videoId = getVideoId(src)
return "https://youtube.com/watch?v=$videoId"
}
private fun createImageLink(src: String): String {
val videoId = getVideoId(src)
return "https://img.youtube.com/vi/$videoId/hqdefault.jpg"
}
override fun getSpans(
configuration: MarkwonConfiguration,
renderProps: RenderProps,
tag: HtmlTag
): Any? {
val attributes = tag.attributes()
val source = attributes["src"]
return if (source?.contains("youtube") == true) {
val imageSpanFactory = configuration
.spansFactory()
.get(Image::class.java)
// ignore this, I'm actually not sure if this will work :'D (trying to make image clickable)
val linkSpanFactory = configuration
.spansFactory()
.get(Link::class.java)
val width = attributes["width"]?.toFloat()
val height = attributes["height"]?.toFloat()
val imageSize = ImageSize(
width?.let { ImageSize.Dimension(it, "px") },
height?.let { ImageSize.Dimension(it, "px") }
)
ImageProps.DESTINATION.set(renderProps, createImageLink(source))
ImageProps.IMAGE_SIZE.set(renderProps, imageSize);
ImageProps.REPLACEMENT_TEXT_IS_LINK.set(renderProps, false);
CoreProps.LINK_DESTINATION.set(renderProps, getVideoUrl(source))
arrayOf(
imageSpanFactory?.getSpans(configuration, renderProps),
linkSpanFactory?.getSpans(configuration, renderProps)
)
} else {
// return some sort of unsupported span
val textSpan = configuration.spansFactory().get(Text::class.java)
renderProps.set(
Prop.of("text-literal"),
"Unsupported embedded element"
)
textSpan?.getSpans(configuration, renderProps)
}
}
override fun supportedTags() = listOf("iframe")
companion object {
fun create() = EmbedTagHandler()
}
}
Besides this everything else works perfectly! Thank you in advance 😺
Issue Analytics
- State:
- Created 3 years ago
- Comments:9 (4 by maintainers)
Top Results From Across the Web
Using custom HTML Tags - css - Stack Overflow
If you do not use standard html tags when designing pages, they will not appear in any organized manner when styles are disabled....
Read more >Using custom elements - Web Components | MDN
Customized built-in elements inherit from basic HTML elements. To create one of these, you have to specify which element they extend (as implied ......
Read more >Chapter 8 Custom Tags in JSP Pages (The Java EE 5 Tutorial)
Simple tag handlers can be used only for tags that do not use scripting elements in attribute ... A simple tag can contain...
Read more >JavaServer Pages (JSP) - A Tutorial
Use a programming text editor to enter the following HTML/JSP codes and save as " first.jsp " under the context root " hellojsp...
Read more >Custom Elements v1 - Reusable Web Components
It's called HTML. You may have heard of it! It's declarative, portable, well supported, and easy to work with. Great as HTML may...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
center
tag is considered to be a block one andiframe
is its child. You will need to useTagHandler
instead ofSimpleTagHandler
:it feels like
SimpleTagHandler
could have this functionality build-inIf you do not control the content, then yes, adding a dummy character (even
space
would work)P.S. leaving it here as you’d mentioned regex and parsing html in one sentence 😄