Reduce feed text to plain text: decode, strip markup, decode again, collapse.
Decoding runs before stripping because RSS descriptions overwhelmingly carry
their HTML escaped — <p>text</p> rather than <p>text</p>. Strip
first and those tags survive as literal <p> in the output, which is what a
consumer then has to clean up itself.
The second decode pass exists for that same escaped-HTML case: source that
renders as & arrives as &amp;, so one pass leaves a visible &
where the reader expects &. Running it again after the tags are gone finishes
the job. Text that was never double-escaped has no entities left by then, so the
extra pass is a no-op on it.
Reduce feed text to plain text: decode, strip markup, decode again, collapse.
Decoding runs before stripping because RSS descriptions overwhelmingly carry their HTML escaped —
<p>text</p>rather than<p>text</p>. Strip first and those tags survive as literal<p>in the output, which is what a consumer then has to clean up itself.The second decode pass exists for that same escaped-HTML case: source that renders as
&arrives as&amp;, so one pass leaves a visible&where the reader expects&. Running it again after the tags are gone finishes the job. Text that was never double-escaped has no entities left by then, so the extra pass is a no-op on it.