wikiLinkReferences1 = array(); $this->wikiLinkReferences2 = array(); $this->mathMLelementsWikipediaLinksFileName = __DIR__ . '/AEHdata/mathMLelementsWikipediaLinks.txt'; $this->mathMLsymbolsWikipediaLinksFileName = __DIR__ . '/AEHdata/mathMLsymbolsWikipediaLinks.txt'; $this->latexSymbolsGreekFileName = __DIR__ . '/AEHdata/latexSymbolsGreek.txt'; $this->mathMLelementsWikipediaLinks = $this->readFileIntoArray($this->mathMLelementsWikipediaLinksFileName); $this->mathMLsymbolsWikipediaLinks = $this->readFileIntoArray($this->mathMLsymbolsWikipediaLinksFileName); $this->latexSymbolsGreek = $this->readFileIntoArray($this->latexSymbolsGreekFileName); $this->mathMLelementsWikipediaLinks = $this->flipDiagonally($this->mathMLelementsWikipediaLinks); $this->mathMLsymbolsWikipediaLinks = $this->flipDiagonally($this->mathMLsymbolsWikipediaLinks); $this->latexSymbolsGreek = $this->flipDiagonally($this->latexSymbolsGreek); } public function mathmlAEHpreprocessContent($tex) { //printArray($tex); //test case: //case 1. match wiki links corresponding to special latex symbols (e.g. "... \alpha[[Fine-structure constant]] ...") preg_match_all('/\\\\(\w+)\[\[(.+?)\]\]/', $tex, $this->wikiLinkReferences1); //4 '\' required to match '\' $this->wikiLinkReferences1 = $this->flipDiagonally($this->wikiLinkReferences1); $tex = $this->removeWikiReferences($this->wikiLinkReferences1, $tex); //case 2. match wiki links corresponding to single alphanumeric characters (e.g. "... c[[quadratic equation#constant]] ...") preg_match('/([a-zA-Z])\[\[(.+?)\]\]/', $tex, $this->wikiLinkReferences2); //4 '\' required to match '\' $this->wikiLinkReferences2 = $this->flipDiagonally($this->wikiLinkReferences2); $tex = $this->removeWikiReferences($this->wikiLinkReferences2, $tex); //printArray($tex); return $tex; } public function mathmlAEHpostprocessContent($mathml) { //printArray($mathml); $dom = new DOMDocument(); $dom->preserveWhiteSpace = false; $dom->formatOutput = true; $dom->loadXML($mathml); //add all explicit latex links[[]] to MathML symbols $this->addHTMLlinksForAllExplicitLatexLinks($dom); //add all predefined links to MathML symbols $rootElement = $dom->documentElement; $this->addHTMLlinksForAllPredefinedMathMLsymbols($rootElement); //add all predefined links to MathML elements $this->addHTMLlinksForAllPredefinedMathMLelements($dom); $mathml = $dom->saveXML(); //printArray($mathml); return $mathml; } private function addHTMLlinksForAllExplicitLatexLinks($dom) { foreach($this->mathmlElementsSupportingWikiLinkReferenceVariables as $mathmlElement) { $mathmlNodesFound = $dom->getElementsByTagName($mathmlElement); foreach($mathmlNodesFound as $mathmlNode) { $symbolHTML = $this->DOMinnerHTML($mathmlNode); //NB $mathmlNode->nodeValue can't be used because it will return the comment contents if the node contains a comment $symbolHTML = $this->removeHtmlComments($symbolHTML); $symbolLatex = $this->convertGreekHTMLSymbolToLatex($symbolHTML); $this->addWikiLinkToElement($mathmlNode, $symbolLatex, $this->wikiLinkReferences1); $this->addWikiLinkToElement($mathmlNode, $symbolHTML, $this->wikiLinkReferences2); } } } private function addHTMLlinksForAllPredefinedMathMLelements($dom) { foreach($this->mathMLelementsWikipediaLinks as $mathMLelementsWikipediaLink) { $mathMLelement = $mathMLelementsWikipediaLink[0]; $wikiTitle = $mathMLelementsWikipediaLink[1]; $mathmlNodesFound = $dom->getElementsByTagName($mathMLelement); foreach($mathmlNodesFound as $mathmlNode) { $this->addHtmllinkToElement($mathmlNode, $wikiTitle); } } } private function addHTMLlinksForAllPredefinedMathMLsymbols($node) { if($node->hasChildNodes()) { foreach($node->childNodes as $n) { $this->addHTMLlinksForAllPredefinedMathMLsymbols($n); } } //process leaves $foundValidElement = false; foreach($this->mathmlElementsSupportingWikiLinkReferenceVariables as $mathmlElement) { if($node->nodeName == $mathmlElement) { $foundValidElement = true; } } if($foundValidElement) { foreach($this->mathMLsymbolsWikipediaLinks as $mathMLsymbolsWikipediaLink) { $mathMLsymbol = $mathMLsymbolsWikipediaLink[0]; $wikiTitle = $mathMLsymbolsWikipediaLink[1]; if(substr($mathMLsymbol, 0, 3) == "") {//is hex $mathMLsymbol = strtoupper($mathMLsymbol); $mathMLsymbol{2} = strtolower(($mathMLsymbol{2})); //converts "" back to "" } $symbolHTML = $this->DOMinnerHTML($node); //NB $node->nodeValue can't be used because it will return the comment contents if the node contains a comment $symbolHTML = $this->removeHtmlComments($symbolHTML); if($symbolHTML == $mathMLsymbol) { $this->addHtmllinkToElement($node, $wikiTitle); } } } } private function removeHtmlComments($content = '') { return preg_replace('//', '', $content); } private function convertHtmlCharacterDecimalToHex($symbolHTML) { preg_match_all('/([0-9]+);/', $symbolHTML, $symbolHTMLdecimalComponentArray); $symbolHTMLdecimalComponentArray = $this->flipDiagonally($symbolHTMLdecimalComponentArray); foreach($symbolHTMLdecimalComponentArray as $symbolHTMLdecimalComponent) { if(!empty($symbolHTMLdecimalComponent)) { $symbolHTMLhexComponent = dechex($symbolHTMLdecimalComponent[1]); $symbolHTMLhexComponent = strtoupper($symbolHTMLhexComponent); $findString = '' . $symbolHTMLdecimalComponent[1] . ';'; $replaceString = '' . $symbolHTMLhexComponent . ';'; $symbolHTML = str_replace($findString, $replaceString, $symbolHTML); } } return $symbolHTML; } private function addWikiLinkToElement($mathmlNode, $elementValue, $wikiLinkReferences) { foreach($wikiLinkReferences as $key => $wikiLinkReferencesEntry) { if(!empty($wikiLinkReferencesEntry)) { $mathSymbol = $wikiLinkReferencesEntry[1]; $wikiTitle = $wikiLinkReferencesEntry[2]; if($mathSymbol == $elementValue) { $this->addHtmllinkToElement($mathmlNode, $wikiTitle); } } } } private function addHtmllinkToElement($mathmlNode, $wikiTitle) { //do not overwrite existing html link $linkAlreadyAdded = false; for ($i = 0; $i < $mathmlNode->attributes->length; ++$i) { $node = $mathmlNode->attributes->item($i); if($node->nodeName == 'href') { $linkAlreadyAdded = true; } } if(!$linkAlreadyAdded) { $wikiLink = $this->generateWikiLinkFromTitle($wikiTitle); $valid_attr = $mathmlNode->ownerDocument->createAttribute('href'); $valid_attr->value = $wikiLink; $mathmlNode->appendChild($valid_attr); } } private function generateWikiLinkFromTitle($wikiTitle) { $wikiTitleWithUnderscores = str_replace(' ', '_', $wikiTitle); //CHECKTHIS; check this is sufficient $wikiLink = "https://en.wikipedia.org/wiki/" . $wikiTitleWithUnderscores; return $wikiLink; } //original source: http://stackoverflow.com/questions/797251/transposing-multidimensional-arrays-in-php private function flipDiagonally($arr) { $out = array(); if($this->countDimensions($arr) > 1) { foreach($arr as $key => $subarr) { foreach ($subarr as $subkey => $subvalue) { $out[$subkey][$key] = $subvalue; } } } else { $out[] = $arr; //make 1D array into 2D array } return $out; } //original source: http://stackoverflow.com/questions/2122211/determine-number-of-dimensions-in-a-php-array private function countDimensions($arr) { if(is_array(reset($arr))) { $return = $this->countDimensions(reset($arr)) + 1; } else { $return = 1; } return $return; } private function removeWikiReferences($wikiLinkReferences, $tex) { foreach($wikiLinkReferences as $key => $wikiLinkReferencesEntry) { if(!empty($wikiLinkReferencesEntry)) { $wikiTitle = $wikiLinkReferencesEntry[2]; $wikiTitleWithBrackets = "[[" . $wikiTitle . "]]"; $tex = str_replace($wikiTitleWithBrackets, '', $tex); //replace all occurances (in case the user has specified the wiki link for a given variable more than once; which is unnecessary) } } return $tex; } private function DOMinnerHTML(DOMNode $element) { $innerHTML = ""; if($element->hasChildNodes()) { $children = $element->childNodes; foreach($children as $child) { $innerHTML .= $element->ownerDocument->saveHTML($child); } } else { $innerHTML = $element->nodeValue; } return $innerHTML; } private function readFileIntoArray($filename) { $array = array(); foreach(file($filename) as $line) { // use trim to remove the end of line sequence $rowArray = explode($this->AEHtextFileDelimiter, trim($line)); $array[0][]= $rowArray[0]; if(count($rowArray) > 1) { $array[1][]= $rowArray[1]; } else { $array[1][]= $this->AEHtextFileCellEmpty; } } return $array; } private function convertGreekHTMLSymbolToLatex($symbolHTMLtoConvert) { $symbolLatexFound = $symbolHTMLtoConvert; foreach($this->latexSymbolsGreek as $symbol) { $symbolLatex = $symbol[0]; $symbolHTML = $symbol[1]; $symbolHTML = $this->convertHtmlCharacterDecimalToHex($symbolHTML); if($symbolHTMLtoConvert === $symbolHTML) { $symbolLatexFound = $symbolLatex; } } return $symbolLatexFound; } } function printArray($arr) { print("
"); print_r($arr); print(""); //exit; }