mirror of
https://github.com/dergigi/boris.git
synced 2025-12-20 16:14:20 +01:00
feat: add context to highlights (previous and next sentences)
This commit is contained in:
@@ -26,12 +26,15 @@ export async function createHighlight(
|
|||||||
// Parse article coordinate to get address pointer
|
// Parse article coordinate to get address pointer
|
||||||
const addressPointer = parseArticleCoordinate(article)
|
const addressPointer = parseArticleCoordinate(article)
|
||||||
|
|
||||||
|
// Extract context (previous and next sentences from the same paragraph)
|
||||||
|
const context = extractContext(selectedText, article.content)
|
||||||
|
|
||||||
// Create highlight event using the blueprint
|
// Create highlight event using the blueprint
|
||||||
const highlightEvent = await factory.create(
|
const highlightEvent = await factory.create(
|
||||||
HighlightBlueprint,
|
HighlightBlueprint,
|
||||||
selectedText,
|
selectedText,
|
||||||
addressPointer,
|
addressPointer,
|
||||||
comment ? { comment } : undefined
|
context ? { comment, context } : comment ? { comment } : undefined
|
||||||
)
|
)
|
||||||
|
|
||||||
// Update the alt tag to identify Boris as the creator
|
// Update the alt tag to identify Boris as the creator
|
||||||
@@ -66,3 +69,80 @@ function parseArticleCoordinate(article: NostrEvent): AddressPointer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts context for a highlight by finding the previous and next sentences
|
||||||
|
* in the same paragraph as the selected text
|
||||||
|
*/
|
||||||
|
function extractContext(selectedText: string, articleContent: string): string | undefined {
|
||||||
|
if (!selectedText || !articleContent) return undefined
|
||||||
|
|
||||||
|
// Find the position of the selected text in the article
|
||||||
|
const selectedIndex = articleContent.indexOf(selectedText)
|
||||||
|
if (selectedIndex === -1) return undefined
|
||||||
|
|
||||||
|
// Split content into paragraphs (by double newlines or single newlines)
|
||||||
|
const paragraphs = articleContent.split(/\n\n+/)
|
||||||
|
|
||||||
|
// Find which paragraph contains the selected text
|
||||||
|
let currentPos = 0
|
||||||
|
let containingParagraph: string | undefined
|
||||||
|
|
||||||
|
for (const paragraph of paragraphs) {
|
||||||
|
const paragraphEnd = currentPos + paragraph.length
|
||||||
|
if (selectedIndex >= currentPos && selectedIndex < paragraphEnd) {
|
||||||
|
containingParagraph = paragraph
|
||||||
|
break
|
||||||
|
}
|
||||||
|
currentPos = paragraphEnd + 2 // Account for the double newline
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!containingParagraph) return undefined
|
||||||
|
|
||||||
|
// Split paragraph into sentences (basic sentence splitting)
|
||||||
|
// This regex splits on periods, exclamation marks, or question marks followed by space or end of string
|
||||||
|
const sentences = containingParagraph.split(/([.!?]+\s+)/).filter(s => s.trim().length > 0)
|
||||||
|
|
||||||
|
// Reconstruct sentences properly by joining sentence text with punctuation
|
||||||
|
const reconstructedSentences: string[] = []
|
||||||
|
for (let i = 0; i < sentences.length; i++) {
|
||||||
|
if (sentences[i].match(/^[.!?]+\s*$/)) {
|
||||||
|
// This is punctuation, attach it to previous sentence
|
||||||
|
if (reconstructedSentences.length > 0) {
|
||||||
|
reconstructedSentences[reconstructedSentences.length - 1] += sentences[i]
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
reconstructedSentences.push(sentences[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find which sentence contains the selected text
|
||||||
|
let selectedSentenceIndex = -1
|
||||||
|
for (let i = 0; i < reconstructedSentences.length; i++) {
|
||||||
|
if (reconstructedSentences[i].includes(selectedText)) {
|
||||||
|
selectedSentenceIndex = i
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectedSentenceIndex === -1) return undefined
|
||||||
|
|
||||||
|
// Build context from previous and next sentences
|
||||||
|
const contextParts: string[] = []
|
||||||
|
|
||||||
|
// Add previous sentence if it exists
|
||||||
|
if (selectedSentenceIndex > 0) {
|
||||||
|
contextParts.push(reconstructedSentences[selectedSentenceIndex - 1].trim())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the selected sentence itself
|
||||||
|
contextParts.push(reconstructedSentences[selectedSentenceIndex].trim())
|
||||||
|
|
||||||
|
// Add next sentence if it exists
|
||||||
|
if (selectedSentenceIndex < reconstructedSentences.length - 1) {
|
||||||
|
contextParts.push(reconstructedSentences[selectedSentenceIndex + 1].trim())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only return context if we have more than just the selected sentence
|
||||||
|
return contextParts.length > 1 ? contextParts.join(' ') : undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user