title: Decoding a combination of windows-1252 and quoted printable HTML
body: <p>I have been given a piece of text representing HTML e.g.:</p>
  
  <pre><code>&lt;html&gt;\r\n&lt;head&gt;\r\n&lt;meta http-equiv=3D\"Content-Type\" content=3D\"text/html; charset=3DWindows-1=\r\n252\"&gt;\r\n&lt;style type=3D\"text/css\" style=3D\"display:none;\"&gt;&lt;!-- P {margin-top:0;margi=\r\nn-bottom:0;} --&gt;&lt;/style&gt;\r\n&lt;/head&gt;\r\n&lt;body dir=3D\"ltr\"&gt;This should be a pound sign: =A3 and this should be a long dash: =96 \r\n&lt;/body&gt;\r\n&lt;/html&gt;\r\n
  </code></pre>
  
  <p>From the HTML <code>&lt;meta&gt;</code> tag I can see that the piece of HTML should be encoded as Windows-1252.</p>
  
  <p>I am using <strong>node.js</strong> to parse this piece of text with <code>cheerio</code>. However decoding it with <a href="https://github.com/mathiasbynens/windows-1252" rel="nofollow noreferrer">https://github.com/mathiasbynens/windows-1252</a> is not helping: <code>windows1252.decode(myString);</code> is giving back the same input string.</p>
  
  <p>The reason I think is because that input string is already encoded in the standard node.js charset, but it actually <strong>represents</strong> a <code>windows-1252</code> encoded piece of HTML (if that makes sense?).</p>
  
  <p>Checking those strange HEX numbers prepend by <code>=</code> I can see valid <code>windows-1252</code> codes e.g.:</p>
  
  <ul>
  <li>this <code>=\r\n</code> and this <code>\r\n</code> should somehow represent a carriage return in the Windows world,</li>
  <li><code>=3D</code>: HEX <code>3D</code> is DEC <code>61</code> which is an equals sign: <code>=</code>,</li>
  <li><code>=96</code>: HEX <code>96</code> is DEC <code>150</code> which is an 'en dash' sign: <code>–</code> (some sort of "long minus symbol"),</li>
  <li><code>=A3</code>: HEX <code>A3</code> is DEC <code>163</code> which is a pound sign: <code>£</code></li>
  </ul>
  
  <p>I don't have control in the generation of that piece of HTML, but I am supposed to parse it and clean it giving back <code>£</code> (instead of <code>=A3</code>) etc.</p>
  
  <p>Now, I know I could keep an in memory map with the conversions, but I was wondering if there is already a programmatic solution that covers the whole <code>windows-1252</code> charset?</p>
  
  <p>Cf. this for the whole conversion table: <a href="https://www.w3schools.com/charsets/ref_html_ansi.asp" rel="nofollow noreferrer">https://www.w3schools.com/charsets/ref_html_ansi.asp</a></p>
  
  <p><strong>Edit:</strong></p>
  
  <p>The input HTML comes from a IMAP session, so it seems there's a 7bit/8bit "quoted printable encoding" going on upstream that I can not control (cf <a href="https://en.wikipedia.org/wiki/Quoted-printable" rel="nofollow noreferrer">https://en.wikipedia.org/wiki/Quoted-printable</a>).</p>
  
  <p>In the meanwhile I became aware of this extra encoding and I've tried this <code>quoted-printable</code> (cf. <a href="https://github.com/mathiasbynens/quoted-printable" rel="nofollow noreferrer">https://github.com/mathiasbynens/quoted-printable</a>) library with no luck.</p>
  
  <p>The following is an MCV (as per request):</p>
  
  <pre><code>var cheerio = require('cheerio');
  var windows1252 = require('windows-1252');
  var quotedPrintable = require('quoted-printable');
  
  const inputString = '&lt;html&gt;\r\n&lt;head&gt;\r\n&lt;meta http-equiv=3D\"Content-Type\" content=3D\"text/html; charset=3DWindows-1=\r\n252\"&gt;\r\n&lt;style type=3D\"text/css\" style=3D\"display:none;\"&gt;&lt;!-- P {margin-top:0;margi=\r\nn-bottom:0;} --&gt;&lt;/style&gt;\r\n&lt;/head&gt;\r\n&lt;body dir=3D\"ltr\"&gt;This should be a pound sign: =A3 and this should be a long dash: =96 \r\n&lt;/body&gt;\r\n&lt;/html&gt;\r\n'
  const $ = cheerio.load(inputString, {decodeEntities: true});
  const bodyContent = $('html body').text().trim();
  const decodedBodyContent = windows1252.decode(bodyContent);
  
  console.log(`The input string: "${bodyContent}"`);
  console.log(`The output string: "${decodedBodyContent}"`);
  
  if (bodyContent === decodedBodyContent) {
    console.log('The windows1252 output seems the same of as the input');
  }
  
  const decodedQp = quotedPrintable.decode(bodyContent)
  console.log(`The decoded QP string: "${decodedQp}"`);
  </code></pre>
  
  <p>The previous script is producing the following output:</p>
  
  <pre><code>The input string: "This should be a pound sign: =A3 and this should be a long dash: =96"
  The output string: "This should be a pound sign: =A3 and this should be a long dash: =96"
  The windows1252 output seems the same of as the input
  The decoded QP string: "This should be a pound sign: £ and this should be a long dash: "
  </code></pre>
  
  <p>On my command line I can not see the long dash and I am not sure how I could properly decode all these <code>=&lt;something&gt;</code> encoded characters?</p>