mirror of
https://github.com/meld-cp/obsidian-build.git
synced 2026-07-22 07:30:25 +00:00
wip
This commit is contained in:
parent
00db6be084
commit
7f1575a849
10 changed files with 248 additions and 102 deletions
|
|
@ -16,6 +16,7 @@ Write and execute JavaScript in code blocks to render templates, query DataView
|
||||||
- [ ] better docs and examples
|
- [ ] better docs and examples
|
||||||
- [ ] alpha release
|
- [ ] alpha release
|
||||||
- [ ] test on mobile
|
- [ ] test on mobile
|
||||||
|
- [ ] better file logging
|
||||||
|
|
||||||
## Manually installing the plugin
|
## Manually installing the plugin
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ esbuild.build({
|
||||||
...builtins],
|
...builtins],
|
||||||
format: 'cjs',
|
format: 'cjs',
|
||||||
watch: !prod,
|
watch: !prod,
|
||||||
target: 'es2018',
|
target: 'es2021',
|
||||||
logLevel: "info",
|
logLevel: "info",
|
||||||
sourcemap: prod ? false : 'inline',
|
sourcemap: prod ? false : 'inline',
|
||||||
treeShaking: true,
|
treeShaking: true,
|
||||||
|
|
|
||||||
53
main.ts
53
main.ts
|
|
@ -11,12 +11,19 @@ const DEFAULT_SETTINGS: MeldBuildPluginSettings = {
|
||||||
mySetting: 'default'
|
mySetting: 'default'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CODE_BLOCK_LANG_TOOLBAR = 'meld-build-toolbar';
|
||||||
|
|
||||||
export default class MeldBuildPlugin extends Plugin {
|
export default class MeldBuildPlugin extends Plugin {
|
||||||
settings: MeldBuildPluginSettings;
|
settings: MeldBuildPluginSettings;
|
||||||
|
|
||||||
|
|
||||||
async onload() {
|
async onload() {
|
||||||
|
|
||||||
|
//console.debug((app as any).commands.commands);
|
||||||
|
|
||||||
await this.loadSettings();
|
await this.loadSettings();
|
||||||
|
|
||||||
|
await this.reloadActiveViewsWithToolbars();
|
||||||
|
|
||||||
this.registerHandlebarHelpers();
|
this.registerHandlebarHelpers();
|
||||||
|
|
||||||
|
|
@ -27,7 +34,7 @@ export default class MeldBuildPlugin extends Plugin {
|
||||||
// });
|
// });
|
||||||
// });
|
// });
|
||||||
|
|
||||||
this.registerMarkdownCodeBlockProcessor('meld-build-toolbar', (source, el, ctx) => {
|
this.registerMarkdownCodeBlockProcessor( CODE_BLOCK_LANG_TOOLBAR, (source, el, ctx) => {
|
||||||
const lines = source.split('\n');
|
const lines = source.split('\n');
|
||||||
const valueMap = new Map<string,string>();
|
const valueMap = new Map<string,string>();
|
||||||
lines.forEach(line => {
|
lines.forEach(line => {
|
||||||
|
|
@ -44,14 +51,8 @@ export default class MeldBuildPlugin extends Plugin {
|
||||||
const showHelpButton = helpButtonLabel !== '';
|
const showHelpButton = helpButtonLabel !== '';
|
||||||
|
|
||||||
if (showRunButton){
|
if (showRunButton){
|
||||||
el.createEl('button', { text: runButtonLabel ?? 'Run'}, el =>{
|
el.createEl('button', { text: runButtonLabel ?? 'Run'}, el => {
|
||||||
el.on('click', '*', ev=>{
|
el.on('click', '*', ev => this.buildAndRunActiveView() );
|
||||||
const view = app.workspace.getActiveViewOfType( MarkdownView );
|
|
||||||
if (!view){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.buildAndRun(view.editor, view);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -75,7 +76,37 @@ export default class MeldBuildPlugin extends Plugin {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private buildAndRun( editor:Editor, view: MarkdownView ){
|
private async reloadActiveViewsWithToolbars(){
|
||||||
|
app.workspace.iterateAllLeaves( leaf =>{
|
||||||
|
const view = leaf.view;
|
||||||
|
if ( view instanceof MarkdownView ){
|
||||||
|
|
||||||
|
if (!view.editor.getValue().contains(CODE_BLOCK_LANG_TOOLBAR)){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.debug( `Meld-Build::Rebuilding view for file '${view.file.path}'` );
|
||||||
|
|
||||||
|
(view.leaf as any).rebuildView();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
//const view = app.workspace.getActiveViewOfType( MarkdownView );
|
||||||
|
//if (view == null){
|
||||||
|
// return;
|
||||||
|
//}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private async buildAndRunActiveView(){
|
||||||
|
const view = app.workspace.getActiveViewOfType( MarkdownView );
|
||||||
|
if (!view){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await this.buildAndRun( view.editor, view);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async buildAndRun( editor:Editor, view: MarkdownView ){
|
||||||
const logger = new RunLogger();
|
const logger = new RunLogger();
|
||||||
try{
|
try{
|
||||||
//await view.save();
|
//await view.save();
|
||||||
|
|
@ -83,7 +114,7 @@ export default class MeldBuildPlugin extends Plugin {
|
||||||
const runner = compiler.compile(logger, editor, view);
|
const runner = compiler.compile(logger, editor, view);
|
||||||
runner();
|
runner();
|
||||||
}catch(e){
|
}catch(e){
|
||||||
logger.error(e);
|
await logger.error(e);
|
||||||
new Notice(e);
|
new Notice(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
8
src/code-block-info.ts
Normal file
8
src/code-block-info.ts
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
export class CodeBlockInfo{
|
||||||
|
public language:string;
|
||||||
|
public params:string[];
|
||||||
|
constructor( language: string, params?:string[] ){
|
||||||
|
this.language = language;
|
||||||
|
this.params = params ?? [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -8,6 +8,7 @@ import { DataSet, IDataSetCollection } from "src/data-set";
|
||||||
import { Parser } from "src/parser";
|
import { Parser } from "src/parser";
|
||||||
import { RunLogger } from 'src/run-logger';
|
import { RunLogger } from 'src/run-logger';
|
||||||
import { TRunContext } from "src/run-context";
|
import { TRunContext } from "src/run-context";
|
||||||
|
import { NamedCodeBlock } from "./named-code-block";
|
||||||
|
|
||||||
export class Compiler{
|
export class Compiler{
|
||||||
private templateLanguages = ['html', 'css'];
|
private templateLanguages = ['html', 'css'];
|
||||||
|
|
@ -23,6 +24,8 @@ export class Compiler{
|
||||||
// build context
|
// build context
|
||||||
const context = this.build_run_context(logger, editor, fileCache, view);
|
const context = this.build_run_context(logger, editor, fileCache, view);
|
||||||
|
|
||||||
|
//console.debug(context.sourceCode);
|
||||||
|
|
||||||
// return runner
|
// return runner
|
||||||
return () => this.buildSandboxedRunnerFunction(context);
|
return () => this.buildSandboxedRunnerFunction(context);
|
||||||
//return () => this.buildRunnerFunction(sourceCode, context);
|
//return () => this.buildRunnerFunction(sourceCode, context);
|
||||||
|
|
@ -45,8 +48,14 @@ export class Compiler{
|
||||||
// templates
|
// templates
|
||||||
const templateBlocks = pzr.fetchCodeBlocks( editor, fileCache, this.templateLanguages );
|
const templateBlocks = pzr.fetchCodeBlocks( editor, fileCache, this.templateLanguages );
|
||||||
|
|
||||||
|
|
||||||
|
// source code
|
||||||
|
const sourceCode = codeBlocks.map( e=>e.content ).join('\n');
|
||||||
|
|
||||||
|
//console.debug({sourceCode});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
sourceCode: codeBlocks.join('\n'),
|
sourceCode: sourceCode,
|
||||||
|
|
||||||
data: data,
|
data: data,
|
||||||
templates: templateBlocks,
|
templates: templateBlocks,
|
||||||
|
|
@ -54,10 +63,15 @@ export class Compiler{
|
||||||
logger : log,
|
logger : log,
|
||||||
log: async (...x) => await log.info( ...x ),
|
log: async (...x) => await log.info( ...x ),
|
||||||
|
|
||||||
render( template, data ) {
|
render( template:string|NamedCodeBlock, data:any ) {
|
||||||
const templateBuilder = HB.compile( template );
|
|
||||||
const result = templateBuilder(data);
|
if( typeof template == 'string' ){
|
||||||
return result;
|
return HB.compile( template )(data);
|
||||||
|
}else if ( template instanceof NamedCodeBlock ){
|
||||||
|
return HB.compile( template.content )(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return '';
|
||||||
},
|
},
|
||||||
|
|
||||||
ui: {
|
ui: {
|
||||||
|
|
@ -255,7 +269,7 @@ export class Compiler{
|
||||||
private async import(
|
private async import(
|
||||||
log: RunLogger,
|
log: RunLogger,
|
||||||
data: IDataSetCollection,
|
data: IDataSetCollection,
|
||||||
templates: string[],
|
templates: NamedCodeBlock[],
|
||||||
path:string
|
path:string
|
||||||
) : Promise<boolean>{
|
) : Promise<boolean>{
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
export class DataSet extends Array<DataSetRow> {
|
export class DataSet extends Array<DataSetRow> {
|
||||||
// TODO: is this needed?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IDataSetCollection {
|
export interface IDataSetCollection {
|
||||||
|
|
|
||||||
14
src/named-code-block.ts
Normal file
14
src/named-code-block.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { CodeBlockInfo } from "./code-block-info";
|
||||||
|
|
||||||
|
export class NamedCodeBlock{
|
||||||
|
|
||||||
|
public info:CodeBlockInfo;
|
||||||
|
public name:string;
|
||||||
|
public content:string;
|
||||||
|
|
||||||
|
constructor( info:CodeBlockInfo, name:string, content:string ){
|
||||||
|
this.info = info,
|
||||||
|
this.name = name;
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
}
|
||||||
230
src/parser.ts
230
src/parser.ts
|
|
@ -1,14 +1,136 @@
|
||||||
import { DataSet, DataSetRow, IDataSetCollection } from "src/data-set";
|
import { DataSet, DataSetRow, IDataSetCollection } from "src/data-set";
|
||||||
import { CachedMetadata, Editor } from "obsidian";
|
import { CachedMetadata, Editor } from "obsidian";
|
||||||
|
import { NamedCodeBlock } from "./named-code-block";
|
||||||
|
import { CodeBlockInfo } from "./code-block-info";
|
||||||
|
|
||||||
export class Parser {
|
export class Parser {
|
||||||
|
|
||||||
|
public fetchCodeBlocks(
|
||||||
|
editor: Editor,
|
||||||
|
fileCache: CachedMetadata | undefined,
|
||||||
|
languages :string[]
|
||||||
|
): NamedCodeBlock[] {
|
||||||
|
const result: NamedCodeBlock[] = [];
|
||||||
|
|
||||||
|
if ( fileCache == undefined ){
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( fileCache.sections == undefined ){
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//console.log(fileCache.sections);
|
||||||
|
const codeBlocks = fileCache.sections?.filter( s => ['heading','code'].contains( s.type ) ) ?? [];
|
||||||
|
//console.debug({codeBlocks});
|
||||||
|
|
||||||
|
let cbName = '';
|
||||||
|
codeBlocks.forEach( codeBlockSection => {
|
||||||
|
|
||||||
|
const from = editor.offsetToPos( codeBlockSection.position.start.offset );
|
||||||
|
const to = editor.offsetToPos( codeBlockSection.position.end.offset );
|
||||||
|
const content = editor.getRange( from, to );
|
||||||
|
|
||||||
|
//console.debug(content);
|
||||||
|
|
||||||
|
if ( codeBlockSection.type == 'heading' ){
|
||||||
|
cbName = this.extractHeaderName(content);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// code block
|
||||||
|
const lines = content.split('\n');
|
||||||
|
if ( lines.length <= 2 ){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// filter languages
|
||||||
|
const codeBlockInfo = this.extractCodeBlockInfo(lines[0]);
|
||||||
|
if (!codeBlockInfo){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( !languages.contains( codeBlockInfo.language ) ){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove first and last lines
|
||||||
|
const cbContent = lines.slice(1,-1).join('\n');
|
||||||
|
|
||||||
|
const codeBlock = new NamedCodeBlock( codeBlockInfo, cbName, cbContent );
|
||||||
|
|
||||||
|
result.push( codeBlock );
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private extractCodeBlockInfo( line:string ) : CodeBlockInfo | null {
|
||||||
|
/*
|
||||||
|
match tests
|
||||||
|
```lang => { language: 'lang', params:[] }
|
||||||
|
```lang with space => { language: 'lang', params:['with','space'] }
|
||||||
|
``` whitespaced => { language: 'whitespaced', params:[] }
|
||||||
|
```` multitick => { language: 'multitick', params:[] }
|
||||||
|
````multitick with space => { language: 'multitick', params:['with','space'] }
|
||||||
|
*/
|
||||||
|
const matches = line.match(/````*\s*([a-z0-9-]+)(?:\s*([a-z0-9-]+))*/i);
|
||||||
|
|
||||||
|
//console.debug(matches);
|
||||||
|
|
||||||
|
if ( matches == null ){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const lang = matches.at(1);
|
||||||
|
if ( lang === undefined ){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const params:string[] = matches.slice(2).filter( e => e );
|
||||||
|
//console.debug({params});
|
||||||
|
|
||||||
|
return new CodeBlockInfo( lang, params );
|
||||||
|
}
|
||||||
|
|
||||||
|
// private matchesCodeBlockStart( line:string, languages:string[] ) : boolean {
|
||||||
|
|
||||||
|
// const cbInfo = this.extractCodeBlockInfo(line);
|
||||||
|
|
||||||
|
// if ( cbInfo == null ){
|
||||||
|
// return false;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// return languages.contains( cbInfo?.language );
|
||||||
|
// }
|
||||||
|
|
||||||
|
public loadCsv( csvContent:string ) : DataSet {
|
||||||
|
const lines = csvContent.split('\n').map( e=>e.trim() );
|
||||||
|
if (lines.length == 0){
|
||||||
|
return new DataSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
const columns = lines.first()?.split(',').map( e => this.extractAsColumnName(e) ) ?? [];
|
||||||
|
|
||||||
|
const rows = new Array<DataSetRow>();
|
||||||
|
|
||||||
|
for (let i = 1; i < lines.length; i++) {
|
||||||
|
const rowData = lines[i].split(',').map( d => this.extractValueFromString(d));
|
||||||
|
rows.push( new DataSetRow(columns, rowData));
|
||||||
|
}
|
||||||
|
|
||||||
|
const ds = new DataSet( ...rows );
|
||||||
|
|
||||||
|
return ds;
|
||||||
|
}
|
||||||
|
|
||||||
public applyMarkdownContent(
|
public applyMarkdownContent(
|
||||||
name:string,
|
name:string,
|
||||||
content:string,
|
content:string,
|
||||||
data:IDataSetCollection,
|
data:IDataSetCollection,
|
||||||
templates:string[],
|
templates:NamedCodeBlock[],
|
||||||
templateLanguages: string[]
|
templateLanguageFilter: string[]
|
||||||
) : void {
|
) : void {
|
||||||
|
|
||||||
const lines = content.split('\n');
|
const lines = content.split('\n');
|
||||||
|
|
@ -17,12 +139,15 @@ export class Parser {
|
||||||
let currentHeader = '';
|
let currentHeader = '';
|
||||||
for ( let i = 0; i < lines.length; i++ ) {
|
for ( let i = 0; i < lines.length; i++ ) {
|
||||||
const trimLine = lines[i].trim();
|
const trimLine = lines[i].trim();
|
||||||
if (trimLine.startsWith('#')){
|
|
||||||
|
const codeBlockInfo = this.extractCodeBlockInfo(trimLine);
|
||||||
|
|
||||||
|
if ( trimLine.startsWith('#') ) {
|
||||||
|
|
||||||
// header
|
// header
|
||||||
currentHeader = this.extractHeader(trimLine);
|
currentHeader = this.extractHeaderName(trimLine);
|
||||||
|
|
||||||
}else if ( trimLine.startsWith('|') ){
|
} else if ( trimLine.startsWith('|') ){
|
||||||
|
|
||||||
// extract table
|
// extract table
|
||||||
const tableLines: string[] = [];
|
const tableLines: string[] = [];
|
||||||
|
|
@ -31,10 +156,10 @@ export class Parser {
|
||||||
tableLines.push(tableLine);
|
tableLines.push(tableLine);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
const dataPropName = this.convertToTableName( currentHeader.length > 0 ? currentHeader : name );
|
const dataPropName = this.extractAsTableName( currentHeader.length > 0 ? currentHeader : name );
|
||||||
data[dataPropName] = this.parseAsMdTable(tableLines);
|
data[dataPropName] = this.parseMdTable(tableLines);
|
||||||
|
|
||||||
}else if ( templateLanguages.find( v => trimLine.toLowerCase().startsWith('```' + v) ) !== undefined ){
|
} else if ( codeBlockInfo && templateLanguageFilter.contains( codeBlockInfo.language ) ){
|
||||||
|
|
||||||
// extract template codeblock
|
// extract template codeblock
|
||||||
const templateLines: string[] = [];
|
const templateLines: string[] = [];
|
||||||
|
|
@ -44,17 +169,24 @@ export class Parser {
|
||||||
templateLines.push(templateLine);
|
templateLines.push(templateLine);
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
templates.push( templateLines.join('\n') );
|
|
||||||
|
const codeBlock = new NamedCodeBlock(
|
||||||
|
codeBlockInfo,
|
||||||
|
name,
|
||||||
|
templateLines.join('\n')
|
||||||
|
);
|
||||||
|
|
||||||
|
templates.push( codeBlock );
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private extractHeader(line:string) : string{
|
private extractHeaderName(line:string) : string{
|
||||||
return this.convertToTableName(line.replace('#','').trim());
|
return line.replaceAll('#','').trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
private parseAsMdTable( tableLines:string[] ): DataSet {
|
private parseMdTable( tableLines:string[] ): DataSet {
|
||||||
const data: DataSet = new DataSet();
|
const data: DataSet = new DataSet();
|
||||||
|
|
||||||
const tlines = tableLines
|
const tlines = tableLines
|
||||||
|
|
@ -63,7 +195,7 @@ export class Parser {
|
||||||
//console.debug(tableLines);
|
//console.debug(tableLines);
|
||||||
const columns = tlines
|
const columns = tlines
|
||||||
.first()?.split('|')
|
.first()?.split('|')
|
||||||
.map( e=> this.convertToColumnName(e) )
|
.map( e=> this.extractAsColumnName(e) )
|
||||||
.filter( e=>e.length > 0)
|
.filter( e=>e.length > 0)
|
||||||
?? []
|
?? []
|
||||||
;
|
;
|
||||||
|
|
@ -77,7 +209,7 @@ export class Parser {
|
||||||
if (rowLine.startsWith('|') && rowLine.endsWith('|')){
|
if (rowLine.startsWith('|') && rowLine.endsWith('|')){
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const rowValues : unknown[] = rowLine.split('|').map( e => this.covertFromString(e) );
|
const rowValues : unknown[] = rowLine.split('|').map( e => this.extractValueFromString(e) );
|
||||||
data.push( new DataSetRow( columns, rowValues ) );
|
data.push( new DataSetRow( columns, rowValues ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -113,9 +245,9 @@ export class Parser {
|
||||||
const to = editor.offsetToPos(section.position.end.offset);
|
const to = editor.offsetToPos(section.position.end.offset);
|
||||||
const table = editor.getRange( from, to );
|
const table = editor.getRange( from, to );
|
||||||
const tableLines = table.split('\n');
|
const tableLines = table.split('\n');
|
||||||
const data = this.parseAsMdTable(tableLines);
|
const data = this.parseMdTable(tableLines);
|
||||||
|
|
||||||
const tableName = this.convertToTableName(lastHeading);
|
const tableName = this.extractAsTableName(lastHeading);
|
||||||
result[tableName] = data;
|
result[tableName] = data;
|
||||||
//result.push( data );
|
//result.push( data );
|
||||||
|
|
||||||
|
|
@ -152,15 +284,15 @@ export class Parser {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private convertToTableName( str:string ) : string {
|
private extractAsTableName( str:string ) : string {
|
||||||
return str.trim().replace(/\W/ig, '_').toLowerCase();
|
return str.trim().replaceAll(/\W/ig, '_').toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
private convertToColumnName( str:string ) : string {
|
private extractAsColumnName( str:string ) : string {
|
||||||
return str.trim().replace(/\W/ig, '_').toLowerCase();
|
return str.trim().replaceAll(/\W/ig, '_').toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
private covertFromString( str:string ) : string | number | Date {
|
private extractValueFromString( str:string ) : string | number | Date {
|
||||||
const trimmed = str.trim();
|
const trimmed = str.trim();
|
||||||
//console.debug({trimmed});
|
//console.debug({trimmed});
|
||||||
//see: https://rgxdb.com/r/526K7G5W
|
//see: https://rgxdb.com/r/526K7G5W
|
||||||
|
|
@ -183,61 +315,5 @@ export class Parser {
|
||||||
return trimmed;
|
return trimmed;
|
||||||
}
|
}
|
||||||
|
|
||||||
public fetchCodeBlocks(
|
|
||||||
editor: Editor,
|
|
||||||
fileCache: CachedMetadata | undefined,
|
|
||||||
languages :string[]
|
|
||||||
): string[] {
|
|
||||||
const result: string[] = [];
|
|
||||||
|
|
||||||
if ( fileCache == undefined ){
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( fileCache.sections == undefined ){
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
fileCache.sections.forEach( section => {
|
|
||||||
if (section.type != 'code'){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const from = editor.offsetToPos(section.position.start.offset);
|
|
||||||
const to = editor.offsetToPos(section.position.end.offset);
|
|
||||||
const code = editor.getRange( from, to );
|
|
||||||
let lines = code.split('\n');
|
|
||||||
if (lines.length <= 2){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const lineStarts = languages.map( l=> '```'+l );
|
|
||||||
if ( !lineStarts.find( e=> e.startsWith( lines[0].toLowerCase() ) )){
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// remove first and last lines
|
|
||||||
lines = lines.slice(1,-1)
|
|
||||||
result.push( lines.join('\n') );
|
|
||||||
});
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public loadCsv( csvdata:string ) : DataSet {
|
|
||||||
const lines = csvdata.split('\n').map( e=>e.trim());
|
|
||||||
if (lines.length == 0){
|
|
||||||
return new DataSet();
|
|
||||||
}
|
|
||||||
//console.debug(lines);
|
|
||||||
const columns = lines.first()?.split(',').map( e=> this.convertToColumnName(e) ) ?? [];
|
|
||||||
|
|
||||||
const rows = new Array<DataSetRow>();
|
|
||||||
|
|
||||||
for (let i = 1; i < lines.length; i++) {
|
|
||||||
const rowData = lines[i].split(',').map( d=>this.covertFromString(d));
|
|
||||||
rows.push( new DataSetRow(columns, rowData));
|
|
||||||
}
|
|
||||||
|
|
||||||
const ds = new DataSet( ...rows );
|
|
||||||
//ds.columns = columns;
|
|
||||||
return ds;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,18 @@
|
||||||
import { DataSet, IDataSetCollection } from "src/data-set";
|
import { DataSet, IDataSetCollection } from "src/data-set";
|
||||||
import { DataviewApi } from "obsidian-dataview";
|
import { DataviewApi } from "obsidian-dataview";
|
||||||
import { RunLogger } from "src/run-logger";
|
import { RunLogger } from "src/run-logger";
|
||||||
|
import { NamedCodeBlock } from "./named-code-block";
|
||||||
|
|
||||||
export type TRunContext = {
|
export type TRunContext = {
|
||||||
|
|
||||||
sourceCode: string;
|
sourceCode: string;
|
||||||
|
|
||||||
data: IDataSetCollection;
|
data: IDataSetCollection;
|
||||||
templates: string[];
|
templates: NamedCodeBlock[];
|
||||||
|
|
||||||
logger: RunLogger,
|
logger: RunLogger,
|
||||||
log( ...params: any[] ) : Promise<void>;
|
log( ...params: any[] ) : Promise<void>;
|
||||||
render( template:string, data:any ) : string;
|
render( template:string|NamedCodeBlock, data:any ) : string;
|
||||||
|
|
||||||
ui: TUiRunContext;
|
ui: TUiRunContext;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
"inlineSourceMap": true,
|
"inlineSourceMap": true,
|
||||||
"inlineSources": true,
|
"inlineSources": true,
|
||||||
"module": "ESNext",
|
"module": "ESNext",
|
||||||
"target": "ES6",
|
"target": "ES2021",
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"noImplicitAny": true,
|
"noImplicitAny": true,
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
|
|
@ -13,9 +13,10 @@
|
||||||
"strictNullChecks": true,
|
"strictNullChecks": true,
|
||||||
"lib": [
|
"lib": [
|
||||||
"DOM",
|
"DOM",
|
||||||
"ES5",
|
//"ES5",
|
||||||
"ES6",
|
//"ES6",
|
||||||
"ES7"
|
//"ES7"
|
||||||
|
"ES2021"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"include": [
|
"include": [
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue