130 lines
3.9 KiB
Plaintext
130 lines
3.9 KiB
Plaintext
<?php
|
|
/*
|
|
Copyright (C) 2023 by 7u83 7u83@mail.ru
|
|
|
|
Permission to use, copy, modify, and/or distribute this software
|
|
for any purpose with or without fee is hereby granted.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
|
|
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
|
|
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
|
|
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
|
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
|
|
DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
|
|
*/
|
|
|
|
namespace ProcessWire;
|
|
|
|
class TextFormatterLatexMathML extends Textformatter {
|
|
|
|
public static function getModuleInfo() {
|
|
|
|
return array(
|
|
'title' => 'LatexMathML Text Formatter',
|
|
'version' => '0.9.1',
|
|
'summary' => 'Replaces $latexformula$ with inline MathML',
|
|
'author' => '7u83',
|
|
'autoload' => true,
|
|
'singular' => true,
|
|
'href' => 'https://git.planix.org/7u83/processwire-TextformatterLatexMathML',
|
|
'requires' => array('ProcessWire>=3.0.0'),
|
|
);
|
|
}
|
|
|
|
public function format(&$str) {
|
|
|
|
// Regular expression to match LaTeX formulas within $ symbols
|
|
$latexPattern = '/(?<!\\\\)\$([^$\\\\]*(\\\\.[^$\\\\]*)*)\$/';
|
|
|
|
$inputString = $str;
|
|
|
|
// Create a DOMDocument object
|
|
$dom = new \DOMDocument('1.0', 'UTF-8');
|
|
|
|
// Load the HTML string into the DOMDocument
|
|
$dom->loadHTML('<?xml encoding="utf-8" ?><html>'.$inputString.'</html>', LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
|
|
|
|
// Create a DOMXPath object to navigate the DOMDocument
|
|
$xpath = new \DOMXPath($dom);
|
|
|
|
// Find all <p>, <div>, <span> ... elements
|
|
$elements = $xpath->query('//p | //div | //span | //strong | //b | //i | //em');
|
|
|
|
|
|
$nodesForReplacement = array();
|
|
|
|
// Iterate through the elements and create and arraz of nodes to modify
|
|
foreach ($elements as $element) {
|
|
foreach ($element->childNodes as $node) {
|
|
if ($node->nodeType === XML_TEXT_NODE) {
|
|
|
|
// convert $formula$ to mathml
|
|
$modifiedValue = preg_replace_callback($latexPattern, array($this,'convertToMathML'), $node->nodeValue);
|
|
|
|
// unescape esaped $-signs
|
|
$modifiedValue = str_replace('\$', '$',$modifiedValue);
|
|
|
|
$modifiedValue = str_replace('&','&',$modifiedValue);
|
|
|
|
// Save the node and its modified content for later replacement
|
|
$nodesForReplacement[] = array(
|
|
'node' => $node,
|
|
'modifiedValue' => $modifiedValue
|
|
);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
// Replace the nodes
|
|
foreach ($nodesForReplacement as $replacement) {
|
|
$fragment = $dom->createDocumentFragment();
|
|
$fragment->appendXML($replacement['modifiedValue']);
|
|
$replacement['node']->parentNode->replaceChild($fragment, $replacement['node']);
|
|
}
|
|
|
|
|
|
// Output the modified HTML
|
|
$str = str_replace(array('<html>','</html>') , '' , $dom->saveHTML($dom->documentElement));
|
|
}
|
|
|
|
// Define a callback function to convert the matched formula to MathML
|
|
function convertToMathML($matches) {
|
|
$cache = wire('cache');
|
|
# $cache->deleteAll();
|
|
|
|
// $matches[1] contains the matched substring within '$'
|
|
$formula = $matches[1];
|
|
|
|
$cn = "TFLatexMathML$formula";
|
|
$mathml = base64_decode($cache->get($cn));
|
|
if ($mathml)
|
|
return $mathml;
|
|
|
|
$mathml = $this->convertFormulaToMathML($formula);
|
|
$cache->save($cn,base64_encode($mathml));
|
|
|
|
// Return the processed result as the replacement
|
|
return $mathml;
|
|
}
|
|
|
|
// Function to convert a formula to MathML
|
|
function convertFormulaToMathML($formula) {
|
|
|
|
$command = 'latexmlmath --quiet -';
|
|
$inputString = '$'.$formula.'$';
|
|
|
|
|
|
// Construct the full command with the input string
|
|
$fullCommand = sprintf('echo %s | %s', escapeshellarg($inputString), $command);
|
|
|
|
|
|
// Execute the command and capture the output
|
|
$output = shell_exec($fullCommand);
|
|
|
|
return $output;
|
|
}
|
|
}
|
|
|