MathML Block - Version 1.2.0

Version Description

  • Add AMP compatibility, props @westonruter. Leverages the amp-mathml component.
Download this release

Release Info

Developer adamsilverstein
Plugin Icon 128x128 MathML Block
Version 1.2.0
Comparing to
See all releases

Code changes from version 1.1.5 to 1.2.0

Files changed (3) hide show
  1. README.md +1 -0
  2. mathml-block.php +164 -30
  3. readme.txt +7 -2
README.md CHANGED
@@ -4,6 +4,7 @@
4
 
5
  * Enables MathML math formulas blocks in the editor.
6
  * Uses the MathJax library to render the formulas: https://www.mathjax.org
 
7
 
8
  ### What is MathML?
9
 
4
 
5
  * Enables MathML math formulas blocks in the editor.
6
  * Uses the MathJax library to render the formulas: https://www.mathjax.org
7
+ * Compatible with the [official AMP plugin](https://amp-wp.org/) by rendering [`amp-mathml`](https://amp.dev/documentation/components/amp-mathml/) on [AMP pages](https://amp.dev/).
8
 
9
  ### What is MathML?
10
 
mathml-block.php CHANGED
@@ -5,7 +5,7 @@
5
  * Version: 1.1.5
6
  * Requires at least: 5.0
7
  * Tested up to: 5.5
8
- * Requires PHP: 5.4
9
  * Stable tag: trunk
10
  * Author: adamsilverstein
11
  * Author URI: http://tunedin.net
@@ -14,12 +14,64 @@
14
  *
15
  * @package mathml-block
16
  */
 
17
  namespace MathMLBlock;
18
 
19
- /**
20
- * Enqueue the admin JavaScript assets.
21
- */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
  function mathml_block_enqueue_scripts() {
 
23
 
24
  wp_enqueue_script(
25
  'mathml-block',
@@ -28,45 +80,127 @@ function mathml_block_enqueue_scripts() {
28
  '',
29
  true
30
  );
 
 
31
 
32
- // Maka JavaScript translatable.
33
- wp_set_script_translations( 'mathml-block', 'mathml-block' );
 
 
 
 
 
34
 
35
- // Filter the MathJax config string.
36
- $config_string = apply_filters( 'mathml_block_mathjax_config', 'TeX-MML-AM_CHTML' );
37
 
38
- wp_enqueue_script(
39
- 'mathjax',
40
- 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/MathJax.js?config=' . $config_string
 
 
 
 
41
  );
42
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  }
44
- add_action( 'enqueue_block_editor_assets', __NAMESPACE__ . '\mathml_block_enqueue_scripts' );
45
 
46
  /**
47
- * Potentially enqueue the front end mathjax script, if any mathml blocks are detected in the content.
 
 
 
 
 
48
  */
49
- function potentially_add_front_end_mathjax_script() {
50
- global $post;
51
-
52
- // Only apply on singular pages.
53
- if ( ! is_singular() ) {
54
- return;
55
  }
 
 
56
 
57
- // Check the content for mathml blocks.
58
- $has_mathml_block = strpos( $post->post_content, 'wp:mathml/mathmlblock' );
59
- $has_mathml_inline = strpos( $post->post_content, '<mathml>' );
60
- if ( false === $has_mathml_block && false === $has_mathml_inline ) {
61
- return;
 
 
 
 
 
 
 
 
62
  }
63
 
64
- // Filter the MathJax config string.
65
- $config_string = apply_filters( 'mathml_block_mathjax_config', 'TeX-MML-AM_CHTML' );
 
 
 
 
 
 
 
 
 
66
 
67
- // Enqueue the MathJax script for front end formula display.
68
- wp_register_script( 'mathjax', 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/MathJax.js?config=' . $config_string );
69
- wp_enqueue_script( 'mathjax' );
 
 
 
 
 
 
 
 
 
 
70
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
71
  }
72
- add_action( 'wp_enqueue_scripts', __NAMESPACE__ . '\potentially_add_front_end_mathjax_script' );
5
  * Version: 1.1.5
6
  * Requires at least: 5.0
7
  * Tested up to: 5.5
8
+ * Requires PHP: 5.6
9
  * Stable tag: trunk
10
  * Author: adamsilverstein
11
  * Author URI: http://tunedin.net
14
  *
15
  * @package mathml-block
16
  */
17
+
18
  namespace MathMLBlock;
19
 
20
+ use WP_Block_Type_Registry;
21
+ use WP_Scripts;
22
+
23
+ const BLOCK_NAME = 'mathml/mathmlblock';
24
+
25
+ const MATHJAX_SCRIPT_HANDLE = 'mathjax';
26
+
27
+ const MATHJAX_SCRIPT_URL = 'https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/MathJax.js';
28
+
29
+ /**
30
+ * Determine whether the response will be an AMP page.
31
+ *
32
+ * @return bool
33
+ */
34
+ function is_amp() {
35
+ return (
36
+ ( function_exists( 'amp_is_request' ) && \amp_is_request() )
37
+ ||
38
+ ( function_exists( 'is_amp_endpoint' ) && \is_amp_endpoint() )
39
+ );
40
+ }
41
+
42
+ /**
43
+ * Register MathJax script.
44
+ *
45
+ * @param WP_Scripts $scripts Scripts.
46
+ */
47
+ function register_mathjax_script( WP_Scripts $scripts ) {
48
+
49
+ /**
50
+ * Filters the MathJax config string.
51
+ *
52
+ * @param string $config MathHax config.
53
+ */
54
+ $config_string = apply_filters( 'mathml_block_mathjax_config', 'TeX-MML-AM_CHTML' );
55
+
56
+ $src = add_query_arg(
57
+ array(
58
+ 'config' => rawurlencode( $config_string )
59
+ ),
60
+ MATHJAX_SCRIPT_URL
61
+ );
62
+
63
+ $scripts->add( MATHJAX_SCRIPT_HANDLE, $src, array(), null, false );
64
+
65
+ // Make JavaScript translatable.
66
+ $scripts->set_translations( MATHJAX_SCRIPT_HANDLE, 'mathml-block' );
67
+ }
68
+ add_action( 'wp_default_scripts', __NAMESPACE__ . '\register_mathjax_script' );
69
+
70
+ /**
71
+ * Enqueue the admin JavaScript assets.
72
+ */
73
  function mathml_block_enqueue_scripts() {
74
+ wp_enqueue_script( MATHJAX_SCRIPT_HANDLE );
75
 
76
  wp_enqueue_script(
77
  'mathml-block',
80
  '',
81
  true
82
  );
83
+ }
84
+ add_action( 'enqueue_block_editor_assets', __NAMESPACE__ . '\mathml_block_enqueue_scripts' );
85
 
86
+ /**
87
+ * Register block.
88
+ */
89
+ function register_block() {
90
+ if ( ! function_exists( 'register_block_type' ) ) {
91
+ return;
92
+ }
93
 
94
+ $registry = WP_Block_Type_Registry::get_instance();
 
95
 
96
+ // @todo This can probably be de-duplicated in the JS code with registerBlockType.
97
+ $attributes = array(
98
+ 'formula' => array(
99
+ 'source' => 'html',
100
+ 'selector' => 'div',
101
+ 'type' => 'string',
102
+ ),
103
  );
104
 
105
+ if ( $registry->is_registered( BLOCK_NAME ) ) {
106
+ $block = $registry->get_registered( BLOCK_NAME );
107
+ $block->render_callback = __NAMESPACE__ . '\render_block';
108
+ $block->attributes = array_merge( $block->attributes, $attributes );
109
+ } else {
110
+ register_block_type(
111
+ BLOCK_NAME,
112
+ [
113
+ 'render_callback' => __NAMESPACE__ . '\render_block',
114
+ 'attributes' => $attributes,
115
+ ]
116
+ );
117
+ }
118
  }
119
+ add_action( 'init', __NAMESPACE__ . '\register_block' );
120
 
121
  /**
122
+ * Add async attribute to MathJax script tag.
123
+ *
124
+ * @param string $tag Script tag.
125
+ * @param string $handle Script handle.
126
+ *
127
+ * @return string Script tag.
128
  */
129
+ function add_async_to_mathjax_script_loader_tag( $tag, $handle ) {
130
+ if ( MATHJAX_SCRIPT_HANDLE === $handle ) {
131
+ $tag = preg_replace( '/(?<=<script\s)/', ' async ', $tag );
 
 
 
132
  }
133
+ return $tag;
134
+ }
135
 
136
+ /**
137
+ * Render block.
138
+ *
139
+ * Creates an <amp-mathml> element on AMP responses.
140
+ *
141
+ * @param array $attributes Attributes.
142
+ * @param string $content Content.
143
+ *
144
+ * @return string Rendered block.
145
+ */
146
+ function render_block( $attributes, $content = '' ) {
147
+ if ( is_admin() || ! preg_match( '#^(?P<start_div>\s*<div.*?>)(?P<formula>.+)(?P<end_div></div>\s*)$#s', $content, $matches ) ) {
148
+ return $content;
149
  }
150
 
151
+ if ( is_amp() ) {
152
+ static $printed_style = false;
153
+ if ( ! $printed_style ) {
154
+ // Add same margins as .MJXc-display.
155
+ ?>
156
+ <style class="amp-mathml">
157
+ .wp-block-mathml-mathmlblock amp-mathml { margin: 1em 0; }
158
+ </style>
159
+ <?php
160
+ $printed_style = true;
161
+ }
162
 
163
+ return sprintf(
164
+ '%s<amp-mathml layout="container" data-formula="%s"><span placeholder>%s</span></amp-mathml>%s',
165
+ $matches['start_div'],
166
+ esc_attr( $matches['formula'] ),
167
+ esc_html( $matches['formula'] ),
168
+ $matches['end_div']
169
+ );
170
+ } elseif ( ! wp_script_is( MATHJAX_SCRIPT_HANDLE, 'done' ) ) {
171
+ ob_start();
172
+ add_filter( 'script_loader_tag', __NAMESPACE__ . '\add_async_to_mathjax_script_loader_tag', 10, 2 );
173
+ wp_scripts()->do_items( MATHJAX_SCRIPT_HANDLE );
174
+ remove_filter( 'script_loader_tag', __NAMESPACE__ . '\add_async_to_mathjax_script_loader_tag' );
175
+ $scripts = ob_get_clean();
176
 
177
+ $content = $matches['start_div'] . $matches['formula'] . $scripts . $matches['end_div'];
178
+ }
179
+ return $content;
180
+ }
181
+
182
+ /**
183
+ * Filter content to transform inline math.
184
+ *
185
+ * @param string $content Content.
186
+ * @return string Replaced content.
187
+ */
188
+ function filter_content( $content ) {
189
+ return preg_replace_callback(
190
+ '#(?P<start_tag><mathml>)(?P<formula>.+)(?P<end_tag></mathml>)#s',
191
+ static function ( $matches ) {
192
+ if ( is_amp() ) {
193
+ return sprintf(
194
+ '<amp-mathml layout="container" data-formula="%s" inline><span placeholder>%s</span></amp-mathml>',
195
+ esc_attr( $matches['formula'] ),
196
+ esc_html( $matches['formula'] )
197
+ );
198
+ } else {
199
+ wp_enqueue_script( MATHJAX_SCRIPT_HANDLE );
200
+ return $matches['start_tag'] . $matches['formula'] . $matches['end_tag'];
201
+ }
202
+ },
203
+ $content
204
+ );
205
  }
206
+ add_filter( 'the_content', __NAMESPACE__ . '\filter_content', 20 );
readme.txt CHANGED
@@ -6,7 +6,7 @@ Tags: MathML, Gutenberg, Block, math, block editor
6
  Requires at least: 5.0
7
  Tested up to: 5.5
8
  Requires PHP: 5.6
9
- Stable tag: trunk
10
  License: GPLv2 or later
11
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
12
  Text Domain: mathml-block
@@ -32,9 +32,11 @@ To test a MathML block and enter a formula, for example: `\[x = {-b \pm \sqrt{b^
32
 
33
  To test using math formulas inline, type an formula into a block of text, select it and hit the 'M' icon in the control bar. For example: `\( \cos(θ+φ)=\cos(θ)\cos(φ)−\sin(θ)\sin(φ) \)`. _Note: if you are copying and pasting formulas into the rich text editor, switching to HTML/code editor mode is less likely to reformat your pasted formula._
34
 
 
 
35
  === Technical Notes ===
36
 
37
- * Requires PHP 5.4+.
38
  * Requires WordPress 5.0+.
39
  * Issues and Pull requests welcome on the GitHub repository: https://github.com/adamsilverstein/mathml-block.
40
 
@@ -50,6 +52,9 @@ To test using math formulas inline, type an formula into a block of text, select
50
 
51
  == Changelog ==
52
 
 
 
 
53
  = 1.1.5 =
54
  * Make JavaScript translatable, take 2.
55
 
6
  Requires at least: 5.0
7
  Tested up to: 5.5
8
  Requires PHP: 5.6
9
+ Stable tag: 1.2.0
10
  License: GPLv2 or later
11
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
12
  Text Domain: mathml-block
32
 
33
  To test using math formulas inline, type an formula into a block of text, select it and hit the 'M' icon in the control bar. For example: `\( \cos(θ+φ)=\cos(θ)\cos(φ)−\sin(θ)\sin(φ) \)`. _Note: if you are copying and pasting formulas into the rich text editor, switching to HTML/code editor mode is less likely to reformat your pasted formula._
34
 
35
+ This plugin is compatible with the [official AMP plugin](https://amp-wp.org/) by rendering [`amp-mathml`](https://amp.dev/documentation/components/amp-mathml/) on [AMP pages](https://amp.dev/).
36
+
37
  === Technical Notes ===
38
 
39
+ * Requires PHP 5.6+.
40
  * Requires WordPress 5.0+.
41
  * Issues and Pull requests welcome on the GitHub repository: https://github.com/adamsilverstein/mathml-block.
42
 
52
 
53
  == Changelog ==
54
 
55
+ = 1.2.0 =
56
+ * Add AMP compatibility, props @westonruter. Leverages the `amp-mathml` component.
57
+
58
  = 1.1.5 =
59
  * Make JavaScript translatable, take 2.
60