mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 02:16:05 +01:00 
			
		
		
		
	parse incomplete attrs
This commit is contained in:
		| @@ -12,6 +12,12 @@ describe("Lexer", () => { | |||||||
|             .toEqual(["#label", "=", "Hallo"]); |             .toEqual(["#label", "=", "Hallo"]); | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|  |     it("label with value", () => { | ||||||
|  |         const tokens = attributeParser.lexer("#label=Hallo"); | ||||||
|  |         expect(tokens[0].startIndex).toEqual(0); | ||||||
|  |         expect(tokens[0].endIndex).toEqual(5); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|     it("relation with value", () => { |     it("relation with value", () => { | ||||||
|         expect(attributeParser.lexer('~relation=<a class="reference-link" href="#root/RclIpMauTOKS/NFi2gL4xtPxM" data-note-path="root/RclIpMauTOKS/NFi2gL4xtPxM">note</a>').map(t => t.text)) |         expect(attributeParser.lexer('~relation=<a class="reference-link" href="#root/RclIpMauTOKS/NFi2gL4xtPxM" data-note-path="root/RclIpMauTOKS/NFi2gL4xtPxM">note</a>').map(t => t.text)) | ||||||
|             .toEqual(["~relation", "=", "#root/RclIpMauTOKS/NFi2gL4xtPxM"]); |             .toEqual(["~relation", "=", "#root/RclIpMauTOKS/NFi2gL4xtPxM"]); | ||||||
|   | |||||||
| @@ -43,7 +43,7 @@ function lexer(str) { | |||||||
|  |  | ||||||
|         tokens.push({ |         tokens.push({ | ||||||
|             text: currentWord, |             text: currentWord, | ||||||
|             startIndex: endIndex - currentWord.length, |             startIndex: endIndex - currentWord.length + 1, | ||||||
|             endIndex: endIndex |             endIndex: endIndex | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
| @@ -110,7 +110,7 @@ function lexer(str) { | |||||||
|     return tokens; |     return tokens; | ||||||
| } | } | ||||||
|  |  | ||||||
| function parser(tokens) { | function parser(tokens, allowEmptyRelations = false) { | ||||||
|     const attrs = []; |     const attrs = []; | ||||||
|  |  | ||||||
|     for (let i = 0; i < tokens.length; i++) { |     for (let i = 0; i < tokens.length; i++) { | ||||||
| @@ -121,8 +121,8 @@ function parser(tokens) { | |||||||
|                 type: 'label', |                 type: 'label', | ||||||
|                 name: text.substr(1), |                 name: text.substr(1), | ||||||
|                 isInheritable: false, // FIXME |                 isInheritable: false, // FIXME | ||||||
|                 startIndex, |                 nameStartIndex: startIndex, | ||||||
|                 endIndex |                 nameEndIndex: endIndex | ||||||
|             }; |             }; | ||||||
|  |  | ||||||
|             if (i + 1 < tokens.length && tokens[i + 1].text === "=") { |             if (i + 1 < tokens.length && tokens[i + 1].text === "=") { | ||||||
| @@ -133,14 +133,31 @@ function parser(tokens) { | |||||||
|                 i += 2; |                 i += 2; | ||||||
|  |  | ||||||
|                 attr.value = tokens[i].text; |                 attr.value = tokens[i].text; | ||||||
|  |                 attr.valueStartIndex = tokens[i].startIndex; | ||||||
|  |                 attr.valueEndIndex = tokens[i].endIndex; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             attrs.push(attr); |             attrs.push(attr); | ||||||
|         } |         } | ||||||
|         else if (text.startsWith('~')) { |         else if (text.startsWith('~')) { | ||||||
|  |             const attr = { | ||||||
|  |                 type: 'relation', | ||||||
|  |                 name: text.substr(1), | ||||||
|  |                 isInheritable: false, // FIXME | ||||||
|  |                 nameStartIndex: startIndex, | ||||||
|  |                 nameEndIndex: endIndex | ||||||
|  |             }; | ||||||
|  |  | ||||||
|  |             attrs.push(attr); | ||||||
|  |  | ||||||
|             if (i + 2 >= tokens.length || tokens[i + 1].text !== '=') { |             if (i + 2 >= tokens.length || tokens[i + 1].text !== '=') { | ||||||
|  |                 if (allowEmptyRelations) { | ||||||
|  |                     break; | ||||||
|  |                 } | ||||||
|  |                 else { | ||||||
|                     throw new Error(`Relation "${text}" should point to a note.`); |                     throw new Error(`Relation "${text}" should point to a note.`); | ||||||
|                 } |                 } | ||||||
|  |             } | ||||||
|  |  | ||||||
|             i += 2; |             i += 2; | ||||||
|  |  | ||||||
| @@ -151,16 +168,9 @@ function parser(tokens) { | |||||||
|  |  | ||||||
|             const noteId = notePath.split('/').pop(); |             const noteId = notePath.split('/').pop(); | ||||||
|  |  | ||||||
|             const attr = { |             attr.value = noteId; | ||||||
|                 type: 'relation', |             attr.valueStartIndex = tokens[i].startIndex; | ||||||
|                 name: text.substr(1), |             attr.valueEndIndex = tokens[i].endIndex; | ||||||
|                 isInheritable: false, // FIXME |  | ||||||
|                 value: noteId, |  | ||||||
|                 startIndex, |  | ||||||
|                 endIndex |  | ||||||
|             }; |  | ||||||
|  |  | ||||||
|             attrs.push(attr); |  | ||||||
|         } |         } | ||||||
|         else { |         else { | ||||||
|             throw new Error(`Unrecognized attribute "${text}"`); |             throw new Error(`Unrecognized attribute "${text}"`); | ||||||
| @@ -170,10 +180,10 @@ function parser(tokens) { | |||||||
|     return attrs; |     return attrs; | ||||||
| } | } | ||||||
|  |  | ||||||
| function lexAndParse(str) { | function lexAndParse(str, allowEmptyRelations = false) { | ||||||
|     const tokens = lexer(str); |     const tokens = lexer(str); | ||||||
|  |  | ||||||
|     return parser(tokens); |     return parser(tokens, allowEmptyRelations); | ||||||
| } | } | ||||||
|  |  | ||||||
| export default { | export default { | ||||||
|   | |||||||
| @@ -116,7 +116,17 @@ export default class NoteAttributesWidget extends TabAwareWidget { | |||||||
|  |  | ||||||
|         this.$editor.on("click", () => { |         this.$editor.on("click", () => { | ||||||
|             const pos = this.textEditor.model.document.selection.getFirstPosition(); |             const pos = this.textEditor.model.document.selection.getFirstPosition(); | ||||||
|             console.log(pos.textNode && pos.textNode.data, pos.parent.textNode && pos.parent.textNode.data, pos.offset); |  | ||||||
|  |             if (pos && pos.textNode && pos.textNode.data) { | ||||||
|  |                 const attr = pos.textNode.data; | ||||||
|  |                 const index = pos.offset - pos.textNode.startOffset; | ||||||
|  |  | ||||||
|  |                 const attrs = attributesParser.lexAndParse(attr, true); | ||||||
|  |  | ||||||
|  |                 console.log(attrs); | ||||||
|  |  | ||||||
|  |                 console.log(attr.substr(0, index) + '|' + attr.substr(index)); | ||||||
|  |             } | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|         this.textEditor = await BalloonEditor.create(this.$editor[0], { |         this.textEditor = await BalloonEditor.create(this.$editor[0], { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user