Matemática deve ser citável

Temos um fórum Discourse para um software científico e usamos o plugin de matemática. Infelizmente, fórmulas matemáticas não podem ser citadas.

Se eu selecionar algum texto, um botão “Citar” aparece:

Ao clicar nele, o seguinte resultado aparece:

[quote]
definição da centralidade de proximidade:

ci=1N−1N∑j=11dij c_i = \frac{1}{N-1} \sum_{j=1}^N\frac{1}{d_{ij}}
[/quote]

Note que na citação, a fórmula matemática aparece como uma versão textual estranha (ilegível) seguida pelo código LaTeX real, mas sem os delimitadores $.

Acho que não há correção para isso no momento. Seria bom se isso pudesse ser melhorado no futuro.

8 curtidas

Isso ainda está ocorrendo e também acontece com matemática inline, conforme relatado por um membro em nossa instância:

3 curtidas

Nota: Concordo totalmente que devemos limpar isso, mas parece extremamente complicado.

Estou adicionando uma pr-welcome caso alguém com habilidades avançadas queira tentar.

7 curtidas

Investiguei a citação de matemática (estou pensando em escrever um PR ou contribuir para um).

Documentando alguns pensamentos e descobertas iniciais aqui.

Então, minha impressão inicial é que um destes pontos pode ser corrigido:

  • toMarkdown corresponde a elementos contra várias tags HTML; mathjax usa elementos personalizados, acho que são detectáveis (talvez não renderização SVG), talvez katex também?
  • selectedText faz alguma correspondência para elementos como blocos de código e onebox – pode detectar elementos mathjax/katex e transformá-los? (Nota: provavelmente é uma boa ideia ter um hook ou algo assim aqui para que a lógica de transformação possa ser adicionada ao plugin discourse-math em vez da base de código principal do discourse).
  • os outros pontos não parecem tão adequados quanto estes dois.

Alguns outros pensamentos sobre abordagens e como obter a matemática bruta.

Dependendo de como katex / mathjax+svg[1] funcionam, toda instância de matemática deve ter um elemento HTML raiz, acho eu (possivelmente múltiplos, pois existem alguns elementos ocultos para acessibilidade e outras coisas). Então, se soubermos os locais onde a matemática existe, podemos analisar a postagem bruta em busca de instâncias de conteúdo delimitadas por $ (mas os interpretadores são complicados – talvez já exista um na base de código?)

Alternativamente, mathjax pelo menos tem um recurso de clique com o botão direito \u003e ver-tex (que deve ser a string literal entre pares de $); não tenho certeza de como me conectar a isso, mas se houver uma maneira de fazer isso para mathjax v2, v3 e katex, então deve ser possível usá-lo para substituir a matemática formatada selecionada por $...$ (nota: isso funciona para matemática inline, é preciso cobrir o caso para o outro tipo também – que usa delimitadores $$...$$ ou [/.../].)

Problemas atuais:

  • Não sei como implementar um hook ou se há algo melhor para usar / uma maneira melhor de fazer isso na base de código do discourse.
  • Vários desconhecidos sobre mathjax/katex que precisam ser investigados.
    • Elementos HTML – como detectá-los de forma confiável?
    • Como obter o código TeX bruto?

Se alguém tiver outras ideias sobre onde/o que corrigir, outros métodos de implementação possíveis ou qualquer outra coisa, por favor, poste-os.


  1. Acho que talvez mathjax+svg não seja suportado, então isso talvez não seja um problema ↩︎

6 curtidas

O Discourse Math foi amplamente atualizado em janeiro de 2026 para uma nova versão oficial incluída no núcleo, com MathJax 4.1 como padrão e KaTeX como alternativa. A documentação do plugin também observa que o KaTeX inclui a extensão CopyTex para copiar a origem LaTeX.

Valeria a pena adicionar um pequeno patch de componente de tema que melhora a seleção de citações para posts com muito conteúdo matemático?

