Very primitive filter lets your users use some of TeX/LaTeX commands in their postings.

"; break; } return t($output); } /** * Implementation of filter_filter(). */ function latex_filter($op, $delta = 0, $format = -1, $text = '') { switch ($op) { case 'list': return array(t('TeX/LaTeX')); case 'description': return t("Allows to use some elements of TeX/LaTeX."); case 'settings': $form['conf'] = array( '#type' => 'fieldset', '#title' => t('LaTeX filter'), '#collapsible' => TRUE, '#collapsed' => TRUE, ); $form['conf']['latex_filter_link'] = array( '#type' => 'select', '#title' => t("Recognize TeX/LaTeX commands"), '#default_value' => variable_get("latex_filter_link", 0), '#options' => array(t("Show unknown commands"), t("Strip unknown commands")), '#description' => t('Enable usage of TeX/LaTeX commands in user-distributed content.
If option set to "Strip unknown commands", then unrecognized TeX/LaTeX commands are not showed in output.
If option set to "Show unknown commands", then arguments of all unrecognized commands are showed in HTML-output.'), ); $form['conf']['latex_custom_commands'] = array( '#type' => 'textarea', '#title' => t("Extend LaTeX filter with your custom commands"), '#default_value' => variable_get("latex_custom_commands", ""), //'#cols' => 70, //'#rows' => 7, '#description' => t('Define your custom regexps (one per line) like this example: \link{(.*)}{(.*)}   <a href="$1">$2</a> - separate pattern part from replace parts with one space character. For inserting space in pattern part use numeric code "\040". '), ); return $form; case 'process': return _latex_filter_process($text); default: return $text; } } function _latex_filter_process($text) { // Save verbatims from conversions: $text = str_replace("\begin{verbatim}", "
", $text);
  $text = str_replace("\end{verbatim}", "
", $text); $text = preg_replace_callback("|
(.*)
|smU", "_latex_hash_verbatim", $text); // Convert some special characters: $text = str_replace("\TeX", "TEX", $text); $text = str_replace("\LaTeX", "LATEX", $text); $text = str_replace("\copyright", "©", $text); $text = str_replace("\dots", "…", $text); $text = str_replace("\ldots", "…", $text); $text = str_replace("\cdots", "…", $text); $text = str_replace("\pm", "±", $text); $text = str_replace("\div", "÷", $text); $text = str_replace("\le", "≤", $text); $text = str_replace("\ge", "≥", $text); $text = str_replace("\lt", "<", $text); $text = str_replace("\gt", ">", $text); $text = str_replace("``", '“', $text); $text = str_replace("''", '”', $text); $text = str_replace("\;", "   ", $text); // BUG: next two lines never pass to filter if Drupal HTML filtering ON and strip unknown tags $text = str_replace("<<", '«', $text); $text = str_replace(">>", '»', $text); $text = str_replace("~---", " —", $text); // I not sure for TeX standards for dash conversion, but Latex on my system eat such things and produce appropriate longdashes $text = str_replace(" ---", " —", $text); $text = str_replace(" --", " —", $text); $text = str_replace("-{}-", "--", $text); $text = str_replace("\ ", " ", $text); // Custom commands (from `latex_custom_commands` site variable): if ($lines = explode("\n", variable_get("latex_custom_commands", ""))) { foreach ($lines as $line) { if (! trim($line)) { continue; } list($pattern, $command) = split(' ', $line, 2); $text = preg_replace($pattern, $command, $text); } } // TeX comments -> HTML comments $text = preg_replace("/[^\\\]?%(.*)/iS", "", $text); // Text blocks: $text = str_replace("\begin{itemize}", "", $text); $text = preg_replace("/\\\begin{flush(left|right)}/U", '
', $text); $text = preg_replace("/\\\end{flush(left|right)}/U", '
', $text); // Skip these commands: $text = str_replace("\\\(begin|end){document}", "", $text); $text = str_replace("\\\documentclass.*{.*})", "", $text); $text = str_replace("\\\usepackage{.*}", "", $text); $text = str_replace("\\\thispagestyle{.*}", "", $text); $text = str_replace("\\\pagestyle{.*}", "", $text); // Captions: $text = preg_replace("/\\\section{(.*)}/U", "

$1

", $text); $text = preg_replace("/\\\subsection{(.*)}/U", "

$1

", $text); $text = preg_replace("/\\\subsubsection{(.*)}/U", "

$1

", $text); $text = preg_replace("/\\\subsubsubsection{(.*)}/U", "
$1
", $text); // Font styles: $text = preg_replace("/{\\\(em|it) (.*)}/U", "$2", $text); $text = preg_replace("/\\\\(emph|textit|textsl){(.*)}/U", "$2", $text); $text = preg_replace("/{\\\\tt (.*)}/U", "$1", $text); $text = preg_replace("/\\\\texttt{(.*)}/U", "$1", $text); $text = preg_replace("/{\\\bf (.*)}/U", "$1", $text); $text = preg_replace("/\\\\textbf{(.*)}/U", "$1", $text); $text = preg_replace("/{\\\textsc (.*)}/U", "$1", $text); // Footnotes: preg_match_all("/\\\footnote{((.)(.*))}/uUms", $text, $footnotes); if ($footnotes) { $text = preg_replace_callback("/\\\footnote{((.)(.*))}/uUms", "_latex_hash_name", $text); } // Unknown commands visibility: if (variable_get("latex_filter_link", 0) == 1) { // ignore unknown commands: $text = preg_replace("/\\\[a-z0-9\[\]]+{(.*)}/Ui", "", $text); } else { // show unknown commands $text = preg_replace("/\\\([a-z0-9\[\]]+){(.*)}/Ui", "\$1\{$2}", $text); } // Finally some miscellaneous conversions: // $text = preg_replace("/(
|<\/h[1-9]>|<\/[uo]l>)\s*$^\s*/ms", "$1", $text); // new paragraph if command on next line (need testing) //$text = preg_replace("/(.*)^\s*$/msU", "$1

", $text); // new paragraph in other cases // $text = preg_replace("/\\\(.){}/U", "$1", $text); // any single char escaped with \{} // $text = preg_replace("/\\\([#$%&_ ])/U", "$1", $text); // and other special chars // BR-conversions commented out, because it now dealed with HTML-filter $text = str_replace("\\", "
", $text); // EOL $text = str_replace("\backslash", "\\", $text); // Return to text previously saved verbatims: foreach (_latex_hash_verbatim() as $key => $value) { $text = str_replace($LATEX_VERBATIM_START_MAGIC. $key. $LATEX_VERBATIM_END_MAGIC, "
". $value. "
", $text); } if($footnotes) { $footnote = "
"; for ($i=0; $i< count($footnotes[1]); $i++) { $footnote .= "[". $footnotes[2][$i]. "] — ". $footnotes[1][$i]. "
"; } $footnote .= "\n"; } return $text . $footnote; } function _latex_hash_verbatim($matches = NULL) { static $verbatim = array(); if ($matches) { $verbatim = array(md5($matches[1]) => $matches[1]); return $LATEX_VERBATIM_START_MAGIC. md5($matches[1]). $LATEX_VERBATIM_END_MAGIC; } else { return $verbatim; } } function _latex_hash_name($matches) { return "[". $matches[2]. "]"; } ?>