Problema de renderização do Markdown com imagem cercada por HTML

Relacionado a Thumbnail generation & markdown rendering issue

Quando o Discourse baixa e substitui uma imagem HTML pela sua sintaxe Markdown — no nosso contexto, isso resulta em:

[...]<a href="<link_here>" target="_blank">![|150x150](upload://l0iarnA6SPVAyJN5l7pnQxZnPvE.jpeg)</a>[...]

O Discourse não consegue renderizar a imagem

Imagem

image

Para corrigir o problema, é necessário pelo menos uma linha em branco acima:

[...]<a href="<link_here>" target="_blank">

![|150x150](upload://l0iarnA6SPVAyJN5l7pnQxZnPvE.jpeg)</a>[...]
Imagem

Seria possível permitir a renderização de imagens Markdown envoltas por HTML, por favor?

@david

5 curtidas

Vamos testar isso no meta. Estou fazendo hotlink desta imagem dentro de um link:

<a href="https://discourse.org"><img src="..."/></a>

Vamos ver o que acontece quando a imagem for carregada…

3 curtidas

@Arkshine, parece que funcionou bem — está renderizando com sucesso <a href="https://discourse.org">![](upload://6zqK52dO23i1JsYH2oyMU12U2ro.jpeg)</a>.

Você pode compartilhar um pouco mais da estrutura HTML ao redor do link?

2 curtidas
Sem formatação
<div data-wp><a href="https://www.mooki.co.il/gaming/hbilvt-giiming-mwtlmvt/mvwb-giiming-khvl-sparkfox-wvlhn-giiming-mqcvei-lumi-whvr-2" target="_blank">![](upload://vAPxoqZB2QvWCrX4kbbzSO5BYYb.png)</a><div><div data-buy><a href="https://www.mooki.co.il/gaming/hbilvt-giiming-mwtlmvt/mvwb-giiming-khvl-sparkfox-wvlhn-giiming-mqcvei-lumi-whvr-2" target="_blank">Comprar</a><span data-clipboard-text="GLA679" data-coupon>GLA679</span><i></i></div><div data-price>R$ 679 <span data-old-price>R$ 1378</span></div></div></div><hr /><p><small>&nbsp;Publicado em:&nbsp;<a href="https://zuzu.deals/%d7%91%d7%9c%d7%a2%d7%93%d7%99-%d7%95%d7%91%d7%9e%d7%97%d7%99%d7%a8-%d7%97%d7%98%d7%99%d7%a4%d7%94-%d7%9e%d7%95%d7%a9%d7%91-%d7%92%d7%99%d7%99%d7%9e%d7%99%d7%a0%d7%92-%d7%90%d7%93%d7%95%d7%9d-spark/"></a></small></p><br /><p>![](upload://npQfkOhEIdPiFymVdtVyKmwRShL.png)</p>
<p style="text-align: center;">Seja você um gamer ou alguém que trabalha e fica sentado o dia todo com as costas pedindo uma cadeira melhor, aqui está mais uma oferta exclusiva por um preço imperdível!<br />
Cadeira de gaming confortável, fones de ouvido para gaming e frete rápido grátis, com garantia do importador oficial &amp;#8211; apenas por R$ 679!!!</p>
<p style="text-align: center;">Use no checkout o cupom exclusivo &amp;#8211; <strong>GLA679</strong></p>
<div> ![](upload://3c2tvGxZnMqoIn2fVfHA02wocm.jpeg)</div>
<div>
<h3 style="text-align: center;">Cadeira de Gaming Profissional SPARKFOX GC60P</h3>
</div>
<div>Cadeira de gaming com design especial para jogos em PC, oferecendo conforto máximo ao usuário</div>
<div>
<ul>
<li>Cadeira com encosto alto</li>
<li>Conforto máximo para longas sessões de jogo</li>
<li>Par de almofadas de apoio para pescoço e lombar</li>
<li>Tipo de material: espuma moldada</li>
<li>Tipo de estrutura: metal</li>
<li>Material: couro com fibras de carbono</li>
<li>Apóia-braços: ajustáveis para cima/baixo</li>
<li>Tipo de mecanismo: borboleta</li>
<li>Tipo de elevação: hidráulica Classe 4</li>
<li>Alcance do encosto: 90°-180°</li>
<li>Tipo de base: náilon</li>
<li>Material das rodas: náilon</li>
<li>Capacidade de carga: até 150 kg</li>
<li>Garantia: 1 ano</li>
</ul>
<div><strong>Dimensões</strong></div>
<div>
<ul>
<li>Largura: 67 cm</li>
<li>Profundidade: 67 cm</li>
<li>Altura ajustável: 124-132 cm</li>
</ul>
<h3></h3>
<p>![](upload://7t26ZtW6tL3vobWYqbpCbRftvpV.jpeg)</p>
<h3 style="text-align: center;">Fones de Ouvido para Gaming SPARKFOX K1</h3>
<div>Fones de ouvido para gaming com design especial para conforto máximo na audição e fala, com cancelamento de ruído ambiente</div>
<div>
<ul>
<li>Compatíveis com a maioria das consoles disponíveis no mercado</li>
<li>Audição e gerenciamento de chamadas em telefones e computadores portáteis</li>
<li>Controle de volume localizado no cabo do fone para fácil acesso</li>
<li>Excelente qualidade de som com drivers grandes de 50 mm</li>
<li>Controles de volume e mute</li>
<li>Conchas auriculares grandes e acolchoadas para máximo conforto</li>
<li>Arco da cabeça ajustável para ajuste perfeito à sua cabeça</li>
<li>Conexão direta à saída de áudio de 3,5 mm</li>
</ul>
</div>
<div>Inclui adaptador especial para conectar os fones a computadores desktop por meio de um divisor de 3,5 mm para 2 saídas de 3,5 mm</div>
</div>
</div>
<p>&nbsp;</p>
<div data-custom-html=""></div>
Com formatação
<div data-wp>
    <a href="https://www.mooki.co.il/gaming/hbilvt-giiming-mwtlmvt/mvwb-giiming-khvl-sparkfox-wvlhn-giiming-mqcvei-lumi-whvr-2" target="_blank">![](upload://vAPxoqZB2QvWCrX4kbbzSO5BYYb.png)</a>
    <div>
        <div data-buy>
            <a href="https://www.mooki.co.il/gaming/hbilvt-giiming-mwtlmvt/mvwb-giiming-khvl-sparkfox-wvlhn-giiming-mqcvei-lumi-whvr-2" target="_blank">Comprar</a>
            <span data-clipboard-text="GLA679" data-coupon>GLA679</span><i></i>
        </div>
        <div data-price>R$ 679 <span data-old-price>R$ 1378</span></div>
    </div>
</div>
<hr />
<p>
    <small>&nbsp;Publicado em:&nbsp;<a href="https://zuzu.deals/%d7%91%d7%9c%d7%a2%d7%93%d7%99-%d7%95%d7%91%d7%9e%d7%97%d7%99%d7%a8-%d7%97%d7%98%d7%99%d7%a4%d7%94-%d7%9e%d7%95%d7%a9%d7%91-%d7%92%d7%99%d7%99%d7%9e%d7%99%d7%a0%d7%92-%d7%90%d7%93%d7%95%d7%9d-spark/"></a></small>
</p>
<br />
<p>![](upload://npQfkOhEIdPiFymVdtVyKmwRShL.png)</p>
<p style="text-align: center;">
    Seja você um gamer ou alguém que trabalha e fica sentado o dia todo com as costas pedindo uma cadeira melhor, aqui está mais uma oferta exclusiva por um preço imperdível!<br />
    Cadeira de gaming confortável, fones de ouvido para gaming e frete rápido grátis, com garantia do importador oficial &amp;#8211; apenas por R$ 679!!!
</p>
<p style="text-align: center;">Use no checkout o cupom exclusivo &amp;#8211; <strong>GLA679</strong></p>
<div>![](upload://3c2tvGxZnMqoIn2fVfHA02wocm.jpeg)</div>
<div>
    <h3 style="text-align: center;">Cadeira de Gaming Profissional SPARKFOX GC60P</h3>
</div>
<div>Cadeira de gaming com design especial para jogos em PC, oferecendo conforto máximo ao usuário</div>
<div>
    <ul>
        <li>Cadeira com encosto alto</li>
        <li>Conforto máximo para longas sessões de jogo</li>
        <li>Par de almofadas de apoio para pescoço e lombar</li>
        <li>Tipo de material: espuma moldada</li>
        <li>Tipo de estrutura: metal</li>
        <li>Material: couro com fibras de carbono</li>
        <li>Apóia-braços: ajustáveis para cima/baixo</li>
        <li>Tipo de mecanismo: borboleta</li>
        <li>Tipo de elevação: hidráulica Classe 4</li>
        <li>Alcance do encosto: 90°-180°</li>
        <li>Tipo de base: náilon</li>
        <li>Material das rodas: náilon</li>
        <li>Capacidade de carga: até 150 kg</li>
        <li>Garantia: 1 ano</li>
    </ul>
    <div><strong>Dimensões</strong></div>
    <div>
        <ul>
            <li>Largura: 67 cm</li>
            <li>Profundidade: 67 cm</li>
            <li>Altura ajustável: 124-132 cm</li>
        </ul>
        <h3></h3>
        <p>![](upload://7t26ZtW6tL3vobWYqbpCbRftvpV.jpeg)</p>
        <h3 style="text-align: center;">Fones de Ouvido para Gaming SPARKFOX K1</h3>
        <div>Fones de ouvido para gaming com design especial para conforto máximo na audição e fala, com cancelamento de ruído ambiente</div>
        <div>
            <ul>
                <li>Compatíveis com a maioria das consoles disponíveis no mercado</li>
                <li>Audição e gerenciamento de chamadas em telefones e computadores portáteis</li>
                <li>Controle de volume localizado no cabo do fone para fácil acesso</li>
                <li>Excelente qualidade de som com drivers grandes de 50 mm</li>
                <li>Controles de volume e mute</li>
                <li>Conchas auriculares grandes e acolchoadas para máximo conforto</li>
                <li>Arco da cabeça ajustável para ajuste perfeito à sua cabeça</li>
                <li>Conexão direta à saída de áudio de 3,5 mm</li>
            </ul>
        </div>
        <div>Inclui adaptador especial para conectar os fones a computadores desktop por meio de um divisor de 3,5 mm para 2 saídas de 3,5 mm</div>
    </div>
</div>
<p>&nbsp;</p>
<div data-custom-html=""></div>
Captura de tela do editor

1 curtida

Esse é o mesmo problema levantado aqui: Images not publishing to Discourse in WP 5.3 - #6 by simon

3 curtidas

Aha! @simon, atualizar o plugin do WordPress vai corrigir as postagens antigas? Ou apenas as novas?

3 curtidas

A correção se aplica apenas a posts publicados com o editor de blocos do WordPress. Ela corrigirá posts antigos se o botão “Atualizar Tópico no Discourse” for clicado no WordPress. Será necessário fazer isso manualmente para cada post, a menos que alguém crie um script para iterar sobre os posts antigos.

4 curtidas

Vamos tentar este HTML:

<p><img src="..."/></p>

![](upload://6zqK52dO23i1JsYH2oyMU12U2ro.jpeg)

4 curtidas

Acho que isso também deve ser corrigido no Discourse, caso haja posts feitos por uma integração que não seja do WordPress. Para resumir:

  1. Eu publiquei <p><img src="..."/></p>. Isso é HTML perfeitamente válido.

  2. pull_hotlinked_images buscou a imagem e substituiu a marcação por <p>![](upload://6zqK52dO23i1JsYH2oyMU12U2ro.jpeg)</p>

  3. Isso não é renderizado.

Portanto, há duas correções possíveis aqui. Ou:

  • Corrigimos o InlineUploads para que ele adicione uma linha em branco na marcação. Isso é renderizado corretamente:
    <p>
    
    ![](upload://6zqK52dO23i1JsYH2oyMU12U2ro.jpeg)
    </p>
    

OU

@sam, você sabe se há uma razão deliberada para imagens em markdown não serem renderizadas na mesma linha de um <p>?

3 curtidas

Isso faz parte da especificação CommonMark

**test**

<p>**test**</p>

Definitivamente não queremos desviar da especificação aqui. Acredito que corrigiremos a hotlink de imagens externas para permitir isso, injetando duas quebras de linha em casos como este. Acredito que seja bastante raro, porém, e meio que autoinfligido.

5 curtidas

Não acho que seja tão raro, especialmente quando o Discourse está associado a ferramentas populares como o WP-Discourse ou qualquer outra que utilize a API.

Por favor, considere adicionar uma linha em branco. Não parece ser uma mudança que quebre a compatibilidade e é bastante simples de implementar. :pray:

3 curtidas

@Arkshine, discutimos bastante isso internamente. O ponto principal para nós é manter a integridade do conteúdo, então a solução de nova linha provavelmente não será implementada.

Mas certamente faremos algo — deixar que o job pull_hotlinked_images destrua as imagens não é aceitável. Esperamos ter uma solução em breve :eyes:

5 curtidas

Uma solução alternativa para esse problema é impedir que o Discourse baixe as imagens remotas. Isso pode ser feito adicionando o domínio da imagem à configuração do site “domínios de download de imagem desabilitados”. Também é possível impedir que o Discourse baixe todas as imagens remotas desabilitando a configuração do site “baixar imagens remotas para local”. Consulte Fix broken images for posts created by the WP Discourse and RSS plugins para obter detalhes.

4 curtidas

No nosso caso, não podemos, pois estamos usando o componente oficial de miniatura de tópico, que exige uma imagem local. Resolvemos o problema adicionando quebras de linha antes de qualquer <img> no conteúdo antes de o tópico ser criado com o WP-Discourse. Não é uma solução para todos, mas funciona para nós. É um pouco triste que o Discourse não suporte esse uso legítimo.

Mas sim, se você não estiver limitado a um plugin/componente e/ou não puder corrigir o conteúdo antes da criação do tópico, isso é, sem dúvida, uma solução alternativa razoável.

2 curtidas

Ainda estamos planejando corrigir o problema. Infelizmente, trata-se de uma questão bastante profunda no nosso sistema de renderização de Markdown, o que torna a correção complexa. Mas vamos resolver isso — desculpe pela demora!

5 curtidas

Estou apenas adicionando uma nota aqui de que o problema também afeta posts com imagens criados por meio do plugin Discourse RSS.

6 curtidas

Desculpe pelos múltiplos posts neste tópico, mas o problema também afeta imagens em posts criados através do nosso plugin do Zendesk quando a configuração “sincronizar comentários do Zendesk” está habilitada. A dificuldade neste caso é que não é possível saber a origem das imagens com antecedência, portanto a solução alternativa de adicionar o src da imagem à configuração “domínios de download de imagem desativados” não funcionará.

Existe alguma maneira de evitar que imagens remotas sejam baixadas para o local se a tag da imagem estiver envolta em tags HTML?

1 curtida

Temor que isso esteja completamente fora de questão. Se fizéssemos algo assim, permitiríamos que terceiros rastreiem o uso em um fórum injetando um gif de rastreamento. O recurso de baixar imagens remotas é parte de uma funcionalidade de segurança.

Em vez disso, acho que precisamos de um sistema “mais inteligente” que funcione de maneira semelhante à forma como @tgxworld construiu nossos remapeadores de imagem há alguns anos, um que funcione de trás para frente a partir do HTML e garanta a estabilidade da alteração ao re-cozinhar. Mudança muito complexa, infelizmente.

4 curtidas

Esse problema surgiu novamente

Apenas pensando em voz alta, mas me pergunto se podemos contornar o problema complicado aqui (ou seja, a conversão de HTML para markdown). Para recapitular (apenas para ajudar a refletir sobre isso)

  1. O Discourse suporta a importação de HTML para a criação de conteúdo de post (por exemplo, HTML do WP Discourse).

  2. Em alguns contextos, o usuário espera que a integridade do HTML original seja mantida exatamente.

  3. “Integridade” aqui tem pelo menos dois aspectos:

    1. Como o conteúdo é renderizado, por exemplo, quebras de linha
    2. Onde a mídia está hospedada, por exemplo, baixar imagens para o local para evitar imagens quebradas ou potencialmente por preocupações de segurança
  4. A conversão de HTML para markdown potencialmente cria problemas para o primeiro tipo de integridade; no entanto, atualmente é necessário para garantir o segundo tipo de integridade.

Então, talvez uma maneira de resolver esse problema para certas postagens importadas seja armazenar o HTML importado diretamente como o conteúdo cozido do post, e o job pull_hotlinked_images suportaria o download de imagens em tal conteúdo sem converter img para markdown.

Sim, dito de forma mais simples, talvez o código pudesse suportar o download de imagens vinculadas sem exigir a conversão de img para markdown. Para essas postagens, você interpolaria a URL da imagem baixada no conteúdo cozido em vez do conteúdo bruto.

3 curtidas

O problema é: como você editaria posts com essa flag? O editor ficaria no modo HTML bruto e toda a barra de ferramentas ficaria quebrada, etc.

1 curtida