Para sites com uso intensivo de MathJax, como o Physics with Ethan, a ideia mais prática é:

  1. interceptar o HTML selecionado antes que o Discourse o converta de volta em Markdown,
  2. encontrar os elementos de encapsulamento de matemática,
  3. substituí-los pela sua fonte TeX original encapsulada em $...$ ou $$...$$,
  4. então deixar o Discourse continuar construindo a citação.

Aqui está um potencial script de componente de tema com o qual eu começaria, se valer a pena modificar a área de </head> ou JS do tema Horizon (ou Padrão).


<script type="text/discourse-plugin" version="1.0">
  apiInitializer("1.34.0", (api) => {
    function texFromMathElement(el) {
      // MathJax v3/v4 comumente armazena a fonte em um filho de anotação.
      const annotation =
        el.querySelector('annotation[encoding="application/x-tex"]') ||
        el.querySelector('annotation');

      if (annotation?.textContent?.trim()) {
        const tex = annotation.textContent.trim();

        // Heurística: wrappers de bloco de matemática são frequentemente contêineres de exibição.
        const isBlock =
          el.tagName === "MJX-CONTAINER" &&
          (el.getAttribute("display") === "true" ||
            el.getAttribute("display") === "block");

        return isBlock ? `$$\n${tex}\n$$` : `$${tex}$`;
      }

      return null;
    }

    function patchMathInFragment(fragment) {
      const candidates = fragment.querySelectorAll(
        "mjx-container, .math, .katex, .MathJax"
      );

      candidates.forEach((node) => {
        const replacement = texFromMathElement(node);
        if (!replacement) {
          return;
        }

        const textNode = document.createTextNode(replacement);
        node.replaceWith(textNode);
      });

      return fragment;
    }

    api.modifyClass("component:quote-button", {
      pluginId: "ethan-math-quote-fix",

      _selectionChanged() {
        this._super(...arguments);

        try {
          const selection = window.getSelection();
          if (!selection || selection.rangeCount === 0) {
            return;
          }

          const range = selection.getRangeAt(0);
          const fragment = range.cloneContents();
          patchMathInFragment(fragment);

          const container = document.createElement("div");
          container.appendChild(fragment);

          // Substitui o buffer que o Discourse converte posteriormente em markdown de citação.
          if (this.quoteState) {
            this.quoteState.buffer = container.innerHTML;
          }
        } catch (e) {
          // Falha silenciosamente para que a citação normal ainda funcione.
          console.warn("Math quote patch failed:", e);
        }
      },
    });
  });
</script>

Algumas ressalvas importantes:

  • Este é um patch prático, não algo que encontrei publicado pela Meta. A estratégia subjacente é inferida do caminho da citação passando pelo HTML selecionado e paraMarkdown.
  • É mais provável que ajude quando estou usando o provedor MathJax, que é o padrão atual no Discourse Math, e a opção que costumo usar.
  • O script pode precisar de pequenos ajustes nos seletores, dependendo se a minha matemática renderizada acaba como mjx-container, .MathJax ou outro wrapper. Eu testaria em um site de staging, que seria uma nova instalação padrão.
  • É improvável que seja perfeito para todos os casos extremos, especialmente seleções mistas inline/bloco ou material citado aninhado.

Como o Discourse agora suporta oficialmente o KaTeX com CopyTex, outra abordagem é mudar o provedor se o meu principal ponto de dor for copiar a fonte LaTeX em vez da fidelidade de renderização. Isso não resolveria automaticamente a seleção de citação, mas significa que a matemática renderizada já tem um caminho mais amigável para cópia integrado.

Para o meu site com uso intensivo de MathJax, Physics with Ethan, estou atualmente pensando:

  • manter o MathJax, a menos que alguém sugira que eu mude para KaTeX? ,
  • talvez adicionar um patch de seleção de citação ao tema Horizon, a partir do acima (usando um site de staging).
  • e tratá-lo como uma correção local de qualidade de vida até que haja uma solução upstream adequada. Este tópico de recurso de 2020 ainda estar aberto em 2026 sugere que o upstream pode permanecer lento aqui.
3 curtidas