2016-12-13 1 views
1

J'écris un Pandoc JSON filter dans Haskell qui devrait transformer l'affichage mathématique LaTeX en SVG avec une application externe, alors que les maths en ligne LaTeX devraient être transformés en MathML par pandoc en interne.Filtre Pandoc imitant la conversion MathML par défaut

Le premier bit SVG fonctionne correctement; c'est le bit MathML qui devrait imiter le comportement standard pandoc qui me pose des problèmes. En parcourant Hackage, j'ai trouvé the texMathToMathML code example (voir ci-dessous). Cette fonction renvoie Either String Element.

Cependant, ce dont j'ai besoin est une fonction tex2mml (voir ci-dessous) retournant un IO String. Que faut-il ajouter à la définition de tex2mml pour y parvenir?

tex2mml latex = texMathToMathML DisplayInline latex 

Je fais cela sur (X) Ubuntu LTS 16.04 avec les pandoc 1.16.0.2 paquetages suivants:

$ sudo apt install pandoc libghc-pandoc-prof 

Voici un extrait de ce que je suis arrivé à ce jour:

#!/usr/bin/env runhaskell 

import Text.Pandoc.JSON 
import Control.Applicative ((<$>)) 
import Text.TeXMath (writeMathML, readTeX, DisplayType(DisplayInline)) 
import Text.XML.Light (Element) 


texMathToMathML :: DisplayType -> String -> Either String Element 
texMathToMathML dt s = writeMathML dt <$> readTeX s 


tex2mml :: String -> IO String 
tex2mml latex = texMathToMathML DisplayInline latex 


main :: IO() 
main = toJSONFilter tex2math 
    where tex2math (Math (DisplayMath) latex) = do 
      svg <- tex2svg latex 
      return (Math (DisplayMath) (svg)) 

     tex2math (Math (InlineMath) latex) = do 
      mml <- tex2mml latex 
      return (Math (InlineMath) (mml)) 

     tex2math other = return other 

S'il vous plaît, supporter avec moi, car je suis un débutant absolu Haskell. Toutes les suggestions pour améliorer le code sont les bienvenues!

+1

"C'est le bit MathML qui devrait imiter le comportement standard de pandoc qui me pose des problèmes." -> Pourquoi ne pas le laisser tel quel et laisser Pandoc le manipuler après que le filtre ait fonctionné? –

+1

@SergioCorreia Parce que, je lance 'pandoc' avec' --jsmath' au lieu de '--mathml' pour générer le SVG en utilisant MathJax. –

+1

@SergioCorreia J'ai vérifié deux fois. En effet, 'pandoc' effectue sa [conversion mathématique] (http://pandoc.org/MANUAL.html#math) _prior_ pour exposer son [' ToJSONFilter'] (https://hackage.haskell.org/package/pandoc- types-1.16.1.1/docs/Text-Pandoc-JSON.html). Pour autant que je sache, la solution ci-dessous est la seule façon d'y arriver. –

Répondre

2

Il est vrai que je ne suis pas familier avec Pandoc et le domaine problème, mais si bien compris le but de tex2mml fonction alors je crois que cela devrait obtenir ce que vous voulez:

import Control.Applicative ((<$>)) 
import Text.Pandoc.JSON 
import Text.TeXMath 
     (writeMathML, readTeX, DisplayType(DisplayInline)) 
import Text.XML.Light (Element,showElement) 

texMathToMathML :: DisplayType -> String -> Either String Element 
texMathToMathML dt s = writeMathML dt <$> readTeX s 

tex2mml :: String -> String 
tex2mml latex = either id showElement (texMathToMathML DisplayInline latex) 

-- actual definition of tex2svg goes here 
tex2svg = undefined 

main :: IO() 
main = toJSONFilter tex2math 
    where 
    tex2math :: Inline -> IO Inline 
    tex2math (Math DisplayMath latex) = do 
     svg <- tex2svg latex 
     return (Math DisplayMath svg) 
    tex2math (Math InlineMath latex) = return (Math InlineMath (tex2mml latex)) 
    tex2math other = return other 

Je suis en utilisant la fonction either à examiner le résultat de la fonction de conversion texMathToMathML - en cas d'échec, l'erreur est retournée telle quelle (id), en cas de succès showElement fonction est utilisée pour convertir Element en sa représentation de chaîne XML.

Cela pourrait aussi être réécrite en utilisant la correspondance de modèle si vous trouvez que plus clairement:

tex2mml :: String -> String 
tex2mml latex = case texMathToMathML DisplayInline latex of 
    Left err -> err 
    Right xml -> showElement xml 

Comme le calcul est pur, il n'a pas besoin d'être intégré dans IO monade, et le résultat peut être transmis directement dans le constructeur Math.

Il existe également d'autres fonctions dans le module Text.XML.Light.Output si vous souhaitez imprimer de manière assez précise la chaîne XML ou si vous souhaitez inclure un en-tête de document XML dans la sortie.

+0

Réponse exquise avec une excellente explication! J'en ai beaucoup appris. –