Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add MonacoEditor.jl #75

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

terasakisatoshi
Copy link

Hello, @fonsp . As we discussed in the aforementioned pull request on GitHub (AtelierArith/PlutoMonacoEditor.jl#1), I am making a new pull request for this repository. This new pull request adds the file src/web/MonacoEditor.jl, which demonstrates how to implement a rich text editor using Monaco Editor inside Pluto.

@terasakisatoshi
Copy link
Author

What we need is adding a frontmatter something like:

#> [frontmatter]
#> license_url = "https://github.com/JuliaPluto/featured/blob/2a6a9664e5428b37abe4957c1dca0994f4a8b7fd/LICENSES/Unlicense"
#> image = "<I'm not sure what image shoud be added>"
#> order = "<Inputme>"
#> tags = ["javascript", "web", "classic"]
#> license = "Unlicense"
#> description = "<Could you help me?>"
#> 
#>     [[frontmatter.author]]
#>     name = "Pluto.jl"
#>     url = "https://github.com/JuliaPluto"

@fonsp
Copy link
Member

fonsp commented Nov 20, 2024

Hey @terasakisatoshi, thanks for your notebook!

Your notebook is a bit unexpected, I thought you would use PlutoMonacoEditor.jl to use rust/python/js inside Pluto! This notebook explains how to PlutoMonacoEditor.jl was made, but don't you want to tell people to just use PlutoMonacoEditor.jl instead?

The current notebook about how PlutoMonacoEditor is very cool for me personally 🌟, but I'm worried that it might be too intimidating for a wider audience:

  • The goal is not so clear ("we will learn how PlutoMonacoEditor.jl was implemented"), and it might not be a goal that people can easily relate to. I think you can get many people interested in PlutoMonacoEditor.jl (a new concept), but directly explaining how it works might be a step too far.
  • The implementation is very tough, there are many new concepts that are assumed to be known (deno, JLL packages, typescript instead of JS, local JS files, PlutoUI.LocalResource, @htl, require, monaco). I think that featured notebooks can definitely have some "prerequisites" that people should know about, but there might be too much here.

I would really like more JS + Pluto notebooks, like https://featured.plutojl.org/web/threejs.html, but I think we need to be careful to not scare people away.


Perhaps we can pick a subset of topics from this notebook, and show them on their own?

For example: PlutoMonacoEditor.jl + @bind + JSON.parse. To show how you can use PlutoMonacoEditor.jl to have syntax highlighting for another language (other than Julia).

Or: PlutoMonacoEditor.jl + @bind + Meta.parse + dump to show PlutoMonacoEditor.jl and Julia's Expr structure.

Or a notebook like https://featured.plutojl.org/web/threejs.html . In that case, the focus should be on explaining step-by-step what JS techniques are used, and why. But I think other packages would be better fit, since monaco needs require and LocalResource, which both feel a bit hacky.


One other difficulty is that we use PlutoSliderServer.jl on a server to host these notebooks interactively online. We can't combine @bind with an execution engine like Base.eval or deno run, as this would allow code execution on our server... I know it's frustrating, but unfortunately it's a limitation of our system.

@fonsp
Copy link
Member

fonsp commented Nov 20, 2024

I played around a bit and I was able to get it to work without LocalReource and require:

# wrong order:
pE.dispatchEvent(new CustomEvent("update"));
pE.value = editorValue;

And I moved the monEditor.getValue() to make the initial value work (when you first open the notebook).

The new code is:

@bind tsmonacofield @htl """
<div>
    <style>
        #mymonacoeditor {
            width: 100%;
            height: 200px;
            border: 1px solid #ddd;
        }
    </style>

    <div id="mymonacoeditor"></div>

<script>
	const monaco = await import('https://cdn.jsdelivr.net/npm/[email protected]/+esm');
 	
	const monEditor = monaco.editor.create(document.getElementById('mymonacoeditor'), {
		value: [
			'function greet(name: string): string{',
			'\treturn \`Hello, \\\${name}!\`;',
			'}',
			'console.log(greet("Update me"));'
		].join('\\n'),
		language: 'typescript'
	});

	const pE = currentScript.parentElement;
	function update_bond() {
		pE.value = monEditor.getValue();
		pE.dispatchEvent(new CustomEvent("update"));
	}
	
	const myEditor = pE.querySelector("#mymonacoeditor");
	myEditor.addEventListener("input", e=>{
		update_bond();
	})
	
	update_bond();
</script>
</div>
"""

@terasakisatoshi
Copy link
Author

but don't you want to tell people to just use PlutoMonacoEditor.jl instead?

If possile, it would be nice to use PlutoMonacoEditor.jl. However, since PlutoMonacoEditor.jl is not currently unregistered, I worried about if I could use the PlutoMonacoEditor.jl package. Also I have no idea how to test/maintain PlutoMonacoEditor.jl. Need to investigate how widgets in PlutoUI.jl are tested.

@terasakisatoshi
Copy link
Author

The new code is:

Thank you. I'll try it.

@terasakisatoshi
Copy link
Author

I thought you would use PlutoMonacoEditor.jl to use rust/python/js inside Pluto!

I can show audiences how to use Python and JavaSript inside Pluto because we have PythonCall.jl and JavaScript originally. I ould not find a compiler for Rust e.g., something like rustc_jll. I also worried about that PythonCall.jl requires to install Conda(micromamba technically) which takes a little time to setup Pluto notebook. Is that O.K.?

If this is no problem for this repository I will rewrite and use Python as an example of how to use PlutoMonacoEditor.jl

@terasakisatoshi
Copy link
Author

I played around a bit, and I was able to get it to work without LocalReource and require:

# wrong order:
pE.dispatchEvent(new CustomEvent("update"));
pE.value = editorValue;

And I moved the monEditor.getValue() to make the initial value work (when you first open the notebook).

The new code is:

@bind tsmonacofield @htl """
<div>
    <style>
        #mymonacoeditor {
            width: 100%;
            height: 200px;
            border: 1px solid #ddd;
        }
    </style>

    <div id="mymonacoeditor"></div>

<script>
	const monaco = await import('https://cdn.jsdelivr.net/npm/[email protected]/+esm');
 	
	const monEditor = monaco.editor.create(document.getElementById('mymonacoeditor'), {
		value: [
			'function greet(name: string): string{',
			'\treturn \`Hello, \\\${name}!\`;',
			'}',
			'console.log(greet("Update me"));'
		].join('\\n'),
		language: 'typescript'
	});

	const pE = currentScript.parentElement;
	function update_bond() {
		pE.value = monEditor.getValue();
		pE.dispatchEvent(new CustomEvent("update"));
	}
	
	const myEditor = pE.querySelector("#mymonacoeditor");
	myEditor.addEventListener("input", e=>{
		update_bond();
	})
	
	update_bond();
</script>
</div>
"""

I've updated the code based on your suggested one.

https://htmlview.glitch.me/?https://gist.github.com/terasakisatoshi/eb19f8e8ca848c284bdc4e8ee2367ce9#file-esm-html

The Base64.jl package allows us to input source code in a more intuitive way.

@terasakisatoshi
Copy link
Author

@fonsp

Sorry for the late reply. Through some trial and error I have come to realize that PlutoMonacoEditor.jl is needed by many people and I am going to register it in the General registry. I will then create a new notebook using PlutoMonacoEditor.jl.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants