Corde organization

This commit is contained in:
Simon Cambier
2022-04-12 07:30:32 +02:00
parent 7316bbaa53
commit 9e885cedc4
3 changed files with 88 additions and 80 deletions

4
src/globals.ts Normal file
View File

@@ -0,0 +1,4 @@
// Matches a wikiling that begins a string
export const regexWikilink = /^!?\[\[(?<name>.+?)(\|(?<alias>.+?))?\]\]/
export const regexLineSplit = /\r?\n|\r|((\.|\?|!)( |\r?\n|\r))/g
export const regexYaml = /^---\s*\n(.*?)\n?^---\s?/ms

View File

@@ -1,19 +1,21 @@
import { Notice, Plugin, SuggestModal, TAbstractFile, TFile } from 'obsidian' import { Notice, Plugin, SuggestModal, TAbstractFile, TFile } from 'obsidian'
import MiniSearch from 'minisearch' import MiniSearch from 'minisearch'
import { markdownToTxt } from 'markdown-to-txt' import {
clearContent,
escapeRegex,
getTitleLine,
highlighter,
removeTitleLine,
wait,
} from './utils'
type OmniNote = { type OmniNote = {
path: string path: string
name: string basename: string
title: string title: string
body: string body: string
} }
// Matches a wikiling that begins a string
const regexWikilink = /^!?\[\[(?<name>.+?)(\|(?<alias>.+?))?\]\]/
const regexLineSplit = /\r?\n|\r|((\.|\?|!)( |\r?\n|\r))/g
const regexYaml = /^---\s*\n(.*?)\n?^---\s?/ms
export default class OmnisearchPlugin extends Plugin { export default class OmnisearchPlugin extends Plugin {
minisearch: MiniSearch<OmniNote> minisearch: MiniSearch<OmniNote>
lastSearch?: string lastSearch?: string
@@ -59,7 +61,7 @@ export default class OmnisearchPlugin extends Plugin {
this.notes = {} this.notes = {}
this.minisearch = new MiniSearch<OmniNote>({ this.minisearch = new MiniSearch<OmniNote>({
idField: 'path', idField: 'path',
fields: ['body', 'title', 'name'], fields: ['body', 'title', 'basename'],
}) })
// Index files that are already present // Index files that are already present
@@ -89,7 +91,7 @@ export default class OmnisearchPlugin extends Plugin {
if (!(file instanceof TFile) || file.extension !== 'md') return if (!(file instanceof TFile) || file.extension !== 'md') return
try { try {
if (this.notes[file.path]) { if (this.notes[file.path]) {
throw new Error(`${file.name} is already indexed`) throw new Error(`${file.basename} is already indexed`)
} }
// Fetch content from the cache, // Fetch content from the cache,
// trim the markdown, remove embeds and clear wikilinks // trim the markdown, remove embeds and clear wikilinks
@@ -100,12 +102,12 @@ export default class OmnisearchPlugin extends Plugin {
const body = removeTitleLine(content) const body = removeTitleLine(content)
// Make the document and index it // Make the document and index it
const note = { name: file.name, title, body, path: file.path } const note = { basename: file.basename, title, body, path: file.path }
this.minisearch.add(note) this.minisearch.add(note)
this.notes[file.path] = note this.notes[file.path] = note
} }
catch (e) { catch (e) {
console.trace('Error while indexing ' + file.name) console.trace('Error while indexing ' + file.basename)
console.error(e) console.error(e)
} }
} }
@@ -219,7 +221,7 @@ class OmnisearchModal extends SuggestModal<OmniNote> {
prefix: true, prefix: true,
fuzzy: term => (term.length > 4 ? 0.2 : false), fuzzy: term => (term.length > 4 ? 0.2 : false),
combineWith: 'AND', combineWith: 'AND',
boost: { name: 2, title: 1.5 }, boost: { basename: 2, title: 1.5 },
}) })
.sort((a, b) => b.score - a.score) .sort((a, b) => b.score - a.score)
.slice(0, 50) .slice(0, 50)
@@ -229,7 +231,7 @@ class OmnisearchModal extends SuggestModal<OmniNote> {
return results.map(result => { return results.map(result => {
const note = this.plugin.notes[result.id] const note = this.plugin.notes[result.id]
// result.id == the file's path // result.id == the file's path
let name = note.name let basename = note.basename
let title = note.title let title = note.title
let body = note.body let body = note.body
@@ -252,11 +254,11 @@ class OmnisearchModal extends SuggestModal<OmniNote> {
const reg = new RegExp(terms.map(escapeRegex).join('|'), 'gi') const reg = new RegExp(terms.map(escapeRegex).join('|'), 'gi')
body = body.replace(reg, highlighter) body = body.replace(reg, highlighter)
title = title.replace(reg, highlighter) title = title.replace(reg, highlighter)
name = name.replace(reg, highlighter) basename = basename.replace(reg, highlighter)
return { return {
path: result.id, path: result.id,
name, basename,
title, title,
body, body,
} }
@@ -272,7 +274,7 @@ class OmnisearchModal extends SuggestModal<OmniNote> {
// filename // filename
const name = document.createElement('span') const name = document.createElement('span')
name.className = 'osresult__name' name.className = 'osresult__name'
name.innerHTML = value.name name.innerHTML = value.basename
// body // body
const body = document.createElement('span') const body = document.createElement('span')
@@ -288,67 +290,3 @@ class OmnisearchModal extends SuggestModal<OmniNote> {
this.app.workspace.openLinkText(item.path, '') this.app.workspace.openLinkText(item.path, '')
} }
} }
function highlighter(str: string): string {
return '<span class="search-result-file-matched-text">' + str + '</span>'
}
/**
* Strips the markdown and frontmatter
* @param text
*/
function clearContent(text: string): string {
return markdownToTxt(removeFrontMatter(text))
}
/**
* The "title" line is the first line that isn't a wikilink
* @param text
* @returns
*/
function getTitleLineIndex(lines: string[]): number {
const index = lines.findIndex(l => !regexWikilink.test(l))
return index > -1 ? index : 0
}
/**
* Returns the "title" line from a text
* @param text
* @returns
*/
function getTitleLine(text: string): string {
const lines = splitLines(text.trim())
return lines[getTitleLineIndex(lines)]
}
/**
* Removes the "title" line from a text
* @param text
* @returns
*/
function removeTitleLine(text: string): string {
const lines = splitLines(text.trim())
const index = getTitleLineIndex(lines)
lines.splice(index, 1)
return lines.join('. ')
}
function splitLines(text: string): string[] {
return text.split(regexLineSplit).filter(l => !!l && l.length > 2)
}
function removeFrontMatter(text: string): string {
// Regex to recognize YAML Front Matter (at beginning of file, 3 hyphens, than any charecter, including newlines, then 3 hyphens).
return text.replace(regexYaml, '')
}
function wait(ms: number): Promise<void> {
return new Promise((resolve, reject) => {
setTimeout(resolve, ms)
})
}
// https://stackoverflow.com/a/3561711
function escapeRegex(str: string): string {
return str.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')
}

66
src/utils.ts Normal file
View File

@@ -0,0 +1,66 @@
import markdownToTxt from 'markdown-to-txt'
import { regexLineSplit, regexWikilink, regexYaml } from './globals'
export function highlighter(str: string): string {
return '<span class="search-result-file-matched-text">' + str + '</span>'
}
/**
* Strips the markdown and frontmatter
* @param text
*/
export function clearContent(text: string): string {
return markdownToTxt(removeFrontMatter(text))
}
/**
* The "title" line is the first line that isn't a wikilink
* @param text
* @returns
*/
export function getTitleLineIndex(lines: string[]): number {
const index = lines.findIndex(l => !regexWikilink.test(l))
return index > -1 ? index : 0
}
/**
* Returns the "title" line from a text
* @param text
* @returns
*/
export function getTitleLine(text: string): string {
const lines = splitLines(text.trim())
return lines[getTitleLineIndex(lines)]
}
/**
* Removes the "title" line from a text
* @param text
* @returns
*/
export function removeTitleLine(text: string): string {
const lines = splitLines(text.trim())
const index = getTitleLineIndex(lines)
lines.splice(index, 1)
return lines.join('. ')
}
export function splitLines(text: string): string[] {
return text.split(regexLineSplit).filter(l => !!l && l.length > 2)
}
export function removeFrontMatter(text: string): string {
// Regex to recognize YAML Front Matter (at beginning of file, 3 hyphens, than any charecter, including newlines, then 3 hyphens).
return text.replace(regexYaml, '')
}
export function wait(ms: number): Promise<void> {
return new Promise((resolve, reject) => {
setTimeout(resolve, ms)
})
}
// https://stackoverflow.com/a/3561711
export function escapeRegex(str: string): string {
return str.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&')
}