-
-
Notifications
You must be signed in to change notification settings - Fork 532
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
00e3227
commit 5770539
Showing
7 changed files
with
445 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"import panel as pn\n", | ||
"pn.extension('ace')" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"The ``Ace`` pane allows to embed a code editor based on [Ace](https://ace.c9.io/).\n", | ||
"Only a small subset of functionnalities are enabled :\n", | ||
" - **syntax highligting** for several languages\n", | ||
" - **themes**\n", | ||
" - basic **completion** fonctionnalities `ctrl+space` (only static analysis of the code)\n", | ||
" - **annotations**\n", | ||
" - **readonly**\n", | ||
"\n", | ||
"#### Parameters:\n", | ||
"\n", | ||
"For layout and styling related parameters see the [customization user guide](../../user_guide/Customization.ipynb).\n", | ||
"\n", | ||
"* **``code``** (str): A string with code to set in the editor\n", | ||
"* **``language``** (str): A string wich define the code syntax highlighter (default: 'python')\n", | ||
"* **``theme``** (str): theme of the editor (defaut: 'chrome')\n", | ||
"* **``annotations``** (list): list of annotations. An annotation is a dict with the following keys:\n", | ||
" - `'row'`: row in the editor of the annotation\n", | ||
" - `'column'`: column of the annotation\n", | ||
" - `'text'`: 'text displayed when hover the annotation'\n", | ||
" - `'type'`: define the type of annotation and the icon displayed {`warning` | `error`}\n", | ||
"* **``readonly``** (boolean): A boolean to set the editor in read only mode\n", | ||
"___" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"To construct an `Ace` panel we must define it explicitly using `pn.pane.Ace`, we can add some text as initial code.\n", | ||
"Code inserted in the editor is automatically reflected in the `code` parameter and can be linked to an other `panel`" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"py_code = \"\"\"import sys\n", | ||
"\"\"\"\n", | ||
"editor = pn.pane.Ace(py_code, sizing_mode='stretch_both', height=300)\n", | ||
"html_pane = pn.pane.HTML(sizing_mode='stretch_both', height=300)\n", | ||
"editor.link(html_pane,code=\"object\")\n", | ||
"pn.Row(editor, html_pane)" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"we can add some code in it" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"editor.code += \"\"\"import Math\n", | ||
"\n", | ||
"x = Math.cos(x)**2 + Math.cos(y)**2\n", | ||
"\"\"\"" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"We can change language and theme of the editor" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"html_code = r\"\"\"<!DOCTYPE html>\n", | ||
"<html>\n", | ||
" <head>\n", | ||
" <meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\" />\n", | ||
" <title>`substitute(Filename('', 'Page Title'), '^.', '\\u&', '')`</title>\n", | ||
" </head>\n", | ||
" <body>\n", | ||
" <h1>Title1</h1>\n", | ||
" <h2>Title2</h2>\n", | ||
" <p>Paragraph</p>\n", | ||
" </body>\n", | ||
"</html>\n", | ||
"\"\"\"\n", | ||
"editor.language = \"html\"\n", | ||
"editor.theme = \"monokai\"\n", | ||
"editor.code = html_code\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"We can add some annotations to the editor" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"editor.annotations= [dict(row=1, column=0, text='an error', type='error'),\n", | ||
" dict(row=2, column=0, text='a warning', type='warning')]" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"If we want just to display editor content but not edit it we can set the `readonly` property to `True`" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"editor.readonly = True" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": null, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [] | ||
} | ||
], | ||
"metadata": { | ||
"kernelspec": { | ||
"display_name": "Python 3", | ||
"language": "python", | ||
"name": "python3" | ||
}, | ||
"language_info": { | ||
"codemirror_mode": { | ||
"name": "ipython", | ||
"version": 3 | ||
}, | ||
"file_extension": ".py", | ||
"mimetype": "text/x-python", | ||
"name": "python", | ||
"nbconvert_exporter": "python", | ||
"pygments_lexer": "ipython3", | ||
"version": "3.7.2" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 2 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
""" | ||
Defines custom AcePlot bokeh model to render Ace editor. | ||
""" | ||
import os | ||
|
||
from bokeh.core.properties import String, Override, Dict, Any, List, Bool | ||
from bokeh.models import HTMLBox | ||
|
||
from ..compiler import CUSTOM_MODELS | ||
|
||
class AcePlot(HTMLBox): | ||
""" | ||
A Bokeh model that wraps around a Ace editor and renders it inside | ||
a Bokeh plot. | ||
""" | ||
|
||
__javascript__ = ['https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.3/ace.js', | ||
'https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.3/ext-language_tools.js'] | ||
|
||
__js_require__ = {'paths': {'ace': 'https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.3/ace'}, | ||
'shim': {'ace': 'ace'}} | ||
|
||
__implementation__ = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'ace.ts') | ||
|
||
code = String() | ||
|
||
theme = String(default='chrome') | ||
|
||
language = String(default='python') | ||
|
||
annotations = List(Dict(String, Any), default=[]) | ||
|
||
readonly = Bool(default=False) | ||
|
||
height = Override(default=300) | ||
|
||
width = Override(default=300) | ||
|
||
|
||
|
||
CUSTOM_MODELS['panel.models.ace.AcePlot'] = AcePlot |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
import * as p from "core/properties" | ||
import {HTMLBox, HTMLBoxView} from "models/layouts/html_box" | ||
import { div } from 'core/dom'; | ||
|
||
function ID() { | ||
// Math.random should be unique because of its seeding algorithm. | ||
// Convert it to base 36 (numbers + letters), and grab the first 9 characters | ||
// after the decimal. | ||
return '_' + Math.random().toString(36).substr(2, 9); | ||
} | ||
|
||
|
||
export class AcePlotView extends HTMLBoxView { | ||
model: AcePlot | ||
protected _ace: any | ||
protected _editor: any | ||
protected _langTools: any | ||
protected _container: HTMLDivElement | ||
|
||
initialize(): void { | ||
super.initialize() | ||
this._ace = (window as any).ace | ||
this._container = div({ | ||
id: ID(), | ||
style: { | ||
width: "100%", | ||
height: "100%" | ||
} | ||
}) | ||
} | ||
|
||
connect_signals(): void { | ||
super.connect_signals() | ||
this.connect(this.model.properties.code.change, () => this._update_code_from_model()) | ||
this.connect(this.model.properties.theme.change, () => this._update_theme()) | ||
this.connect(this.model.properties.language.change, () => this._update_language()) | ||
this.connect(this.model.properties.annotations.change, () => this._add_annotations()) | ||
this.connect(this.model.properties.readonly.change, () => { | ||
this._editor.setReadOnly(this.model.readonly) | ||
}) | ||
} | ||
|
||
render(): void { | ||
super.render() | ||
if (!(this._container === this.el.childNodes[0])) | ||
this.el.appendChild(this._container) | ||
this._container.textContent = this.model.code | ||
this._editor = this._ace.edit(this._container.id) | ||
this._editor.setTheme("ace/theme/" + `${this.model.theme}`) | ||
this._editor.session.setMode("ace/mode/" + `${this.model.language}`) | ||
this._editor.setReadOnly(this.model.readonly) | ||
this._langTools = this._ace.require('ace/ext/language_tools') | ||
this._editor.setOptions({ | ||
enableBasicAutocompletion: true, | ||
enableSnippets: true, | ||
fontFamily: "monospace", //hack for cursor position | ||
}); | ||
this._editor.on('change', () => this._update_code_from_editor()) | ||
} | ||
|
||
_update_code_from_model(): void { | ||
if (this._editor && this._editor.getValue() != this.model.code) | ||
this._editor.setValue(this.model.code) | ||
} | ||
|
||
_update_code_from_editor(): void { | ||
if(this._editor.getValue() != this.model.code){ | ||
this.model.code = this._editor.getValue() | ||
} | ||
} | ||
|
||
_update_theme(): void{ | ||
this._editor.setTheme("ace/theme/" + `${this.model.theme}`) | ||
} | ||
|
||
_update_language(): void{ | ||
this._editor.session.setMode("ace/mode/" + `${this.model.language}`) | ||
} | ||
|
||
_add_annotations(): void{ | ||
this._editor.session.setAnnotations(this.model.annotations) | ||
} | ||
|
||
after_layout(): void{ | ||
super.after_layout() | ||
this._editor.resize() | ||
} | ||
|
||
} | ||
|
||
export namespace AcePlot { | ||
export type Attrs = p.AttrsOf<Props> | ||
export type Props = HTMLBox.Props & { | ||
code: p.Property<string> | ||
language: p.Property<string> | ||
theme: p.Property<string> | ||
annotations: p.Property<any[]> | ||
readonly: p.Property<boolean> | ||
} | ||
} | ||
|
||
export interface AcePlot extends AcePlot.Attrs {} | ||
|
||
export class AcePlot extends HTMLBox { | ||
properties: AcePlot.Props | ||
|
||
constructor(attrs?: Partial<AcePlot.Attrs>) { | ||
super(attrs) | ||
} | ||
|
||
static initClass(): void { | ||
this.prototype.type = "AcePlot" | ||
this.prototype.default_view = AcePlotView | ||
|
||
this.define<AcePlot.Props>({ | ||
code: [ p.String ], | ||
language: [ p.String, 'python' ], | ||
theme: [ p.String, 'chrome' ], | ||
annotations: [ p.Array, [] ], | ||
readonly: [ p.Boolean, false ] | ||
}) | ||
|
||
this.override({ | ||
height: 300, | ||
width: 300 | ||
}) | ||
} | ||
} | ||
AcePlot.initClass() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.