mirror of
https://github.com/dergigi/boris.git
synced 2025-12-19 07:34:28 +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
|
||||
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
|
||||
const highlightEvent = await factory.create(
|
||||
HighlightBlueprint,
|
||||
selectedText,
|
||||
addressPointer,
|
||||
comment ? { comment } : undefined
|
||||
context ? { comment, context } : comment ? { comment } : undefined
|
||||
)
|
||||
|
||||
// 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