Initial commit
This commit is contained in:
parent
9abe18f886
commit
b9078dcf5b
126
TextformatterLatexMathML.module
Normal file
126
TextformatterLatexMathML.module
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
<?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' => '1.0.0',
|
||||||
|
'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);
|
||||||
|
|
||||||
|
// 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');
|
||||||
|
|
||||||
|
// $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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user