[Question]
  [
Everyone knows that the news is boring. *Really boring*. Unless if it's about Politicians and their scandals. That is fun! But alas, Politicians can commit only so many scandals. So, I am employing you to make the news more interesting.
**Objective** Given an HTML snippet, perform all the substitutions found [here](https://xkcd.com/1288/), that is, in this picture: ![](https://imgs.xkcd.com/comics/substitutions.png)
BUT you should not edit any HTML tags themselves. I call a valid word any word that is not found within any HTML tag or their attributes. That is, you shouldn't replace `<div class="smartphone">iPhone</div>` with `<div class="pokedex">iPhone</div>`, but should replace `<div>election</div>` with `<div>eating contest</div>`.
# Parsing rules
* **EDIT** You should only match words delineated by a non-word. That is, you should only match full words. (E.g., match "Hello witness" but not "Hellowitness", "Hellow itness", or "Witnesspacelection."
* If you can't type out the character on your keyboard, you should display the closest equivalent. (E.g., "Smartphone" would really become "Pokedex")
* First-letter case or all-letter case must be retained. (E.g., "Allegedly, they died" becomes "Kinda probably, they died", "They allegedly died" becomes "They kinda probably died", and "THE ELECTION!" becomes "THE EATING CONTEST!", while "SpAcE" becomes "Spaaace" and "nEW STUDY" becomes "tumblr post")
* All cases must be matched. (I.e., you must match a word, regardless of its capitalization.)
* Any instance in which `a <vowel>` is met should become `an <vowel>` and *vice versa*. (E.g., "A senator" becomes "An elf-lord") You do not have to do this for every instance, but at least for your own replacements.
* Anything plural must also retain pluralization in the translation (E.g., "Smartphones" becomes "pokedex" and "Spaces" becomes "Spaaaces")
* Anything in a certain tense must remain in that tense in the translation. (E.g., "Rebuilt" becomes "Avenged", "Rebuilds" becomes "Avenges", etc.)
* Anything in the singular must remain singular in the translation (E.g., "Congressional leader" becomes "River spirit")
* If the entry spans multiple HTML elements, you should still match it, but you may "throw away" any intermediate elements. (E.g., `S<b>pa</b>ace` should become simply "spaaace"). If the entry is self-contained within a single element, it should be matched properly and the tag retained.
* "The witnesses" should become "Those dudes I know"
* "witness" should become "This dude I know"
* "The witness" should become "That dude I know"
* "Couldn't be reached for comment" should become "Is guilty and everyone knows it"
* "Cannot be reached for comment" should become "Are guilty and everyone knows it"
# Bonuses
If you meet a `-N%` bonus, your `new amount = (old amount) * (1 - N/100)`. So, if you met a `-5%` bonus with a 500 byte code, your `new amount = 500 * (1 - 5/100) = 500 * .95 = 475`.
* -5% bonus if, for every instance of "space" after the first replacement, an extra "a" is added. So, the first replacement would be "spaaace", the second would be "spaaaace", the third would be "spaaaaace", etc.
* -5% bonus if, for every valid number, you replace that number with a link to the respective XKCD comic. (It doesn't have to yet exist). If you do go for this bonus, you should match numbers such as `500`, `3,000`, `4 523`, and `5.324`. (You may opt to replace, instead, the number with the image of the comic. If you do this, instead of a `-5%` bonus, you will get a `-15% bonus`. Another extra `-15%` bonus if you can add the title-text to the picture, if any.)
* -25% bonus if you can replace simultaneously all instances on the right side of the image with those on the left. (E.g., "spaaace" becomes "space", "eating contest" becomes "election", etc.) If you opt for any of the bonuses, you should be able to revert those to their respective entries. (E.g., `http://www.xkcd.com/542` should become "542", and "spaaaaaaaace" should become "space".)
* ***You may choose to do a minimum of 6 substitutions, but for each substitution not done (exclusive of bonus substitutions), you will receive an additional +10% penalty.***
# Example IOs (no bonuses)
```
Input: Witnesses allegedly used their smartphones to commit the crime.
Output: These dudes I know kinda probably used their pokedex to commit the crime.
Input: Mayor Golfalot rebuilt the city after the fatal election.
Output: Mayor Golfalot avenged the city after the fatal eating contest.
Input: This <b>new study</b> shows that people in <span class="space">space</span> cannot be reached for comment.
Output: This <b>tumblr post</b> shows that people in <span class="space">spaaace</span> are guilty and everyone knows it.
Input: <b>g</b><i>oo</i><s>g</s><u>le</u> glass is terrible. :(
Output: virtual boy is terrible. :(
Input: Electric SMARTPHONES have been shown to be more productive when not used by Senators and when not used in cars.
Output: Atomic POKEDEX have been shown to be more productive when not used by Elf-lords and when not used in cats.
Input: Homeland Security has been established as an evil foundation, especially in space.
Output: Homestar runner has been established as an evil foundation, especially in spaaace.
Input: The congressional leaders are testy today.
Output: The river spirits are testy today.
Input: SPACE is not a Senator or a cAR.
Output: SPAAACE is not an Elf-lord or a cat.
Input: Mr. Biz is running for reelection.
Output: Mr. Biz is running for reelection.
Input: Google   glass !
Output: Virtual boy !
Input: New (or old) study
Output: New (or old) study
```
---
This is a [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), so the shortest program in bytes wins.
  
[Answer]
## JavaScript ES6, 954 bytes
I thought this was going to be a lot easier than it was! I originally used JavaScript so I could easily descend only into text nodes and replace the text there, but that wasn't what the question was after, so I've ended up with this monstrosity! It passes all the test cases except for `<b>g</b><i>oo</i><s>g</s><u>le</u> glass is terrible. :(` where the whole string comes back in a `<b>` tag due to the tags getting balanced. The bulk of the code is the lookup table, and I'm probably still missing some edge cases, but I couldn't come up with a nicer way to handle the tense correctly and I'm sure I could compress that more, but I'm running out of ideas... I'm sure I'll come back to this later though. Should've used Perl, better choice [@LukStorms](https://codegolf.stackexchange.com/users/42827/luk-storms)!
```
d=document.createElement`div`,u='toUpperCase'
d[i='innerHTML']=prompt``;`the ${w='witness'}es,those dudes I know|${w}es,these dudes I know|the ${w},this dude I know|${w},dude I know|allegedly,kinda probably|new study,tumblr post|new studies,tumblr posts|rebuild,avenge|rebuilt,avenged|space,spaaace|${g='google glass'},virtual boy|${g}es,virtual boys|smartphones,pokédex|smartphone,pokédex|electric,atomic|senator,elf-lord|car,cat|election,eating contest|congressional leader,river spirit|homeland security,homestar runner|could not ${b='be reached for comment'},is${g=' guilty and everyone knows it'}|couldn't be reached for comment,is${g}|cannot be reached for comment,are${g}`[v='split']`|`.map(w=>d[i]=d[i][r='replace'](eval(`/(<[^>]+)?\\b${(w=w[v]`,`)[0][v]``.join`(?:<\\/?[^>]+>)*`[r](/ /g,'\\s+')}(s?)\\b/gi`),(s,q,t)=>[q?s:((!s.match(/[^A-Z]/)?w[1][u]():s.match(/^[A-Z]/)?w[1][r](/^./,q=>q[u]()):w[1])+t),q?0:w[1]=w[1][r](/ce$/,'ace')][0])[r](/\ba(?= [aeiou])/gi,s=>s=="a"?"an":"AN"))
alert(d[i])
```
I applied one bonus for 5% of `spaaace` getting an additional `a` after each successful match. Uses `alert()` as suggested by [@sysreq](https://codegolf.stackexchange.com/users/46231/sysreq), thanks!
### Examples
```
Input: <b>g</b><i>oo</i><s>g</s><u>le</u> glass is terrible. :(
Output: <b>virtual boy is terrible. :(</b>
```
```
Input: space. Space? Space! SPACE!
Output: spaaace. Spaaaace? Spaaaaace! SPAAAAAACE!
```
```
Input: Smartphones aren't really smart phones, but: SMARTPHONES!
Output: Pokédex aren't really smart phones, but: POKÉDEX!
```
```
Input: Senator John Doe was arrested today after attempting to write a new study on the danger of smartphones being used in the car, on his smartphone whilst driving his car. A witness testified to having seen the senator committing the crime. When questioned, Senator Doe "could not be reached for comment". It's unknown if his reputation can be rebuilt and this puts new doubts on the upcoming election. Congressional leaders have yet to comment.
Output: Elf-lord John Doe was arrested today after attempting to write a tumblr post on the danger of pokédex being used in the cat, on his pokédex whilst driving his cat. A dude I know testified to having seen the elf-lord committing the crime. When questioned, Elf-lord Doe "is guilty and everyone knows it". It's unknown if his reputation can be avenged and this puts new doubts on the upcoming eating contest. River spirits have yet to comment.
```
---
### Bonus: bookmarklet
Run this in your console to have the body text updated in-place:
```
d=document.body;`the ${w='witness'}es,those dudes I know|${w}es,these dudes I know|the ${w},this dude I know|${w},dude I know|allegedly,kinda probably|new study,tumblr post|new studies,tumblr posts|rebuild,avenge|rebuilt,avenged|space,spaaace|${g='google glass'},virtual boy|${g}es,virtual boys|smartphones,pokédex|smartphone,pokédex|electric,atomic|senator,elf-lord|car,cat|election,eating contest|congressional leader,river spirit|homeland security,homestar runner|could not ${b='be reached for comment'},is${g=' guilty and everyone knows it'}|couldn't be reached for comment,is${g}|cannot be reached for comment,are${g}`[v='split']`|`.map(w=>d[i='innerHTML']=d[i][r='replace'](eval('/(<[^>]+)?\\b'+(w=w[v]`,`)[0][v]``.join`(?:<\\/?[^>]+>)*`[r](/ /g,'\\s+')+'(s)?\\b/gi'),(s,q,t)=>[q?s:((s.match(/^[A-Z]+$/)?w[1].toUpperCase():s.match(/^[A-Z]/)?w[1][r](/^./,q=>q.toUpperCase()):w[1])+(t||"")),q?0:w[1]=w[1][r](/ce$/,'ace')][0])[r](/\ba ([aeiou])/gi,(s,t)=>s[0]=="a"?"an "+t:"AN "+t))
```
[Answer]
# [Perl 5](https://www.perl.org/), 850
Lots of regex used or generated.  
The %l hash is used for repeated words.
```
%l=qw(A avenge B _be_reached_for_comment C could D dude E pokedex G google_glass I _I_know K river_spirit L congressional_leader P smartphone 4 rebuil N new_stud T tumblr_post V virtual_boy W witness Y _guilty_and_everyone_knows_it);$t="G,V;Ges,Vs;Ps,E;P,E;4d,A;4t,Ad;Nies,Ts;Ny,T;Wes,these DsI;W,this DI;allegedly,kinda probably;cannotB,areY;car,cat;cars,cats;Ls,Ks;L,K;C notB,isY;Cn'tB,isY;election,eating contest;electric,atomic;homeland Security,homestar runner;senator,elf-lord;senators,elf-lords;space,spaaace";$o=$s=$_;$s=~s/\s\s*/ /g;map{$t=~s/$_/$l{$_}/g}keys%l;$t=~s/_/ /g;@L=split/;/,$t;map{my@T=split/,/;push@W,\@T}@L;map{$e=$a=$W[$_][0];$b=$W[$_][1];$U=uc$a;$u=ucfirst$a;$s=~s/(?<![\w"])$U(?![\w"])/\U$b/g;$s=~s/(?<![\w"])$u(?![\w"])/\u$b/g;$s=~s/(?<![\w"])$a(?![\w"])/$b/gi;$e=~s@.@(<.*?>)?$&(</.*?>)?@g;$s=~s/$e /$b /ig;}0..@W;$_=$s.$/
```
### Test
```
$ cat news.txt |perl -p readingnews.pl
These dudes I know kinda probably used their pokedex to commit the crime.
Mayor Golfalot avenged the city after the fatal eating contest.
This <b>tumblr post</b> shows that people in <span class="space">spaaace</span> are guilty and everyone knows it.
virtual boy is terrible. :(
Atomic POKEDEX have been shown to be more productive when not used by Elf-lords and when not used in cats.
Homestar runner has been established as an evil foundation, especially in spaaace.
The river spirits are testy today.
SPAAACE is not a Elf-lord or a cat.
Mr. Biz is running for reelection.
Virtual boy !
New (or old) study
```
]