Skip to content

Commit

Permalink
atom: switch from white-space: pre to converting newlines to <br>s
Browse files Browse the repository at this point in the history
...because some feed readers follow it too strictly and don't even line wrap, eg https://forum.newsblur.com/t/android-cant-read-line-pre-formatted-lines/6116

re: #80
  • Loading branch information
snarfed committed Sep 4, 2019
1 parent a2d83d8 commit 0ac5436
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 6 deletions.
2 changes: 2 additions & 0 deletions README.md
Expand Up @@ -318,6 +318,8 @@ Changelog
* Revise whitespace handling; use `white-space: pre` CSS in HTML output.
* Facebook:
* Bug fix: don't interpret `photo.php` as username in post URLs.
* Atom:
* Switch from `white-space: pre` CSS back to converting newlines to `<br>`s because some feed readers ([eg NewsBlur](https://forum.newsblur.com/t/android-cant-read-line-pre-formatted-lines/6116)) follow it too strictly and don't even line wrap.
* RSS:
* Default title to ellipsized content.

Expand Down
6 changes: 5 additions & 1 deletion granary/atom.py
Expand Up @@ -357,7 +357,11 @@ def _prepare_activity(a, reader=True):

# Render content as HTML; escape &s
obj['rendered_content'] = _encode_ampersands(microformats2.render_content(
primary, include_location=reader, render_attachments=True))
primary, include_location=reader, render_attachments=True,
# Readers often obey CSS white-space: pre strictly and don't even line wrap,
# so don't use it.
# https://forum.newsblur.com/t/android-cant-read-line-pre-formatted-lines/6116
white_space_pre=False))

# Make sure every activity has the title field, since Atom <entry> requires
# the title element.
Expand Down
10 changes: 8 additions & 2 deletions granary/microformats2.py
Expand Up @@ -769,7 +769,7 @@ def hcard_to_html(hcard, parent_props=None):


def render_content(obj, include_location=True, synthesize_content=True,
render_attachments=False):
render_attachments=False, white_space_pre=True):
"""Renders the content of an ActivityStreams object as HTML.
Includes tags, mentions, and non-note/article attachments. (Note/article
Expand All @@ -784,6 +784,9 @@ def render_content(obj, include_location=True, synthesize_content=True,
include_location: whether to render location, if provided
synthesize_content: whether to generate synthetic content if the object
doesn't have its own, e.g. 'likes this.' or 'shared this.'
white_space_pre: boolean, whether to wrap in CSS white-space: pre. If False,
newlines will be converted to <br> tags instead. Background:
https://indiewebcamp.com/note#Indieweb_whitespace_thinking
Returns:
string, rendered HTML
Expand Down Expand Up @@ -826,7 +829,10 @@ def render_content(obj, include_location=True, synthesize_content=True,
# https://indiewebcamp.com/note#Indieweb_whitespace_thinking
# https://github.com/snarfed/granary/issues/80
if content and not obj.get('content_is_html') and '\n' in content:
content = '<div style="white-space: pre">%s</div>' % content
if white_space_pre:
content = '<div style="white-space: pre">%s</div>' % content
else:
content = content.replace('\n', '<br />\n')

# linkify embedded links. ignore the "mention" tags that we added ourselves.
# TODO: fix the bug in test_linkify_broken() in webutil/tests/test_util.py, then
Expand Down
16 changes: 13 additions & 3 deletions granary/tests/test_microformats2.py
Expand Up @@ -204,7 +204,7 @@ def test_render_content_multiple_image_attachments(self):
<img class="u-photo" src="http://2" alt="" />
</p>""", microformats2.render_content(obj, render_attachments=True))

def test_render_content_converts_newlines_to_brs(self):
def test_render_content_newlines_default_white_space_pre(self):
self.assert_equals("""\
<div style="white-space: pre">foo
bar
Expand All @@ -214,6 +214,16 @@ def test_render_content_converts_newlines_to_brs(self):
'tags': [{'url': 'http://baz', 'startIndex': 8, 'length': 3}]
}))

def test_render_content_convert_newlines_to_brs(self):
self.assert_equals("""\
foo<br />
bar<br />
<a href="http://baz">baz</a>
""", microformats2.render_content({
'content': 'foo\nbar\nbaz',
'tags': [{'url': 'http://baz', 'startIndex': 8, 'length': 3}]
}, white_space_pre=False))

def test_render_content_omits_tags_without_urls(self):
self.assert_equals("""\
foo
Expand Down Expand Up @@ -633,8 +643,8 @@ def test_json_to_object_with_categories(self):
},
], obj.get('tags'))

def test_json_to_object_converts_text_newlines_to_brs(self):
"""Text newlines should be converted to <br>s."""
def test_json_to_object_text_newlines(self):
"""Text newlines should not be converted to <br>s."""
self.assert_equals({
'objectType': 'note',
'content': 'asdf\nqwer',
Expand Down

0 comments on commit 0ac5436

Please sign in to comment.