Skip to content

Commit

Permalink
feat: ✨ add doT
Browse files Browse the repository at this point in the history
  • Loading branch information
mrjackphil committed Jun 6, 2022
1 parent c181e9c commit 62fed1b
Show file tree
Hide file tree
Showing 3 changed files with 329 additions and 27 deletions.
80 changes: 53 additions & 27 deletions src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
import sequences, {Sequences} from "./sequences/sequences";
import {splitByLines} from "./helpers/string";
import {extractFilesFromSearchResults} from "./helpers/search-results";
import doT from "./modules/doT/doT";

interface PluginSettings {
delay: number
Expand Down Expand Up @@ -106,7 +107,7 @@ export default class TextExpander extends Plugin {
return
}

this.init(true)
await this.init(true)

})

Expand All @@ -123,8 +124,8 @@ export default class TextExpander extends Plugin {
console.log('unloading plugin');
}

saveSettings() {
this.saveData(this.config)
async saveSettings() {
await this.saveData(this.config)
}

private async init(proceedAllQueriesOnPage = false) {
Expand Down Expand Up @@ -180,16 +181,7 @@ export default class TextExpander extends Plugin {

const templateContent = query.template.split('\n')

const isHeader = (line: string) => line.startsWith(prefixes.header)
const isFooter = (line: string) => line.startsWith(prefixes.footer)
const isRepeat = (line: string) => !isHeader(line) && !isFooter(line)

const heading = templateContent.filter(isHeader).map((s) => s.slice(1))
const footer = templateContent.filter(isFooter).map((s) => s.slice(1))
const repeatableContent =
templateContent.filter(isRepeat).filter(e => e).length === 0
? [this.config.defaultTemplate]
: templateContent.filter(isRepeat).filter(e => e)
const {heading, footer, repeatableContent} = this.parseTemplate(prefixes, templateContent);

if (currentView instanceof FileView) {
currentFileName = currentView.file.basename
Expand All @@ -199,25 +191,33 @@ export default class TextExpander extends Plugin {

const files = extractFilesFromSearchResults(searchResults, currentFileName, this.config.excludeCurrent);

files.forEach(file => console.log(this.app.metadataCache.getFileCache(file)))

const changed = await Promise.all(
files
.map(async (file, i) => {
const result = await Promise.all(repeatableContent.map(async (s) => await this.applyTemplateToSearchResults(searchResults, file, s, i)))
return result.join('\n')
})
const filesInfo = await Promise.all(
files.map(async (file, i) => {
return Object.assign({},
file,
{
content: this.app.vault.cachedRead(file),
link: this.app.fileManager.generateMarkdownLink(file, file.path)
},
this.app.metadataCache.getFileCache(file))
})
)

const result = [
' ',
heading.join('\n'),
changed.join('\n'),
footer.join('\n'),
' ',
let changed = ''
if (query.template.contains("{{")) {
changed = doT.template(repeatableContent.join('\n'), { strip: false })({ files: filesInfo })
} else {
changed = await this.generateTemplateFromSequences(files, repeatableContent, searchResults);
}

let result = [
heading,
changed,
footer,
this.config.lineEnding
].filter(e => e).join('\n')


// Do not paste generated content if used changed activeLeaf
const viewBeforeReplace = this.app.workspace.activeLeaf.view
if (!(viewBeforeReplace instanceof MarkdownView) || viewBeforeReplace.file.basename !== currentFileName) {
Expand All @@ -231,6 +231,32 @@ export default class TextExpander extends Plugin {
return Promise.resolve()
}

private async generateTemplateFromSequences(files: TFile[], repeatableContent: string[], searchResults: Map<TFile, SearchDetails>): Promise<string> {
const changed = await Promise.all(
files
.map(async (file, i) => {
const result = await Promise.all(repeatableContent.map(async (s) => await this.applyTemplateToSearchResults(searchResults, file, s, i)))
return result.join('\n')
})
)

return changed.join('\n');
}

private parseTemplate(prefixes: { header: string; footer: string }, templateContent: string[]) {
const isHeader = (line: string) => line.startsWith(prefixes.header)
const isFooter = (line: string) => line.startsWith(prefixes.footer)
const isRepeat = (line: string) => !isHeader(line) && !isFooter(line)

const heading = templateContent.filter(isHeader).map((s) => s.slice(1)).join('\n')
const footer = templateContent.filter(isFooter).map((s) => s.slice(1)).join('\n')
const repeatableContent =
templateContent.filter(isRepeat).filter(e => e).length === 0
? [this.config.defaultTemplate]
: templateContent.filter(isRepeat).filter(e => e)
return {heading, footer, repeatableContent};
}

private search(s: string) {
// @ts-ignore
const globalSearchFn = this.app.internalPlugins.getPluginById('global-search').instance.openGlobalSearch.bind(this)
Expand Down
38 changes: 38 additions & 0 deletions src/modules/doT/doT.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
declare namespace doT {
function template(
tmpl: string,
cfg?: Partial<TemplateSettings>,
def?: Definitions
): TemplateFunction

function compile(tmpl: string, def?: Definitions): TemplateFunction

function setDelimiters({start, end}: Delimiters): void

interface TemplateSettings {
argName: string | string[]
encoders: {
[key: string]: Encoder
}
selfContained: boolean
strip: boolean
internalPrefix: string
encodersPrefix: string
delimiters: Delimiters
}

type TemplateFunction = (data: any) => string

interface Definitions {
[key: string]: string | Function | any
}

type Encoder = (data: any) => string

type Delimiters = {
start: string
end: string
}
}

export = doT
Loading

0 comments on commit 62fed1b

Please sign in to comment.