• Thank you for the plugin! Have been using it for years on several websites. But those did not use mathematics whereas a new site that I’m working on does (in the form of MathJax), so I discovered the following issue: If I use inline LaTeX code with MathJax, something like

    “…where $\gamma$ is a parameter …”

    then $\gamma$ turns into $\gam&shy;ma$. Since \gamma has no wrapper apart from $ … $, I cannot use the class ignore feature unless I wrap it into a separate <span class=”something”></span> which is a pain most of the time. As the author of the plugin, perhaps, you would have other suggestions?

Viewing 13 replies - 16 through 28 (of 28 total)
  • Thread Starter Aleksei Tepljakov

    (@firelord)

    Hi @pputzer, can we return to this discussion? Regrettably I didn’t have time to do anything with my website, and it’s not yet public, but that again there’s a chance the problem described above could be fixed before the official release.

    Above you mentioned some new filter hooks. Is that a thing already or…?

    Plugin Author pepe

    (@pputzer)

    @firelord Thanks for reminding me. Unfortunately, I’ve put this issue on the back burner a bit as well. (I’d need to replicate things in a test environment to be able to provide a solution. I’ll check out your plugin tonight.)

    Plugin Author pepe

    (@pputzer)

    Hi @firelord, implementing this properly is harder than I thought, because the underlying PHP-Typography library would have to be changed. However, I’ve a “probably good enough” proof-of-concept here that works with the current version of the plugin.

    Warning: This is not production-quality code. At the very least, the functions and the global will need to be prefixed (better yet, they should be refactored as a class).

    
    add_filter( 'typo_custom_characters_node_fix', 'mask_latex_equations', 10, 4 );
    add_filter( 'typo_custom_html_insertion_node_fix', 'reveal_latex_equations', 10, 4 );
    
    $latex_equations = [];
    
    function mask_latex_equations( $nodedata, $textnode, $settings, $is_title ) {
    	global $latex_equations;
    
    	if ( preg_match_all( '/(?:\A|\s)(\$[^\$]+\$)(?:\s|\Z)/', $nodedata, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE ) ) {
    		$mask        = '__MASKED_LATEX__';
    		$mask_length = strlen( $mask );
    		$offset      = 0;
    
    		foreach( $matches as $match ) {
    			$equation       = $match[1][0];
    			$length         = strlen( $equation );
    			$applied_offset = $offset + $match[1][1];
    
    			// Store equation.
    			$latex_equations[ spl_object_id( $textnode ) ][] = $equation;
    
    			// Replace equation with mask.
    			$nodedata = substr_replace( $nodedata, $mask, $applied_offset, $length );
    
    			// Fix matched offset.
    			$offset += $mask_legth - $length;
    		}
    	}
    
    	return $nodedata;
    }
    
    function reveal_latex_equations( $nodedata, $textnode, $settings, $is_title ) {
    	global $latex_equations;
    
    	$key = spl_object_id( $textnode );
    	if ( ! empty( $latex_equations[ $key ] ) ) {
    		$mask        = '__MASKED_LATEX__';
    		$mask_length = strlen( $mask );
    
    		foreach ( $latex_equations[ $key ] as $equation ) {
    			$pos = strpos( $nodedata, $mask );
    			if ( $pos !== false ) {
    				$nodedata = substr_replace( $nodedata, $equation, $pos, $mask_length );
    			}
    
    		}
    	}
    
    	return $nodedata;
    }
    
    Thread Starter Aleksei Tepljakov

    (@firelord)

    Cool, thanks. I’ll give it a go as soon as I can.

    Plugin Author pepe

    (@pputzer)

    @firelord Have you been able to check out the proof-of-concept?

    Thread Starter Aleksei Tepljakov

    (@firelord)

    Tried using the filter hooks, no go. Let me know how you applied this in your setup.
    What’s more important, I realied just now that I apparently only targeted inline math $like=this$, but displayed equations also suffer from automatic insertion of ­ like $$myequation=1$$ or \[this=0\].
    This thing becomes more complicated by the minute.

    Plugin Author pepe

    (@pputzer)

    I put the code into into a MU plugin, but should work in functions.php as well. You can add error_log() calls to check if the filters are actually called.

    Thread Starter Aleksei Tepljakov

    (@firelord)

    Ok, here’s a solution. It only works for math enclosed in \( math \) (inline) and \[ math \] (displayed). Dollar signs are too much of a hassle to implement properly.

    
    function fixWpTypoMathCompat($content) {
                preg_match_all('/\\\\\[(?!\\\\\]).*?\\\\\]/s', $content, $result, PREG_PATTERN_ORDER);
                for ($i = 0; $i < count($result[0]); $i++) {
                    for ($i = 0; $i < count($result[0]); $i++) {
                        $now_eq = $result[0][$i];
                        $content = str_replace($now_eq, "<div class=\"lire-equation\">" . $result[0][$i] . "</div>", $content);
                    }
                }
    
                preg_match_all('/\\\\\((?!\\\\\)).*?\\\\\)/s', $content, $result, PREG_PATTERN_ORDER);
                for ($i = 0; $i < count($result[0]); $i++) {
                    $now_eq = $result[0][$i];
                    $content = str_replace($now_eq, "<span class=\"lire-equation\">" . $result[0][$i] . "</span>", $content);
                }
                return $content;
            }
    

    Added this as action with default priority to my plugin and then set up an option in wp-typography to ignore lire-equation class. Seems to be working. Will test further.

    Thread Starter Aleksei Tepljakov

    (@firelord)

    Added support for “dollarsigned” inline math as well.
    But now there’s also the issue with \begin{env} ... \end{env}. Will have to figure out a regex for handling that as well, hopefully for a general env and not for equation, align, etc. separately.

    Plugin Author pepe

    (@pputzer)

    I’m glad to hear you have been able to make this work, though I have doubts that generalizing this will really be feasible. It would amount to LaTeX parsing with regular expressions, and I’m not sure that’s technically possible.

    I’m assuming you use the_content hook for your filter? My approach might have been overkill, but I used wp-Typography’s processing hooks to get access to the parsed HTML DOM, skipping all HTML elements and dealing only with plain text nodes. While my PoC was limited to the $something$ notation, it should be adaptable to other markers.

    Thread Starter Aleksei Tepljakov

    (@firelord)

    That’s right. I do it like this:

    if (defined("LIRE_USE_WITH_WP_TYPOGRAPHY") && LIRE_USE_WITH_WP_TYPOGRAPHY === true) {
            add_action('the_content', array(&$wpLire, 'fixWpTypoMathCompat'), 1);
        }

    And I’ve also come up with updated code that also takes into account \begin{env}...\end{env}. I guess for completeness I should also do $$...$$, but that can probably wait. For reference, this is what I have now:

    define("LIRE_USE_WITH_WP_TYPOGRAPHY", true);
    define("LIRE_FIX_DOLLAR_INLINE_MATH_WP_TYPOGRAPHY", true);
    define("LIRE_FIX_ENVS_WP_TYPOGRAPHY", true);
    
    function fixWpTypoMathCompat($content) {
    
                // Display equations \[ ... \]
                preg_match_all('/\\\\\[(?!\\\\\]).*?\\\\\]/s', $content, $result, PREG_PATTERN_ORDER);
                for ($i = 0; $i < count($result[0]); $i++) {
                    for ($i = 0; $i < count($result[0]); $i++) {
                        $now_eq = $result[0][$i];
                        $content = str_replace($now_eq, "<div class=\"lire-equation\">" . $result[0][$i] . "</div>", $content);
                    }
                }
                
                // Environments such as \begin{equation} ... \end{equation}
                if (defined("LIRE_FIX_ENVS_WP_TYPOGRAPHY") && LIRE_FIX_ENVS_WP_TYPOGRAPHY === true) {
                    preg_match_all('/\\\\begin{([A-Za-z]+\*?)}.+?\\\\end{\g{1}}/s', $content, $result, PREG_PATTERN_ORDER);
                    for ($i = 0; $i < count($result[0]); $i++) {
                        $now_eq = $result[0][$i];
                        $content = str_replace($now_eq, "<div class=\"lire-equation\">" . $result[0][$i] . "</div>", $content);
                    }
                }
    
                // Inline equations \( ... \)
                preg_match_all('/\\\\\((?!\\\\\)).*?\\\\\)/s', $content, $result, PREG_PATTERN_ORDER);
                for ($i = 0; $i < count($result[0]); $i++) {
                    $now_eq = $result[0][$i];
                    $content = str_replace($now_eq, "<span class=\"lire-equation\">" . $result[0][$i] . "</span>", $content);
                }
    
                // Inline equations $ ... $
                if (defined("LIRE_FIX_DOLLAR_INLINE_MATH_WP_TYPOGRAPHY") && LIRE_FIX_DOLLAR_INLINE_MATH_WP_TYPOGRAPHY === true) {
                    preg_match_all('/(?<!\\\\)\$((?:\\\\[^\n\r\x{2028}\x{2029}]|[^$])*)(?<!\\\\)\$/u', $content, $result, PREG_PATTERN_ORDER);
                    for ($i = 0; $i < count($result[0]); $i++) {
                        $now_eq = $result[0][$i];
                        $content = str_replace($now_eq, "<span class=\"lire-equation\">" . $result[0][$i] . "</span>", $content);
                    }
                }
    
                return $content;
            }
    

    What would be really cool is if you could add lire-equation as a default ignored class when you update the plugin. Or, maybe suggest some other class name that would be more generic, I’m open to suggestions as I can easily change the class name in my plugin.

    Plugin Author pepe

    (@pputzer)

    The noTypo class is ignored by default. If you want to have specialized class for styling the equations, just add both (class="lire-equation noTypo"). Or you can add custom ignored classes via the settings.

    Thread Starter Aleksei Tepljakov

    (@firelord)

    Good point. Basically, I think we can finally consider this issue resolved ??

Viewing 13 replies - 16 through 28 (of 28 total)
  • The topic ‘Plugin interferes with inline parsing of mathematical formulae’ is closed to new replies.