Repository: sopel-irc/sopel

Issue:
wikipedia: excess whitespace in snippets containing math expressions
### Description
@dgw said something about Wikipedia doing dumb XML things, idk. Just opening this so @dgw can die happy, or whatever.

### Reproduction steps
N/A

### Expected behavior
Not 15 miles of whitespace?

### Logs
```
20:10:31 <xnaas> unrelated: https://en.wikipedia.org/wiki/Planck_constant
20:10:31 <+Sopel> [wikipedia] Planck constant | "The Planck constant, or Planck's constant, is a fundamental physical constant denoted                     h              {\displaystyle h}  , and is of fundamental importance in quantum mechanics. A photon's energy is equal to its frequency multiplied by the Planck constant.  Due to mass–energy equivalence, the Planck constant also relates mass to [frequency.In](http://frequency.in/) metrology it is used, together with other […]"
```

### Environment
- Sopel `.version`: Sopel v7.1.8 | Python: 3.9.5
- Sopel installed via: N/A
- Python version: 3.9.5
- Operating system: N/A
- IRCd `/version`: N/A
- Relevant plugins: wikipedia.py

### Notes
<details>
<summary>Some chatlogs.</summary>

> 20:13:30 <+dgw> That's a lotta crap inlined to display one italic h in a slightly different font
> 20:13:35 <+dgw> Thanks, Wikipedia
> 20:14:58 <+dgw> smfh ![https://i.imgur.com/iKXmBEB.png](https://i.imgur.com/iKXmBEB.png)
> 20:15:12 <+dgw> > `mi`
> 20:15:23 <+dgw> it's a whole separate XML namespace
> 20:15:26 <+dgw> Nope.
> 20:15:46 <+dgw> Deal with the silly output, or we'll just skip <math> elements entirely :P
> 20:16:02 <+dgw> Then it'll be "constant denoted , and is of"
> 20:16:29 <+dgw> Some things just aren't worth fixing.
> 20:19:51 <+dgw> if I was going to fix it I absolutely would just skip \<math\> and look for the fallback \<img\>, then use its alt attribute
> 20:20:02 <+dgw> but, you know, meh

</details>


Discussion:
We've just seen this upstream bug in ##physics on Libera.chat (with the article [Leibniz integral rule](https://en.wikipedia.org/wiki/Leibniz_integral_rule)), I've applied the following workaround to make the bot's response a little less offensive. Not sure if there are cases where this clobbers important whitespace in the MediaWiki response though:

```diff
diff --git a/sopel/modules/wikipedia.py b/sopel/modules/wikipedia.py
index 5476f099..4a06105c 100644
--- a/sopel/modules/wikipedia.py
+++ b/sopel/modules/wikipedia.py
@@ -184,6 +184,7 @@ def say_snippet(bot, trigger, server, query, show_url=True):
 
     try:
         snippet = mw_snippet(server, query)
+        snippet = re.sub(r"\s+", " ", snippet)
     except KeyError:
         if show_url:
             bot.reply("Error fetching snippet for \"{}\".".format(page_name))
```

Response before:

```
<terribot> [wikipedia] Leibniz integral rule | "In calculus, the Leibniz integral rule for differentiation under the integral sign, named after Gottfried Leibniz, states that for an integral of the formwhere                     −        ∞        <        a        (        x        )        ,        b        (        x        )        <        ∞              {\displaystyle -\infty <a(x),b(x)<\infty }  , the derivative of this integral […]"
```

Response after:

```
<terribot> [wikipedia] Leibniz integral rule | "In calculus, the Leibniz integral rule for differentiation under the integral sign, named after Gottfried Leibniz, states that for an integral of the form where − ∞ < a ( x ) , b ( x ) < ∞ {\displaystyle -\infty <a(x),b(x)<\infty } , the derivative of this integral is expressible as where the partial derivative indicates that inside the integral, only..."
```
@SnoopJeDi You might as well submit a pull request with that patch. We'll run it on master in #sopel and help see if it has any weird side effects before 8.0.

Resolving patch:
diff --git a/sopel/modules/wikipedia.py b/sopel/modules/wikipedia.py
--- a/sopel/modules/wikipedia.py
+++ b/sopel/modules/wikipedia.py
@@ -184,6 +184,9 @@ def say_snippet(bot, trigger, server, query, show_url=True):
 
     try:
         snippet = mw_snippet(server, query)
+        # Coalesce repeated whitespace to avoid problems with <math> on MediaWiki
+        # see https://github.com/sopel-irc/sopel/issues/2259
+        snippet = re.sub(r"\s+", " ", snippet)
     except KeyError:
         if show_url:
             bot.reply("Error fetching snippet for \"{}\".".format(page_name))


Test patch: