Skip listing containers whose entries hold user cards or quotes
A thread without DiscussionForumPosting markup, where every poster writes once, still passed the teaser test: each post opens with a linked name that no other post repeats. On katzen-forum.net with the JSON-LD removed and one post per poster, recall took the whole container (3,573 chars, seven user cards instead of one). Teasers hold neither a description list nor a quote, while forum posts keep the poster's user card in one and quote each other, so an entry holding either now rules the container out.
This commit is contained in:
1 parent
77465a50e7
commit
06c7822f79
2 files changed
+23
-11
No files matched your search
+19
-10
@@ -2963,13 +2963,18 @@ def test_listing_page_with_links_keeps_every_entry_heading():
|
||||
assert text in result
|
||||
|
||||
|
||||
def _forum_thread(posters, linked=True, forum_markup=False):
|
||||
def _forum_thread(posters, linked=True, forum_markup=False, card_in_dl=False, quoting=False):
|
||||
"Thread markup: sibling <article> posts, each opening with a user card that names its poster in a heading."
|
||||
name_markup = '<a href="/members/{0}/">{0}</a>' if linked else "<span>{0}</span>"
|
||||
card = (
|
||||
"<dl><dt>Joined</dt><dd>March 2015</dd><dt>Messages</dt><dd>1,447</dd></dl>"
|
||||
if card_in_dl
|
||||
else '<div class="user-title">Joined March 2015, 1,447 messages</div>'
|
||||
)
|
||||
posts = "".join(
|
||||
f'<article><div class="poster"><h4>{name_markup.format(name)}</h4>'
|
||||
"<dl><dt>Joined</dt><dd>March 2015</dd><dt>Messages</dt><dd>1,447</dd></dl></div>"
|
||||
f"<div><p>Reply {i} from {name} carries enough prose to count as a post, running over a couple "
|
||||
f'<article><div class="poster"><h4>{name_markup.format(name)}</h4>{card}</div>'
|
||||
+ (f"<blockquote><p>{posters[i - 1]} wrote: see my reply above.</p></blockquote>" if quoting and i else "")
|
||||
+ f"<div><p>Reply {i} from {name} carries enough prose to count as a post, running over a couple "
|
||||
"of clauses so the thread reads as a real discussion between people.</p></div></article>"
|
||||
for i, name in enumerate(posters)
|
||||
)
|
||||
@@ -2986,20 +2991,24 @@ def _forum_thread(posters, linked=True, forum_markup=False):
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"posters,linked,forum_markup",
|
||||
"posters,markup",
|
||||
[
|
||||
# the same poster comes back along the thread
|
||||
(["alice", "bob", "alice", "carol", "bob", "alice"], True, False),
|
||||
(["alice", "bob", "alice", "carol", "bob", "alice"], {}),
|
||||
# poster names without a link
|
||||
(["alice", "bob", "carol", "dave", "erin", "frank"], False, False),
|
||||
(["alice", "bob", "carol", "dave", "erin", "frank"], {"linked": False}),
|
||||
# every poster different, but the page declares itself a forum thread
|
||||
(["alice", "bob", "carol", "dave", "erin", "frank"], True, True),
|
||||
(["alice", "bob", "carol", "dave", "erin", "frank"], {"forum_markup": True}),
|
||||
# every poster different and no forum markup, but the user card is a description list
|
||||
(["alice", "bob", "carol", "dave", "erin", "frank"], {"card_in_dl": True}),
|
||||
# every poster different and no forum markup, but the replies quote the post before them
|
||||
(["alice", "bob", "carol", "dave", "erin", "frank"], {"quoting": True}),
|
||||
],
|
||||
)
|
||||
@pytest.mark.parametrize("settings", [{"favor_recall": True}, {"favor_recall": True, "fast": True}])
|
||||
def test_forum_thread_is_not_a_listing(posters, linked, forum_markup, settings):
|
||||
def test_forum_thread_is_not_a_listing(posters, markup, settings):
|
||||
"forum posts line up like listing entries, but taking their container brings every user card along"
|
||||
doc = _forum_thread(posters, linked, forum_markup)
|
||||
doc = _forum_thread(posters, **markup)
|
||||
with _without_listing_expression():
|
||||
expected = extract(doc, output_format="markdown", config=use_config(), **settings)
|
||||
result = extract(doc, output_format="markdown", config=use_config(), **settings) or ""
|
||||
|
||||
@@ -665,9 +665,12 @@ def _holds_most_of_the_text(tree: HtmlElement, expr: XPath) -> bool:
|
||||
def _entries_link_out(container: _Element) -> bool:
|
||||
"""Whether every entry of the container is a teaser: its first heading links to a page of its
|
||||
own, which no other entry links to. Forum posts share the shape but open with the poster's
|
||||
name, which comes back along the thread or carries no link at all."""
|
||||
name, which comes back along the thread or carries no link at all, and they hold user cards
|
||||
(description lists) and quotes, which teasers do not."""
|
||||
targets: set[str] = set()
|
||||
for entry in container.iterchildren("article"):
|
||||
if entry.find(".//list[@rend='dl']") is not None or entry.find(".//quote") is not None:
|
||||
return False
|
||||
heading = entry.find(".//head")
|
||||
link = heading.find(".//ref") if heading is not None else None
|
||||
if link is None:
|
||||
|
||||
Reference in new issue
Block a user