Merge branch 'dev' of gitlab.com:ligolang/ligo into rinderknecht@pprint

This commit is contained in:
Christian Rinderknecht 2020-06-10 16:59:39 +02:00
commit 358ae530b8
18 changed files with 16548 additions and 17 deletions

2
.gitignore vendored
View File

@ -3,6 +3,8 @@
*.merlin *.merlin
cache/* cache/*
Version.ml Version.ml
/result
/result-*
/_opam/ /_opam/
/*.pp.ligo /*.pp.ligo
/*.pp.mligo /*.pp.mligo

View File

@ -0,0 +1,170 @@
---
id: ligo-snippets-demo
title: Ligo-Snippets Demo
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
“ligo-snippets” (https://www.npmjs.com/package/@ligolang/ligo-snippets) is a React component that can be included on any webpage to display Ligo source code to users.
The user will see Ligo code with syntax highlighting, and an action button allowing the user to open the source code in the Ligo Web IDE (https://ide.ligolang.org).
Each code snippet can have preset Ligo Web IDE configurations (e.g. entrypoint, parameters or storage). These configurations are optional and will be passed onto the Ligo Web IDE when present. This will allow examples to provide the proper configurations for the reader to experiment with.
The “ligo-snippets” React component uses the CodeJar editor (https://github.com/antonmedv/codejar), which is extremely lightweight (only 2kB). It currently supports syntax highlighting for PascaLigo, CameLigo and ReasonLigo. Additionally, it has both a light and dark theme mode.
<Tabs
defaultValue="pascaligo"
values={[
{ label: 'PascaLIGO', value: 'pascaligo', },
{ label: 'CameLIGO', value: 'cameligo', },
{ label: 'ReasonLIGO', value: 'reasonligo', },
]
}>
<TabItem value="pascaligo">
```pascaligo {"name": "Ligo Introduction Example", "editor": true}
(*_*
name: PascaLIGO Contract
language: pascaligo
compile:
entrypoint: main
dryRun:
entrypoint: main
parameters: Increment (1)
storage: 999
deploy:
entrypoint: main
storage: 999
evaluateValue:
entrypoint: ""
evaluateFunction:
entrypoint: add
parameters: (5, 6)
generateDeployScript:
entrypoint: main
storage: 999
*_*)
// variant defining pseudo multi-entrypoint actions
type action is
| Increment of int
| Decrement of int
function add (const a : int ; const b : int) : int is
block { skip } with a + b
function subtract (const a : int ; const b : int) : int is
block { skip } with a - b
// real entrypoint that re-routes the flow based
// on the action provided
function main (const p : action ; const s : int) :
(list(operation) * int) is
block { skip } with ((nil : list(operation)),
case p of
| Increment(n) -> add(s, n)
| Decrement(n) -> subtract(s, n)
end)
```
</TabItem>
<TabItem value="cameligo">
```cameligo {"name": "Ligo Introduction Example", "editor": true}
(*_*
name: CameLIGO Contract
language: cameligo
compile:
entrypoint: main
dryRun:
entrypoint: main
parameters: Increment 1
storage: 999
deploy:
entrypoint: main
storage: 999
evaluateValue:
entrypoint: ""
evaluateFunction:
entrypoint: add
parameters: 5, 6
generateDeployScript:
entrypoint: main
storage: 999
*_*)
type storage = int
(* variant defining pseudo multi-entrypoint actions *)
type action =
| Increment of int
| Decrement of int
let add (a,b: int * int) : int = a + b
let sub (a,b: int * int) : int = a - b
(* real entrypoint that re-routes the flow based on the action provided *)
let main (p,s: action * storage) =
let storage =
match p with
| Increment n -> add (s, n)
| Decrement n -> sub (s, n)
in ([] : operation list), storage
```
</TabItem>
<TabItem value="reasonligo">
```reasonligo {"name": "Ligo Introduction Example", "editor": true}
(*_*
name: ReasonLIGO Contract
language: reasonligo
compile:
entrypoint: main
dryRun:
entrypoint: main
parameters: Increment (1)
storage: 999
deploy:
entrypoint: main
storage: 999
evaluateValue:
entrypoint: ""
evaluateFunction:
entrypoint: add
parameters: (5, 6)
generateDeployScript:
entrypoint: main
storage: 999
*_*)
type storage = int;
/* variant defining pseudo multi-entrypoint actions */
type action =
| Increment(int)
| Decrement(int);
let add = ((a,b): (int, int)): int => a + b;
let sub = ((a,b): (int, int)): int => a - b;
/* real entrypoint that re-routes the flow based on the action provided */
let main = ((p,storage): (action, storage)) => {
let storage =
switch (p) {
| Increment(n) => add((storage, n))
| Decrement(n) => sub((storage, n))
};
([]: list(operation), storage);
};
```
</TabItem>
</Tabs>

View File

@ -1535,6 +1535,20 @@
"@ligo/syntax": { "@ligo/syntax": {
"version": "file:src/@ligo/syntax" "version": "file:src/@ligo/syntax"
}, },
"@ligolang/ligo-snippets": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@ligolang/ligo-snippets/-/ligo-snippets-1.0.1.tgz",
"integrity": "sha512-JJa69veCkdwOS+u7iUngRNHFlXBJ+3Wx5l+EfrQyhBXMGzH4Ii4onZPxghDQEiL6RzqRbhCIsOE+A8OX7NCYMA==",
"requires": {
"@types/prismjs": "^1.16.1",
"axios": "^0.19.2",
"ligo-snippets-css": "0.0.1",
"prism-react-renderer": "^1.1.1",
"prismjs": "^1.20.0",
"react-codejar": "^1.0.1",
"yaml": "^1.9.2"
}
},
"@mdx-js/mdx": { "@mdx-js/mdx": {
"version": "1.6.5", "version": "1.6.5",
"resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-1.6.5.tgz", "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-1.6.5.tgz",
@ -1621,6 +1635,11 @@
"integrity": "sha512-ljr9hGQYW3kZY1NmQbmSe4yXvgq3KDRt0FMBOB5OaDWqi4X2WzEsp6SZ02KmVrieNW1cjWlj13pgvcf0towZPw==", "integrity": "sha512-ljr9hGQYW3kZY1NmQbmSe4yXvgq3KDRt0FMBOB5OaDWqi4X2WzEsp6SZ02KmVrieNW1cjWlj13pgvcf0towZPw==",
"dev": true "dev": true
}, },
"@medv/codejar": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/@medv/codejar/-/codejar-1.0.9.tgz",
"integrity": "sha512-TxcSsq+TFcCvbsTDbVT5h4y9g86yBpEk+Da6tyIyd2OTJKWK0o7U5Olva4XMG4i+ExW5A9MfZAGFClwYokacIQ=="
},
"@mrmlnc/readdir-enhanced": { "@mrmlnc/readdir-enhanced": {
"version": "2.2.1", "version": "2.2.1",
"resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz",
@ -1859,6 +1878,11 @@
"integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
"dev": true "dev": true
}, },
"@types/prismjs": {
"version": "1.16.1",
"resolved": "https://registry.npmjs.org/@types/prismjs/-/prismjs-1.16.1.tgz",
"integrity": "sha512-RNgcK3FEc1GpeOkamGDq42EYkb6yZW5OWQwTS56NJIB8WL0QGISQglA7En7NUx9RGP8AC52DOe+squqbAckXlA=="
},
"@types/q": { "@types/q": {
"version": "1.5.4", "version": "1.5.4",
"resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz",
@ -2516,6 +2540,37 @@
"integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==", "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==",
"dev": true "dev": true
}, },
"axios": {
"version": "0.19.2",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz",
"integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==",
"requires": {
"follow-redirects": "1.5.10"
},
"dependencies": {
"debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"requires": {
"ms": "2.0.0"
}
},
"follow-redirects": {
"version": "1.5.10",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
"integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
"requires": {
"debug": "=3.1.0"
}
},
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
}
}
},
"babel-code-frame": { "babel-code-frame": {
"version": "6.26.0", "version": "6.26.0",
"resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
@ -3418,7 +3473,6 @@
"version": "2.0.6", "version": "2.0.6",
"resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.6.tgz", "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.6.tgz",
"integrity": "sha512-g5zbiixBRk/wyKakSwCKd7vQXDjFnAMGHoEyBogG/bw9kTD9GvdAvaoRR1ALcEzt3pVKxZR0pViekPMIS0QyGg==", "integrity": "sha512-g5zbiixBRk/wyKakSwCKd7vQXDjFnAMGHoEyBogG/bw9kTD9GvdAvaoRR1ALcEzt3pVKxZR0pViekPMIS0QyGg==",
"dev": true,
"requires": { "requires": {
"good-listener": "^1.2.2", "good-listener": "^1.2.2",
"select": "^1.1.2", "select": "^1.1.2",
@ -4419,8 +4473,7 @@
"delegate": { "delegate": {
"version": "3.2.0", "version": "3.2.0",
"resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz", "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz",
"integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==", "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw=="
"dev": true
}, },
"depd": { "depd": {
"version": "1.1.2", "version": "1.1.2",
@ -5961,7 +6014,6 @@
"version": "1.2.2", "version": "1.2.2",
"resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz", "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz",
"integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=", "integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=",
"dev": true,
"requires": { "requires": {
"delegate": "^3.1.2" "delegate": "^3.1.2"
} }
@ -7367,6 +7419,11 @@
"leven": "^3.1.0" "leven": "^3.1.0"
} }
}, },
"ligo-snippets-css": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/ligo-snippets-css/-/ligo-snippets-css-0.0.1.tgz",
"integrity": "sha512-8qZ3TO198MX03HJw5YzTe5am63hacUtYzZEt2DlLtLP22Iri2UvLnckVXisZEVt0w18kM6aDhtMarAz127/z4g=="
},
"lines-and-columns": { "lines-and-columns": {
"version": "1.1.6", "version": "1.1.6",
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz",
@ -10042,14 +10099,12 @@
"prism-react-renderer": { "prism-react-renderer": {
"version": "1.1.1", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-1.1.1.tgz", "resolved": "https://registry.npmjs.org/prism-react-renderer/-/prism-react-renderer-1.1.1.tgz",
"integrity": "sha512-MgMhSdHuHymNRqD6KM3eGS0PNqgK9q4QF5P0yoQQvpB6jNjeSAi3jcSAz0Sua/t9fa4xDOMar9HJbLa08gl9ug==", "integrity": "sha512-MgMhSdHuHymNRqD6KM3eGS0PNqgK9q4QF5P0yoQQvpB6jNjeSAi3jcSAz0Sua/t9fa4xDOMar9HJbLa08gl9ug=="
"dev": true
}, },
"prismjs": { "prismjs": {
"version": "1.20.0", "version": "1.20.0",
"resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.20.0.tgz", "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.20.0.tgz",
"integrity": "sha512-AEDjSrVNkynnw6A+B1DsFkd6AVdTnp+/WoUixFRULlCLZVRZlVQMVWio/16jv7G1FscUxQxOQhWwApgbnxr6kQ==", "integrity": "sha512-AEDjSrVNkynnw6A+B1DsFkd6AVdTnp+/WoUixFRULlCLZVRZlVQMVWio/16jv7G1FscUxQxOQhWwApgbnxr6kQ==",
"dev": true,
"requires": { "requires": {
"clipboard": "^2.0.0" "clipboard": "^2.0.0"
} }
@ -10267,6 +10322,14 @@
"prop-types": "^15.6.2" "prop-types": "^15.6.2"
} }
}, },
"react-codejar": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/react-codejar/-/react-codejar-1.0.1.tgz",
"integrity": "sha512-t58v/YF4qV8w1yHi8Ylkte5tOU5ziYd5/4EIyyuJ6g/rS73ccaV113HhQBwvtoofSKTqOdKv3Rc4K5iMZ10IGg==",
"requires": {
"@medv/codejar": "^1.0.0"
}
},
"react-dev-utils": { "react-dev-utils": {
"version": "10.2.1", "version": "10.2.1",
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-10.2.1.tgz", "resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-10.2.1.tgz",
@ -11452,8 +11515,7 @@
"select": { "select": {
"version": "1.1.2", "version": "1.1.2",
"resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz",
"integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=", "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0="
"dev": true
}, },
"select-hose": { "select-hose": {
"version": "2.0.0", "version": "2.0.0",
@ -12678,8 +12740,7 @@
"tiny-emitter": { "tiny-emitter": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz", "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
"integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==", "integrity": "sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q=="
"dev": true
}, },
"tiny-invariant": { "tiny-invariant": {
"version": "1.1.0", "version": "1.1.0",
@ -14516,8 +14577,7 @@
"yaml": { "yaml": {
"version": "1.10.0", "version": "1.10.0",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz", "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.0.tgz",
"integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg==", "integrity": "sha512-yr2icI4glYaNG+KWONODapy2/jDdMSDnrONSjblABjD9B4Z5LgiircSt8m8sRZFNi08kG9Sm0uSHtEmP3zaEGg=="
"dev": true
}, },
"yargs": { "yargs": {
"version": "13.3.2", "version": "13.3.2",

View File

@ -29,6 +29,10 @@
}, },
"dependencies": { "dependencies": {
"@docusaurus/plugin-sitemap": "^2.0.0-alpha.56", "@docusaurus/plugin-sitemap": "^2.0.0-alpha.56",
"@ligo/syntax": "file:src/@ligo/syntax" "@ligo/syntax": "file:src/@ligo/syntax",
"@ligolang/ligo-snippets": "^1.0.1",
"axios": "^0.19.2",
"react-codejar": "^1.0.1",
"yaml": "^1.10.0"
} }
} }

View File

@ -81,11 +81,13 @@ Prism.languages = {
] ]
} }
}; };
import defaultTheme from 'prism-react-renderer/themes/palenight'; import defaultTheme from 'prism-react-renderer/themes/palenight';
import Clipboard from 'clipboard'; import Clipboard from 'clipboard';
import rangeParser from 'parse-numeric-range'; import rangeParser from 'parse-numeric-range';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import useThemeContext from '@theme/hooks/useThemeContext'; import useThemeContext from '@theme/hooks/useThemeContext';
import { LigoSnippet } from '@ligolang/ligo-snippets'
import styles from './styles.module.css'; import styles from './styles.module.css';
@ -159,7 +161,8 @@ const highlightDirectiveRegex = (lang) => {
}; };
const codeBlockTitleRegex = /title=".*"/; const codeBlockTitleRegex = /title=".*"/;
export default ({children, className: languageClassName, metastring}) => { export default ({ children, className: languageClassName, metastring }) => {
const { const {
siteConfig: { siteConfig: {
themeConfig: {prism = {}}, themeConfig: {prism = {}},
@ -277,6 +280,34 @@ export default ({children, className: languageClassName, metastring}) => {
setTimeout(() => setShowCopied(false), 2000); setTimeout(() => setShowCopied(false), 2000);
}; };
// ligo-snippets - begin
if (metastring) {
const theme = isDarkTheme ? 'dark' : 'light';
let isObject = true
let metadata
try {
metadata = JSON.parse(metastring)
} catch (e) {
isObject = false
}
if (isObject) {
const snippetData = {
"language": language,
"name": metadata.name,
"code": children,
"theme": theme,
"height": "" // Optional
}
if (metadata.editor) {
return <LigoSnippet data={snippetData} />
}
}
}
// ligo-snippets - end
return ( return (
<Highlight <Highlight
{...defaultProps} {...defaultProps}

View File

@ -9,11 +9,12 @@ let
inherit (import sources."gitignore.nix" { inherit (self) lib; }) inherit (import sources."gitignore.nix" { inherit (self) lib; })
gitignoreSource; gitignoreSource;
# Remove list of directories or files from source (to stop unneeded rebuilds) # Remove list of directories or files from source (to stop unneeded rebuilds)
# Also, apply the gitignore here.
filterOut = xs: filterOut = xs:
self.lib.cleanSourceWith { gitignoreSource (self.lib.cleanSourceWith {
filter = p: type: !(builtins.elem (builtins.baseNameOf p) xs); filter = p: type: !(builtins.elem (builtins.baseNameOf p) xs);
src = gitignoreSource ../.; src = gitignoreSource ../.;
}; });
in { in {
ocamlPackages = self.ocaml-ng.ocamlPackages_4_07.overrideScope' ocamlPackages = self.ocaml-ng.ocamlPackages_4_07.overrideScope'
(builtins.foldl' self.lib.composeExtensions (_: _: { }) [ (builtins.foldl' self.lib.composeExtensions (_: _: { }) [

View File

@ -0,0 +1,8 @@
{
"presets": [
"@babel/preset-react",
"@babel/preset-env",
"@babel/preset-typescript"
],
"plugins": ["@babel/plugin-transform-react-jsx", "@babel/plugin-transform-runtime"]
}

6
tools/ligo-snippets/.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
*.log
node_modules/
lib/
.cache/
dist/

View File

@ -0,0 +1,9 @@
src
demo
*.lock
.babelrc
.gitignore
webpack.config.js
tsconfig.json
webpack.config.js

View File

@ -0,0 +1,131 @@
A React component for embedding Ligo code snippets on a page.
# Quick start
1. Install package `yarn add @ligolang/ligo-snippets`
2. Add `LigoSnippet` component to a page
```jsx
import { LigoSnippet } from "@ligolang/ligo-snippets";
const App = () => {
const code = `type storage is int
type parameter is
Increment of int
| Decrement of int
| Reset
type return is list (operation) * storage
// Two entrypoints
function add (const store : storage; const delta : int) : storage is
store + delta
function sub (const store : storage; const delta : int) : storage is
store - delta
(* Main access point that dispatches to the entrypoints according to
the smart contract parameter. *)
function main (const action : parameter; const store : storage) : return is
((nil : list (operation)), // No operations
case action of
Increment (n) -> add (store, n)
| Decrement (n) -> sub (store, n)
| Reset -> 0
end)`
const snippetData = {
"language": "pascaligo", // Required - Takes a string value of a Ligo language (e.g. "pascaligo", "reasonligo" or "cameligo").
"code": code, // Required - Takes a string value of your code snippet.
"name": "PascaLigo Code Snippet Example", // Optional - Takes a string value to display as your snippet's title on the Ligo Web IDE.
"theme": "dark", // Optional - Takes a string value of either "dark" or "light".
"height": "" // Optional - Takes a string value of a CSS height (e.g. "100px").
}
return <LigoSnippet data={snippetData} />
}
render(<App />, document.getElementById("root"));
```
The `snippetData` values of `language` and `code` are required. These values determine the code displayed and the syntax highlighting. The `name` value is optional and will be used as the title of your code when sent to the Ligo Web IDE.
# Ligo Web IDE
Ligo Snippets can be opened in the Ligo Web IDE [(https://ide.ligolang.org/)](https://ide.ligolang.org/) by clicking the IDE button at the bottom of the snippet. The Ligo Web IDE can take in preset configurations for the available features.
## Available Configurations
```json
"name": string,
"language": string,
"compile": {
"entrypoint": string
},
"dryRun": {
"entrypoint": string,
"parameters": string,
"storage": string,
},
"deploy": {
"entrypoint": string,
"storage": string,
},
"evaluateValue": {
"entrypoint": string
},
"evaluateFunction": {
"entrypoint": string,
"parameters": string
},
"generateDeployScript": {
"entrypoint": string,
"storage": string
}
```
## Setting Configurations
When using the configurations to set preset default values for the Ligo Web IDE, please note that the `name` and `language` values are required. When present, these values will replace the `name` and `language` values from your `snippetData`. Everything else is optional.
Add the configuration in a yaml format at the top of your the code you are trying to display.
```js
(*_*
name: PascaLIGO Contract
language: pascaligo
compile:
entrypoint: main
dryRun:
entrypoint: main
parameters: Increment (1)
storage: 0
deploy:
entrypoint: main
storage: 0
evaluateValue:
entrypoint: ""
evaluateFunction:
entrypoint: add
parameters: (5, 6)
generateDeployScript:
entrypoint: main
storage: 0
*_*)
type action is
| Increment of int
| Decrement of int
function add (const a : int ; const b : int) : int is
block { skip } with a + b
function subtract (const a : int ; const b : int) : int is
block { skip } with a - b
function main (const p : action ; const s : int) :
(list(operation) * int) is
block { skip } with ((nil : list(operation)),
case p of
| Increment(n) -> add(s, n)
| Decrement(n) -> subtract(s, n)
end)
```

9118
tools/ligo-snippets/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,49 @@
{
"name": "@ligolang/ligo-snippets",
"version": "1.0.1",
"main": "./lib/index.js",
"scripts": {
"build": "webpack"
},
"files": [
"lib"
],
"license": "ISC",
"peerDependencies": {
"react": "^16.13.1",
"react-dom": "^16.13.1"
},
"devDependencies": {
"@babel/cli": "^7.8.4",
"@babel/core": "^7.8.7",
"@babel/plugin-transform-react-jsx": "^7.8.3",
"@babel/plugin-transform-runtime": "^7.10.1",
"@babel/preset-env": "^7.8.7",
"@babel/preset-react": "^7.8.3",
"@babel/preset-typescript": "^7.8.3",
"@types/node": "^13.9.5",
"@types/react": "^16.9.23",
"@types/react-dom": "^16.9.5",
"@types/styled-components": "^5.0.1",
"babel-loader": "8.0.6",
"css-loader": "^3.4.2",
"parcel-bundler": "^1.12.4",
"path": "^0.12.7",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"style-loader": "^1.1.3",
"typescript": "^3.8.3",
"webpack": "4.41.5",
"webpack-cli": "^3.3.11",
"webpack-node-externals": "^1.7.2"
},
"dependencies": {
"@types/prismjs": "^1.16.1",
"axios": "^0.19.2",
"ligo-snippets-css": "0.0.1",
"prism-react-renderer": "^1.1.1",
"prismjs": "^1.20.0",
"react-codejar": "^1.0.1",
"yaml": "^1.9.2"
}
}

View File

@ -0,0 +1,225 @@
import React from 'react';
import PrismJS from 'prismjs';
import { ReactCodeJar } from "react-codejar";
import axios from 'axios';
import YAML from 'yaml';
require('ligo-snippets-css/css/ligo-prism.css')
const { Prism } = require("prism-react-renderer");
Prism.languages = {
...Prism.languages,
pascaligo: {
'comment': [
/\(\*[\s\S]+?\*\)/,
// /\{[\s\S]+?\}/,
/\/\/.*/
],
'string': {
pattern: /(?:'(?:''|[^'\r\n])*'|#[&$%]?[a-f\d]+)+|\^[a-z]/i,
greedy: true
},
'keyword': [
{
// Turbo Pascal
pattern: /(^|[^&])\b(?:absolute|array|asm|begin|case|const|constructor|destructor|do|downto|else|end|file|for|function|goto|if|implementation|inherited|inline|interface|label|nil|object|of|operator|packed|procedure|program|record|reintroduce|repeat|self|set|string|then|to|type|unit|until|uses|var|while|with)\b/i,
lookbehind: true
},
{
// Free Pascal
pattern: /(^|[^&])\b(?:dispose|exit|false|new|true)\b/i,
lookbehind: true
},
{
// Object Pascal
pattern: /(^|[^&])\b(?:class|dispinterface|except|exports|finalization|finally|initialization|inline|library|on|out|packed|property|raise|resourcestring|threadvar|try)\b/i,
lookbehind: true
},
{
// Modifiers
pattern: /(^|[^&])\b(?:absolute|abstract|alias|assembler|bitpacked|break|cdecl|continue|cppdecl|cvar|default|deprecated|dynamic|enumerator|experimental|export|external|far|far16|forward|generic|helper|implements|index|interrupt|iochecks|local|message|name|near|nodefault|noreturn|nostackframe|oldfpccall|otherwise|overload|override|pascal|platform|private|protected|public|published|read|register|reintroduce|result|safecall|saveregisters|softfloat|specialize|static|stdcall|stored|strict|unaligned|unimplemented|varargs|virtual|write)\b/i,
lookbehind: true
}
],
'number': [
// Hexadecimal, octal and binary
/(?:[&%]\d+|\$[a-f\d]+)/i,
// Decimal
/\b\d+(?:\.\d+)?(?:e[+-]?\d+)?/i
],
'operator': [
/\.\.|\*\*|:=|<[<=>]?|>[>=]?|[+\-*\/]=?|[@^=]/i,
{
pattern: /(^|[^&])\b(?:and|as|div|exclude|in|include|is|mod|not|or|shl|shr|xor)\b/,
lookbehind: true
}
],
'punctuation': /\(\.|\.\)|[()\[\]:;,.]/
},
reasonligo:
{
...Prism.languages.reason,
'comment': [
/(^|[^\\])\/\*[\s\S]*?\*\//,
/\(\*[\s\S]*?\*\)/,
/\/\/.*/
]
},
cameligo: {
...Prism.languages.ocaml,
'comment': [
/(^|[^\\])\/\*[\s\S]*?\*\//,
/\(\*[\s\S]*?\*\)/,
/\/\/.*/
]
}
};
async function openInIde(editorParams, snippetCode) {
editorParams.editor.code = snippetCode
let webIdeUrl = 'https://ide.ligolang.org'
const response = await axios.post(`${webIdeUrl}/api/share`, editorParams);
const { hash } = await response.data;
window.open(`${webIdeUrl}/p/${hash}`, "_blank");
}
function parseEditorConfigs(data) {
const CONFIG_REGEX = /\(\*_\*([^]*?)\*_\*\)\s*/;
const match = data.code.match(CONFIG_REGEX);
if (!match || !match[1]) {
return {
"editor": {
"title": data.name,
"language": data.language,
"code": data.code,
"dirty": false
}
};
}
try {
const config = YAML.parse(match[1]);
data.code = data.code.replace(CONFIG_REGEX, '')
return {
"editor": {
"title": config.name,
"language": config.language,
"code": data.code,
"dirty": false
},
"compile": {
"entrypoint": config.compile.entrypoint
},
"dryRun": {
"entrypoint": config.dryRun.entrypoint,
"parameters": config.dryRun.parameters,
"storage": config.dryRun.storage
},
"deploy": {
"entrypoint": config.deploy.entrypoint,
"storage": config.deploy.storage
},
"evaluateValue": {
"entrypoint": config.evaluateValue.entrypoint
},
"evaluateFunction": {
"entrypoint": config.evaluateFunction.entrypoint,
"parameters": config.evaluateFunction.parameters
}
}
} catch (ex) {
throw new Error(`Unable to parse configuration.`);
}
}
function getTheme(data) {
let theme = {
editorStyle: {
borderRadius: "25px 25px 25px 0",
boxShadow: "0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2)",
fontFamily: "'Source Code Pro', monospace",
fontSize: "14px",
fontWeight: "400",
color:"black",
height: "350px",
letterSpacing: "normal",
lineHeight: "20px",
padding: "20px",
tabSize: "4",
overflow: "hidden",
background: "#3A444C"
},
buttonStyle: {
margin: "10px",
fontWeight: "bold",
color: "white",
border: "none",
background: "#0F60CF"
},
buttonContainer: {
textAlign: "right",
background: "#0F60CF",
borderRadius: "0 0 0 25px"
}
}
if (data.height != "") {
theme.editorStyle.height = data.height
}
if (data.theme === 'light') {
theme.editorStyle.background = "#f7fcff"
theme.editorStyle.color = "black"
theme.buttonStyle.background = "#3F90FF"
theme.buttonContainer.background = "#3F90FF"
} else {
theme.editorStyle.background = "#3A444C"
theme.editorStyle.color = "white"
theme.buttonStyle.background = "#0F60CF"
theme.buttonContainer.background = "#0F60CF"
}
return theme
}
function getLanguageHighlight(language) {
switch (language) {
case 'cameligo':
return Prism.languages.cameligo
case 'reasonligo':
return Prism.languages.reasonligo
default:
return Prism.languages.pascaligo
}
}
export const LigoSnippet = (props) => {
const data = props.data
const editorParams = parseEditorConfigs(data)
let theme = getTheme(data)
const [snippetCode, onUpdate] = React.useState(editorParams.editor.code);
const highlight = editor => {
const text = editor.textContent;
editor.innerHTML = PrismJS.highlight(
text,
getLanguageHighlight(data.language),
data.language
);
};
return (
<div>
<ReactCodeJar style={theme.editorStyle} code={snippetCode} onUpdate={onUpdate} highlight={highlight} />
<div style={theme.buttonContainer}>
<button style={theme.buttonStyle} onClick={() => openInIde(editorParams, snippetCode)} title="Open in Ligo Web IDE">I D E </button>
</div>
</div>
);
}

View File

@ -0,0 +1,76 @@
/**
* prism.js default theme for JavaScript, CSS and HTML
* Based on dabblet (http://dabblet.com)
* @author Lea Verou
*/
.token.comment,
.token.prolog,
.token.doctype,
.token.cdata {
color: slategray;
}
.token.punctuation {
color: #999;
}
.token.namespace {
opacity: .7;
}
.token.property,
.token.tag,
.token.boolean,
.token.number,
.token.constant,
.token.symbol,
.token.deleted {
color: #B5CEA8;
}
.token.selector,
.token.attr-name,
.token.string,
.token.char,
.token.builtin,
.token.inserted {
color: #690;
}
.token.operator,
.token.entity,
.token.url,
.language-css .token.string,
.style .token.string {
color: #9a6e3a;
}
.token.atrule,
.token.attr-value,
.token.keyword {
color: #07a;
}
.token.function,
.token.class-name {
color: #DD4A68;
}
.token.regex,
.token.important,
.token.variable {
color: #e90;
}
.token.important,
.token.bold {
font-weight: bold;
}
.token.italic {
font-style: italic;
}
.token.entity {
cursor: help;
}

View File

@ -0,0 +1 @@
export { LigoSnippet } from './components/editor'

View File

@ -0,0 +1,19 @@
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react"
},
"include": ["src"]
}

View File

@ -0,0 +1,28 @@
const path = require('path');
const nodeExternals = require("webpack-node-externals");
module.exports = {
mode: 'production',
entry: './src/index.tsx',
output: {
path: path.resolve('lib'),
filename: 'index.js',
libraryTarget: 'commonjs2'
},
module: {
rules: [{
test: /\.(t|j)sx?$/,
exclude: /(node_modules)/,
use: 'babel-loader'
},
{
test: /\.css/,
use: ["style-loader", "css-loader"],
},
]
},
externals: [nodeExternals()],
resolve: {
extensions: ['.ts', '.tsx', '.js', '.jsx']
},
}

File diff suppressed because it is too large Load Diff