Skip to content

Commit

Permalink
GitHub Publish: preserve <code> elements instead of converting them t…
Browse files Browse the repository at this point in the history
…o `s

... so that GitHub renders HTML entities like &gt; inside them instead of leaving them escaped. background: https://chat.indieweb.org/dev/2019-12-24#t1577174464779200

the html2text people have gone back and forth on how to handle this: Alir3z4/html2text#57, Alir3z4/html2text#109, etc. original bridgy publish github escaping was added in snarfed/bridgy#810.
  • Loading branch information
snarfed committed Dec 26, 2019
1 parent 919a539 commit af26bf3
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 2 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,8 @@ Non-breaking changes:
* Bug fix: extract feed image from `hfeed` correctly.
* REST API:
* Add HTTP `HEAD` support.
* GitHub:
* Publish: preserve `<code>` tags instead of converting them to \`s so that GitHub renders HTML entities like `&gt;` inside them instead of leaving them escaped. [Background.](https://chat.indieweb.org/dev/2019-12-24#t1577174464779200)
* The `cache` kwarg to `Source.original_post_discovery()` now has no effect. `webutil.util.follow_redirects()` has its own built in caching now.
### 2.2 - 2019-11-02
Expand Down
23 changes: 21 additions & 2 deletions granary/github.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,24 @@
}
REACTIONS_REST_CHARS = {char: name for name, char, in REACTIONS_REST.items()}


# preserve <code> elements instead of converting them to `s so that GitHub
# renders HTML entities like &gt; inside them instead of leaving them escaped.
# background: https://chat.indieweb.org/dev/2019-12-24#t1577174464779200
CODE_PLACEHOLDER_START = '~~~BRIDGY-CODE-TAG-START~~~'
CODE_PLACEHOLDER_END = '~~~BRIDGY-CODE-TAG-END~~~'

def tag_callback_code_placeholders(self, tag, attrs, start):
if tag == 'code':
self.o(CODE_PLACEHOLDER_START if start else CODE_PLACEHOLDER_END)
return True


def replace_code_placeholders(text):
return text.replace(CODE_PLACEHOLDER_START, '<code>')\
.replace(CODE_PLACEHOLDER_END, '</code>')


class GitHub(source.Source):
"""GitHub source class. See file docstring and Source class for details.
Expand All @@ -198,6 +216,7 @@ class GitHub(source.Source):
'ignore_links': False,
'protect_links': False,
'use_automatic_links': False,
'tag_callback': tag_callback_code_placeholders,
}

def __init__(self, access_token=None):
Expand Down Expand Up @@ -514,9 +533,9 @@ def _create(self, obj, preview=None, include_link=source.OMIT_LINK,
abort=True,
error_plain='You need an in-reply-to GitHub repo, issue, PR, or comment URL.')

content = orig_content = html.escape(
content = orig_content = replace_code_placeholders(html.escape(
self._content_for_create(obj, ignore_formatting=ignore_formatting),
quote=False)
quote=False))
url = obj.get('url')
if include_link == source.INCLUDE_LINK and url:
content += '\n\n(Originally published at: %s)' % url
Expand Down
20 changes: 20 additions & 0 deletions granary/tests/test_github.py
Original file line number Diff line number Diff line change
Expand Up @@ -801,6 +801,26 @@ def test_create_escape_html(self):
})
self.assertIsNone(result.error_plain, result)

def test_create_doesnt_escape_html_inside_code_tag(self):
"""https://github.com/indieweb/fragmention/issues/3"""
content = 'abc <code>&lt;div style="height: 10000px"&gt;&lt;/div&gt;</code> xyz'
self.expect_graphql_get_labels([])
self.expect_requests_post(github.REST_API_CREATE_ISSUE % ('foo', 'bar'), json={
'title': 'an issue title',
'body': content,
'labels': [],
}, response={
'html_url': 'https://github.com/foo/bar/issues/123',
}, headers=EXPECTED_HEADERS)
self.mox.ReplayAll()

result = self.gh.create({
'title': 'an issue title',
'content': content,
'inReplyTo': [{'url': 'https://github.com/foo/bar/issues'}],
})
self.assertIsNone(result.error_plain, result)

def test_preview_issue(self):
for i in range(2):
self.expect_graphql_get_labels(['new silo'])
Expand Down

0 comments on commit af26bf3

Please sign in to comment.