From 80e58a05b44fc0b6a7f387054c1c9a76e25d1e98 Mon Sep 17 00:00:00 2001 From: MykolaGolubyev Date: Sun, 9 Nov 2025 15:52:31 -0500 Subject: [PATCH] search: search-entries.xml extra fields --- .../znai/search/GlobalSearchEntry.java | 64 +++++++++++++++++-- .../search/GlobalSearchEntriesTest.groovy | 62 +++++++++++++++--- ...-2025-11-09-search-entries-extra-fields.md | 1 + .../znai/website/WebSite.java | 27 ++------ 4 files changed, 118 insertions(+), 36 deletions(-) create mode 100644 znai-docs/znai/release-notes/1.83/add-2025-11-09-search-entries-extra-fields.md diff --git a/znai-core/src/main/java/org/testingisdocumenting/znai/search/GlobalSearchEntry.java b/znai-core/src/main/java/org/testingisdocumenting/znai/search/GlobalSearchEntry.java index 0bf97b21c..008a51940 100644 --- a/znai-core/src/main/java/org/testingisdocumenting/znai/search/GlobalSearchEntry.java +++ b/znai-core/src/main/java/org/testingisdocumenting/znai/search/GlobalSearchEntry.java @@ -1,4 +1,5 @@ /* + * Copyright 2025 znai maintainers * Copyright 2019 TWO SIGMA OPEN SOURCE, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,6 +17,10 @@ package org.testingisdocumenting.znai.search; +import org.testingisdocumenting.znai.core.DocMeta; +import org.testingisdocumenting.znai.markdown.PageMarkdownSection; +import org.testingisdocumenting.znai.structure.TocItem; + import java.util.Objects; /** @@ -24,15 +29,37 @@ public class GlobalSearchEntry { private String url; private String fullTitle; + private String pageTitle; + private String chapterTitle; + private String pageSectionTitle; private SearchText text; public GlobalSearchEntry() { } - public GlobalSearchEntry(String url, String fullTitle, String text) { + public GlobalSearchEntry(DocMeta docMeta, TocItem tocItem, PageMarkdownSection section, String url) { this.url = url; - this.fullTitle = fullTitle; - this.text = SearchScore.STANDARD.text(text); + this.fullTitle = buildFullTitle(tocItem, section, docMeta); + this.pageTitle = tocItem.getPageTitle(); + this.chapterTitle = tocItem.getChapterTitle(); + this.pageSectionTitle = section.title(); + this.text = SearchScore.STANDARD.text(section.markdown()); + } + + private String buildFullTitle(TocItem tocItem, PageMarkdownSection section, DocMeta docMeta) { + if (tocItem.isIndex()) { + return docMeta.getTitle() + (section.title().isEmpty() ? "" : ": " + section.title()); + } + + String pageSectionPart = section.title().isEmpty() ? + "" : + ", " + section.title(); + + String chapterPart = tocItem.getChapterTitle().isEmpty() ? + "" : + " [" + tocItem.getChapterTitle() + "]"; + + return docMeta.getTitle() + ": " + tocItem.getPageTitle() + pageSectionPart + chapterPart; } public String getUrl() { @@ -51,6 +78,30 @@ public void setFullTitle(String fullTitle) { this.fullTitle = fullTitle; } + public String getPageTitle() { + return pageTitle; + } + + public void setPageTitle(String pageTitle) { + this.pageTitle = pageTitle; + } + + public String getChapterTitle() { + return chapterTitle; + } + + public void setChapterTitle(String chapterTitle) { + this.chapterTitle = chapterTitle; + } + + public String getPageSectionTitle() { + return pageSectionTitle; + } + + public void setPageSectionTitle(String pageSectionTitle) { + this.pageSectionTitle = pageSectionTitle; + } + public SearchText getText() { return text; } @@ -71,11 +122,14 @@ public boolean equals(Object o) { GlobalSearchEntry that = (GlobalSearchEntry) o; return Objects.equals(url, that.url) && - Objects.equals(fullTitle, that.fullTitle); + Objects.equals(fullTitle, that.fullTitle) && + Objects.equals(pageTitle, that.pageTitle) && + Objects.equals(chapterTitle, that.chapterTitle) && + Objects.equals(pageSectionTitle, that.pageSectionTitle); } @Override public int hashCode() { - return Objects.hash(url, fullTitle); + return Objects.hash(url, fullTitle, pageTitle, chapterTitle, pageSectionTitle); } } diff --git a/znai-core/src/test/groovy/org/testingisdocumenting/znai/search/GlobalSearchEntriesTest.groovy b/znai-core/src/test/groovy/org/testingisdocumenting/znai/search/GlobalSearchEntriesTest.groovy index ee57bef64..d27f71a7a 100644 --- a/znai-core/src/test/groovy/org/testingisdocumenting/znai/search/GlobalSearchEntriesTest.groovy +++ b/znai-core/src/test/groovy/org/testingisdocumenting/znai/search/GlobalSearchEntriesTest.groovy @@ -18,20 +18,41 @@ package org.testingisdocumenting.znai.search import org.junit.Test +import org.testingisdocumenting.znai.core.DocMeta +import org.testingisdocumenting.znai.markdown.PageMarkdownSection +import org.testingisdocumenting.znai.structure.TocItem class GlobalSearchEntriesTest { @Test void "should generate XML document"() { + def docMeta = new DocMeta([title: 'Test Doc']) + def tocItem1 = new TocItem('chapter1', 'page1', 'md') + tocItem1.setPageTitleIfNoTocOverridePresent('page 1') + tocItem1.setChapterTitle('chapter 1') + def section1 = new PageMarkdownSection('section1', 'section 1', 'text 1') + + def tocItem2 = new TocItem('chapter2', 'page2', 'md') + tocItem2.setPageTitleIfNoTocOverridePresent('page 2') + tocItem2.setChapterTitle('chapter 2') + def section2 = new PageMarkdownSection('section2', 'section 2', 'text 2') + + def tocItemIndex = TocItem.createIndex() + def sectionIndex = new PageMarkdownSection('', '', 'index text') + def entries = new GlobalSearchEntries() entries.addAll([ - new GlobalSearchEntry('/doc-id/title1', 'full title 1', 'text 1'), - new GlobalSearchEntry('/doc-id/title2', 'full title 2', 'text 2')]) + new GlobalSearchEntry(docMeta, tocItem1, section1, '/doc-id/title1'), + new GlobalSearchEntry(docMeta, tocItem2, section2, '/doc-id/title2'), + new GlobalSearchEntry(docMeta, tocItemIndex, sectionIndex, '/doc-id')]) println entries.toXml() entries.toXml().should == '\n' + ' \n' + ' /doc-id/title1\n' + - ' full title 1\n' + + ' Test Doc: page 1, section 1 [chapter 1]\n' + + ' page 1\n' + + ' chapter 1\n' + + ' section 1\n' + ' \n' + ' STANDARD\n' + ' text 1\n' + @@ -39,28 +60,51 @@ class GlobalSearchEntriesTest { ' \n' + ' \n' + ' /doc-id/title2\n' + - ' full title 2\n' + + ' Test Doc: page 2, section 2 [chapter 2]\n' + + ' page 2\n' + + ' chapter 2\n' + + ' section 2\n' + ' \n' + ' STANDARD\n' + ' text 2\n' + ' \n' + ' \n' + + ' \n' + + ' /doc-id\n' + + ' Test Doc\n' + + ' \n' + + ' \n' + + ' \n' + + ' \n' + + ' STANDARD\n' + + ' index text\n' + + ' \n' + + ' \n' + '\n' } @Test void "should handle ansi sequences"() { + def docMeta = new DocMeta([title: 'title', type: 'Guide']) + def tocItem = new TocItem('chapter', 'page', 'md') + tocItem.setPageTitleIfNoTocOverridePresent('page') + tocItem.setChapterTitle('chapter') + def section = new PageMarkdownSection('section', 'section', + "\u001B[1mwebtau:\u001B[m000\u001B" + + "[1m>\u001B[m http.get(\"https://jsonplaceholder.typicode.com/todos/1\")" + + " \u001B[33m> (\u001B[32m342ms\u001B[33m)\u001B[0m") + def entries = new GlobalSearchEntries() entries.addAll([ - new GlobalSearchEntry('/doc-id/title', 'title', - "\u001B[1mwebtau:\u001B[m000\u001B" + - "[1m>\u001B[m http.get(\"https://jsonplaceholder.typicode.com/todos/1\")" + - " \u001B[33m> (\u001B[32m342ms\u001B[33m)\u001B[0m")]) + new GlobalSearchEntry(docMeta, tocItem, section, '/doc-id/title')]) entries.toXml().should == '\n' + ' \n' + ' /doc-id/title\n' + - ' title\n' + + ' title: page, section [chapter]\n' + + ' page\n' + + ' chapter\n' + + ' section\n' + ' \n' + ' STANDARD\n' + ' webtau:000> http.get("https://jsonplaceholder.typicode.com/todos/1") > (342ms)\n' + diff --git a/znai-docs/znai/release-notes/1.83/add-2025-11-09-search-entries-extra-fields.md b/znai-docs/znai/release-notes/1.83/add-2025-11-09-search-entries-extra-fields.md new file mode 100644 index 000000000..500f35807 --- /dev/null +++ b/znai-docs/znai/release-notes/1.83/add-2025-11-09-search-entries-extra-fields.md @@ -0,0 +1 @@ +* Add: `search-entries.xml` add extra fields \ No newline at end of file diff --git a/znai-website-gen/src/main/java/org/testingisdocumenting/znai/website/WebSite.java b/znai-website-gen/src/main/java/org/testingisdocumenting/znai/website/WebSite.java index 7f46ff5cd..ac17dbe59 100644 --- a/znai-website-gen/src/main/java/org/testingisdocumenting/znai/website/WebSite.java +++ b/znai-website-gen/src/main/java/org/testingisdocumenting/znai/website/WebSite.java @@ -590,11 +590,11 @@ private void updateTocItemWithPageMeta(TocItem tocItem, PageMeta pageMeta) { private void updateSearchEntries(TocItem tocItem, MarkupParserResult parserResult) { List siteSearchEntries = parserResult.markdown().sections().stream() .filter(section -> !(section.title().isEmpty() && section.markdown().trim().isEmpty())) - .map(section -> - new GlobalSearchEntry( - searchEntryUrl(tocItem, section), - searchEntryTitle(tocItem, section), - section.markdown())) + .map(section -> new GlobalSearchEntry( + docMeta, + tocItem, + section, + searchEntryUrl(tocItem, section))) .collect(toList()); globalSearchEntries.addAll(siteSearchEntries); @@ -609,23 +609,6 @@ private String searchEntryUrl(TocItem tocItem, PageMarkdownSection section) { return docStructure.createUrl(null, docUrl); } - private String searchEntryTitle(TocItem tocItem, PageMarkdownSection section) { - if (tocItem.isIndex()) { - return docMeta.getTitle() + " " + (section.title().isEmpty() ? - docMeta.getType() : section.title()); - } - - String pageSectionPart = section.title().isEmpty() ? - "" : - ", " + section.title(); - - String chapterPart = tocItem.getChapterTitle().isEmpty() ? - "" : - " [" + tocItem.getChapterTitle() + "]"; - - return docMeta.getTitle() + ": " + tocItem.getPageTitle() + pageSectionPart + chapterPart; - } - // each markup file may refer other files like code snippets or diagrams // we maintain dependency between them, so we know which one triggers what page refresh during preview mode //