mirror of
https://github.com/harttle/liquidjs.git
synced 2026-09-18 22:10:41 -07:00
feat: support jekyll-like include, see #433
This commit is contained in:
@@ -92,15 +92,20 @@ export function parseFilePath (tokenizer: Tokenizer, liquid: Liquid): ParsedFile
|
||||
if (file.getText() === 'none') return null
|
||||
if (TypeGuards.isQuotedToken(file)) {
|
||||
// for filenames like "files/{{file}}", eval as liquid template
|
||||
const tpls = liquid.parse(evalQuotedToken(file))
|
||||
// for filenames like "files/file.liquid", extract the string directly
|
||||
if (tpls.length === 1 && TypeGuards.isHTMLToken(tpls[0].token)) return tpls[0].token.getContent()
|
||||
return tpls
|
||||
const templates = liquid.parse(evalQuotedToken(file))
|
||||
return optimize(templates)
|
||||
}
|
||||
return file
|
||||
}
|
||||
const filepath = tokenizer.readFileName().getText()
|
||||
return filepath === 'none' ? null : filepath
|
||||
const tokens = [...tokenizer.readFileNameTemplate(liquid.options)]
|
||||
const templates = optimize(liquid.parser.parseTokens(tokens))
|
||||
return templates === 'none' ? null : templates
|
||||
}
|
||||
|
||||
function optimize (templates: Template[]): string | Template[] {
|
||||
// for filenames like "files/file.liquid", extract the string directly
|
||||
if (templates.length === 1 && TypeGuards.isHTMLToken(templates[0].token)) return templates[0].token.getContent()
|
||||
return templates
|
||||
}
|
||||
|
||||
export function renderFilePath (file: ParsedFileName, ctx: Context, liquid: Liquid) {
|
||||
|
||||
+14
-10
@@ -33,7 +33,7 @@ export class Tokenizer {
|
||||
constructor (
|
||||
public input: string,
|
||||
private trie: Trie,
|
||||
private file: string = ''
|
||||
public file: string = ''
|
||||
) {
|
||||
this.N = input.length
|
||||
}
|
||||
@@ -119,15 +119,13 @@ export class Tokenizer {
|
||||
if (this.rawBeginAt > -1) return this.readEndrawOrRawContent(options)
|
||||
if (this.match(tagDelimiterLeft)) return this.readTagToken(options)
|
||||
if (this.match(outputDelimiterLeft)) return this.readOutputToken(options)
|
||||
return this.readHTMLToken(options)
|
||||
return this.readHTMLToken([tagDelimiterLeft, outputDelimiterLeft])
|
||||
}
|
||||
|
||||
readHTMLToken (options: NormalizedFullOptions): HTMLToken {
|
||||
readHTMLToken (stopStrings: string[]): HTMLToken {
|
||||
const begin = this.p
|
||||
while (this.p < this.N) {
|
||||
const { tagDelimiterLeft, outputDelimiterLeft } = options
|
||||
if (this.match(tagDelimiterLeft)) break
|
||||
if (this.match(outputDelimiterLeft)) break
|
||||
if (stopStrings.some(str => this.match(str))) break
|
||||
++this.p
|
||||
}
|
||||
return new HTMLToken(this.input, begin, this.p, this.file)
|
||||
@@ -334,10 +332,16 @@ export class Tokenizer {
|
||||
return new QuotedToken(this.input, begin, this.p, this.file)
|
||||
}
|
||||
|
||||
readFileName (): IdentifierToken {
|
||||
const begin = this.p
|
||||
while (!(this.peekType() & BLANK) && this.peek() !== ',' && this.p < this.N) this.p++
|
||||
return new IdentifierToken(this.input, begin, this.p, this.file)
|
||||
* readFileNameTemplate (options: NormalizedFullOptions): IterableIterator<TopLevelToken> {
|
||||
const { outputDelimiterLeft } = options
|
||||
const htmlStopStrings = [',', ' ', outputDelimiterLeft]
|
||||
const htmlStopStringSet = new Set(htmlStopStrings)
|
||||
// break on ',' and ' ', outputDelimiterLeft only stops HTML token
|
||||
while (this.p < this.N && !htmlStopStringSet.has(this.peek())) {
|
||||
yield this.match(outputDelimiterLeft)
|
||||
? this.readOutputToken(options)
|
||||
: this.readHTMLToken(htmlStopStrings)
|
||||
}
|
||||
}
|
||||
|
||||
match (word: string) {
|
||||
|
||||
Reference in New Issue
Block a user