diff --git a/internal/reader/rewrite/rewrite_functions.go b/internal/reader/rewrite/rewrite_functions.go index 878167c1444..e128a22a416 100644 --- a/internal/reader/rewrite/rewrite_functions.go +++ b/internal/reader/rewrite/rewrite_functions.go @@ -462,22 +462,48 @@ func fixGhostCards(entryContent string) string { return entryContent } - doc.Find("figure.kg-card").Each(func(i int, s *goquery.Selection) { + const cardSelector = "figure.kg-card" + var currentList *goquery.Selection + + doc.Find(cardSelector).Each(func(i int, s *goquery.Selection) { title := s.Find(".kg-bookmark-title").First().Text() author := s.Find(".kg-bookmark-author").First().Text() href := s.Find("a.kg-bookmark-container").First().AttrOr("href", "") - if href == "" { + // if there is no link or title, skip processing + if href == "" || title == "" { return } + link := "" if author == "" || strings.HasSuffix(title, author) { - s.ReplaceWithHtml(fmt.Sprintf("%s", href, title)) + link = fmt.Sprintf("%s", href, title) + } else { + link = fmt.Sprintf("%s - %s", href, title, author) + } + + next := s.Next() + + // if the next element is also a card, start a list + if next.Is(cardSelector) && currentList == nil { + currentList = s.BeforeHtml("").Prev() + } + + if currentList != nil { + // add this card to the list, then delete it + currentList.AppendHtml("
  • " + link + "
  • ") + s.Remove() } else { - s.ReplaceWithHtml(fmt.Sprintf("%s - %s", href, title, author)) + // replace single card + s.ReplaceWithHtml(link) + } + + // if the next element is not a card, start a new list + if !next.Is(cardSelector) && currentList != nil { + currentList = nil } }) output, _ := doc.FindMatcher(goquery.Single("body")).Html() - return output + return strings.TrimSpace(output) } diff --git a/internal/reader/rewrite/rewriter_test.go b/internal/reader/rewrite/rewriter_test.go index 151dc0aefa7..52ea5c01d26 100644 --- a/internal/reader/rewrite/rewriter_test.go +++ b/internal/reader/rewrite/rewriter_test.go @@ -832,3 +832,102 @@ func TestFixGhostCardDuplicatedAuthor(t *testing.T) { t.Errorf(`Not expected output: got "%+v" instead of "%+v"`, testEntry, controlEntry) } } + +func TestFixGhostCardMultiple(t *testing.T) { + testEntry := &model.Entry{ + Title: `A title`, + Content: `
    + +
    +
    Example Article 1 - Example
    +
    Lorem ipsum odor amet, consectetuer adipiscing elit. Pretium magnis luctus ligula conubia quam, donec orci vehicula efficitur...
    + +
    +
    + +
    +
    +
    +
    + +
    +
    Example Article 2 - Example
    +
    Lorem ipsum odor amet, consectetuer adipiscing elit. Pretium magnis luctus ligula conubia quam, donec orci vehicula efficitur...
    + +
    +
    + +
    +
    +
    `, + } + + controlEntry := &model.Entry{ + Title: `A title`, + Content: ``, + } + Rewriter("https://example.org/article", testEntry, `fix_ghost_cards`) + + if !reflect.DeepEqual(testEntry, controlEntry) { + t.Errorf(`Not expected output: got "%+v" instead of "%+v"`, testEntry, controlEntry) + } +} + +func TestFixGhostCardMultipleSplit(t *testing.T) { + testEntry := &model.Entry{ + Title: `A title`, + Content: `
    + +
    +
    Example Article 1 - Example
    +
    Lorem ipsum odor amet, consectetuer adipiscing elit. Pretium magnis luctus ligula conubia quam, donec orci vehicula efficitur...
    + +
    +
    + +
    +
    +
    +

    This separates the two cards

    +
    + +
    +
    Example Article 2 - Example
    +
    Lorem ipsum odor amet, consectetuer adipiscing elit. Pretium magnis luctus ligula conubia quam, donec orci vehicula efficitur...
    + +
    +
    + +
    +
    +
    `, + } + + controlEntry := &model.Entry{ + Title: `A title`, + Content: `Example Article 1 - Example +

    This separates the two cards

    + Example Article 2 - Example`, + } + Rewriter("https://example.org/article", testEntry, `fix_ghost_cards`) + + if !reflect.DeepEqual(testEntry, controlEntry) { + t.Errorf(`Not expected output: got "%+v" instead of "%+v"`, testEntry, controlEntry) + } +}