diff --git a/src/AgreementData.tsx b/src/AgreementData.tsx index 9b70534..732a7c9 100644 --- a/src/AgreementData.tsx +++ b/src/AgreementData.tsx @@ -1,4 +1,4 @@ -import MarkdownEditor from './MarkdownEditor'; +import JSONEditor from './JSONEditor'; import useAppStore from './store'; function AgreementData() { @@ -15,7 +15,7 @@ function AgreementData() {

Data

JSON data (an instance of the Concerto model) used to preview output from the template.
- + ; } diff --git a/src/ConcertoEditor.tsx b/src/ConcertoEditor.tsx new file mode 100644 index 0000000..175cf3e --- /dev/null +++ b/src/ConcertoEditor.tsx @@ -0,0 +1,76 @@ +import * as monaco from '@monaco-editor/react'; +import { editor } from 'monaco-editor'; + +const options:editor.IStandaloneEditorConstructionOptions = { + minimap: { enabled: false }, + wordWrap: "on" +} +const concertoKeywords = ['map','concept','from','optional','default','range','regex','length','abstract','namespace','import', 'enum', 'scalar', 'extends', 'default', 'participant','asset', 'o','identified by','transaction','event']; +const concertoTypes = ['String','Integer','Double','DateTime','Long','Boolean'] + +export default function ConcertoEditor( {value, onChange} : {value: string, onChange?: (value:string|undefined) => void} ) { + + function handleEditorWillMount(monaco:monaco.Monaco) { + monaco.languages.register({ + id: 'concerto', + extensions: ['.cto'], + aliases: ['Concerto', 'concerto'], + mimetypes: ['application/vnd.accordproject.concerto'], + }); + + monaco.languages.setMonarchTokensProvider('concerto', { + keywords: concertoKeywords, + typeKeywords: concertoTypes, + operators: ['=', '{', '}', '@', '"'], + symbols: /[=}{@"]+/, + escapes: /\\(?:[btnfru"'\\]|\\u[0-9A-Fa-f]{4})/, + tokenizer: { + root: [ + { include: '@whitespace' }, + [/[a-zA-Z_]\w*/, { + cases: { + '@keywords': 'keyword', + '@typeKeywords': 'type', + '@default': 'identifier', + }, + }], + [/"([^"\\]|\\.)*$/, 'string.invalid'], // non-terminated string + [/"/, 'string', '@string'], + ], + string: [ + [/[^\\"]+/, 'string'], + [/@escapes/, 'string.escape'], + [/\\./, 'string.escape.invalid'], + [/"/, 'string', '@pop'], + ], + whitespace: [ + [/\s+/, 'white'], + [/(\/\/.*)/, 'comment'], + ], + }, + }); + monaco.editor.defineTheme('concertoTheme', { + base: 'vs', + inherit: true, + rules: [ + { token: 'keyword', foreground: 'cd2184' }, + { token: 'type', foreground: '008080' }, + { token: 'identifier', foreground: '000000' }, + { token: 'string', foreground: '008000' }, + { token: 'string.escape', foreground: '800000' }, + { token: 'comment', foreground: '808080' }, + { token: 'white', foreground: 'FFFFFF' }, + ], + colors: {}, + }); + + monaco.editor.setTheme('concertoTheme'); + } + + return ( +
+ +
+ ); +} \ No newline at end of file diff --git a/src/JSONEditor.tsx b/src/JSONEditor.tsx new file mode 100644 index 0000000..bf24ec8 --- /dev/null +++ b/src/JSONEditor.tsx @@ -0,0 +1,18 @@ +import * as monaco from '@monaco-editor/react'; +import { editor } from 'monaco-editor'; + +const options:editor.IStandaloneEditorConstructionOptions = { + minimap: { enabled: false }, + wordWrap: "on", + automaticLayout:true +} + +export default function JSONEditor( {value, onChange} : {value: string, onChange?: (value:string|undefined) => void} ) { + + return ( +
+ +
+ ); +} \ No newline at end of file diff --git a/src/TemplateModel.tsx b/src/TemplateModel.tsx index c1c1852..3f74ffc 100644 --- a/src/TemplateModel.tsx +++ b/src/TemplateModel.tsx @@ -1,4 +1,4 @@ -import MarkdownEditor from './MarkdownEditor'; +import ConcertoEditor from './ConcertoEditor'; import useAppStore from './store'; function TemplateModel() { @@ -15,7 +15,7 @@ function TemplateModel() {

Concerto Model

Defines the data model for the template and its logic.
- + ; }