Re: tinymce

25 views
Skip to first unread message

William Stein

unread,
Jun 18, 2009, 11:01:05 AM6/18/09
to jason...@creativetrax.com, sage-devel
On Wed, Jun 17, 2009 at 4:49 PM, <jason...@creativetrax.com> wrote:
> William Stein wrote:
>>
>> Jason,
>>
>> Unfortunately, I find it highly highly frustrating in tinyMCE that I
>> can't enter a newline (i.e., what shift enter did before you rebound
>> it) without directly editing the html.  In my personal copy of Sage,
>> I've disabled the shift-enter submits tinymce cells.  I would be ok
>> with a button to enter a newline, but I couldn't figure out how to add
>> such a button to tinyMCE.  Any ideas?
>>
>
> I think basically you have to write a new plugin or something.  There's an
> example plugin skeleton, though, so presumably it wouldn't be too extremely
> hard (see http://wiki.moxiecode.com/index.php/TinyMCE:Create_plugin/3.x)  A
> very similar plugin is here:
> http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/pagebreak.
> In fact, you could probably just use the pagebreak plugin with a special
> "pagebreak" option.  Just add the following to the tinymce.init:
>
>        plugins : "pagebreak",
>        pagebreak_separator : "<br/>"
>
>
> Does that work?  It's a little hackish, but it's probably the fastest way to
> do something like what you suggest.  A better way would be to modify the
> pagebreak plugin to be a "linebreak" plugin.

I may try that.

>
> Of course, other options are:
>
> * you can revert your feature request to have shift-enter submit the cell :)
> (apparently you've personally done that...)

Yep, and it sucks and drives me crazy not having shift-enter submit...
Why can't TinyMCE just read my mind?

> * is there another shortcut key that you'd like?

What about control-enter? Can you make it so

control-enter = linebreak
shift-enter = submit
?

>
> Also, I've been thinking about how to add Rado's graph editor, an equation
> editor, and other nice input methods to the code cells.  Basically, I'm
> looking at how to replace a small section of Sage code with a "widget" that
> represents the code nicely, all inside of the code cell. Requirements that
> make sense to me include:
>
> 1. When the cell is recreated (on page creation, for example), the user
> should see the widget, not the generated Sage code
> 2. The user should be able to highlight some Sage code and convert it to the
> widget (replacing the highlighted part with the graphical div).  If the sage
> code is not understood by the widget, then some sort of error should be
> signaled (maybe an alert box?) and the code should remain in the cell.
> 3. The user should be able to toggle between seeing the Sage code text and
> the widget representation, on a widget-by-widget basis.
>
> Point (1) requires that the cell understand that some sort of widget
> represents the code between character positions x and y.  What's the easiest
> way to store/send that sort of metadata along with the cell?
>
> We probably don't want to use tinymce---it's way too heavyweight for this
> and has *lots* of unneeded functionality.
>
> This will probably necessitate subtle changes in the existing javascript for
> code cells, as we can't use textareas anymore, but instead will use some
> sort of contentEditable divs for code cells.  This also exposes us to lots
> of cross-browser support issues, I believe.  It seems that a major issue for
> the html wysiwyg editors is how well they support different browsers.
>
> What do you think?

Ouch. Oh the pain. I would have to see a demo. I have never tried
any sort of contentEditable div before. I'm amazed how far we've gone
using textareas, to be honest.

-- William

Pat LeSmithe

unread,
Jun 20, 2009, 6:47:33 PM6/20/09
to sage-...@googlegroups.com
William Stein wrote:
> What about control-enter? Can you make it so
> control-enter = linebreak
> shift-enter = submit
> ?

Control-enter is bound to spliteval_cell. To make control-shift-enter,
say, insert a line break, try augmenting notebook.py's tinyMCE.init()'s
setup with some code ripped from the Safari plug-in:

// Around line 1840 of sage/server/notebook/notebook.py
setup : function(ed) {
ed.onKeyDown.add(function(ed, e) {
// Make ctrl-shift-enter insert a line break. Copied from
the Safari plug-in.
if (e.keyCode == 13 && e.shiftKey && e.ctrlKey) {
// Workaround for missing shift+enter support,
http://bugs.webkit.org/show_bug.cgi?id=16973
var dom = ed.dom, s = ed.selection, r = s.getRng(), br;

// Insert BR element
r.insertNode(br = dom.create('br'));

// Place caret after BR
r.setStartAfter(br);
r.setEndAfter(br);
s.setRng(r);

// Could not place caret after BR then insert an nbsp
entity and move the caret
if (s.getSel().focusNode == br.previousSibling) {

s.select(dom.insertAfter(dom.doc.createTextNode('\u00a0'), br));
s.collapse(1);
}

// Scroll to new position, scrollIntoView can't be
used due to bug: http://bugs.webkit.org/show_bug.cgi?id=16117
ed.getWin().scrollTo(0,
dom.getPos(s.getRng().startContainer).y);

tinymce.dom.Event.cancel(e);
}
});
// Make shift-enter quit editing. This is the "old" code.
ed.onKeyDown.add(function(ed, e) {
if (key_enter_shift(key_event(e))) {
$(ed.formElement).submit();
}
})
}

This seems to work on Linux in Firefox, Opera, and the Qt 4.5 WebKit
demo browser (e.g., /usr/lib64/qt4/demos/browser/browser).

Jason Grout

unread,
Jul 2, 2009, 1:59:01 AM7/2/09
to sage-...@googlegroups.com
William Stein wrote:


Actually, that's how TinyMCE is implemented, so you've been using lots
of these contentEditable divs lately (well, probably actually an
ancestor to contentEditable divs). Since textareas can't contain
anything but text currently, we can't implement any sort of wysiwyg
mathematics with just a textarea.

What I'm talking about is a lightweight tinymce-like control that would
be able to sections of represent Sage code with a graphical widget, like
replacing Graph({0:[2,3], 1:[3],2:[3,4]}) with Rado's graph editor, or a
symbolic expression with Davide's equation editor. So in a cell, you
would see something like:

-----------------------------------------------------------------------
| ____________________________________________________ |
| | XX| |
| | Rado's graph editor | |
| G= | | |
| | | |
| ---------------------------------------------------- |
| |
----------------------------------------------------------------------

Clicking on the small XX in the upper right corner would replace the
graph editor with the corresponding code.

On the other hand, you could highlight "Graph({0:[2,3], 1:[3],2:[3,4]})"
in a cell and click a "Graph Editor" button that would then replace the
text with Rado's editor, as sketched above.

Does anyone here have experience with contentEditable divs? I don't,
but I'm learning slowly as I have time. Does anyone have good
experience with a very lightweight online edit control that lets us
easily replace random text with a div (containing the representing
widget)? I've looked at lots of different possibilities, but I don't
have experience with any other than TinyMCE. I haven't found anything
that strikes me as easy to modify for what we need and as lightweight as
we need.

Jason

Rado

unread,
Jul 2, 2009, 3:47:42 AM7/2/09
to sage-devel
I would like to help in the embedding of my graph editor. Mainly to
save someone the effort of reading my code (as someone else put other
people's code is like other people's underwear).

What is the status of the sage - frontend decoupling? I played with
codenode and it seems to be getting there. I am learning django (for
fun) and it would definitely will make sense to use something powerful
like django. It should make it easier to plug-in and out modules/apps
like graph editor (or syntax highlighting which would be awesome).

If the decoupling is expected soon and that is the general direction
of the Sage project it would make sense to wait it for it. Otherwise
we need to hack into that huge triple-quoted chunk of js.

P.S. Didn't even know about contentEditable divs, thanks for the info,
looks pretty promising.

Rado

Rob Beezer

unread,
Jul 2, 2009, 10:39:13 AM7/2/09
to sage-devel
On Jul 1, 10:59 pm, Jason Grout <jason-s...@creativetrax.com> wrote:
> What I'm talking about is a lightweight tinymce-like control that would
> be able to sections of represent Sage code with a graphical widget, like
> replacing Graph({0:[2,3], 1:[3],2:[3,4]}) with Rado's graph editor, or a
> symbolic expression with Davide's equation editor.

Jason,

I really like your idea of toggling back-and-forth between a widget
and more standard textual input.

I've got a grander vision for graphs. Tell me if I'm just dreaming.
Here's how it would go:

G = graph.PetersenGraph()
G.visual_edit()
<new window opens with G in a graph editor>
<move vertices around in edit window>
G.num_edges() # in old window
15
<remove an edge in edit window>
G.num_edges() # in old window
14

and so on. If the notebook can communicate with a running Sage
process, could a graph-edit window/page also communicate with the same
process and update the graph's data structure in lock-step with the
actions performed in the editor? Or am I being naive?

And then I want to do it all in an interact. ;-) See a graph,
twiddle it with the mouse, various properties (planarity, degrees,
girth, etc) all update in response. Never even have to know what a
dictionary is, yet can fruitfully explore interesting properties as a
graph is adjusted/created. I think folks doing research/teaching with
graphs would find this capability a great complement to all the
computational support graphs have (and what's coming along soon).

I'm really glad to see both you and Rado interested in this, and I'll
do what I can to help, but I think I'll be relegated to testing (and
being a critic - in the good sense of the word).

Rob

William Stein

unread,
Jul 2, 2009, 11:08:02 AM7/2/09
to sage-...@googlegroups.com
On Thu, Jul 2, 2009 at 4:39 PM, Rob Beezer<goo...@beezer.cotse.net> wrote:
>
> On Jul 1, 10:59 pm, Jason Grout <jason-s...@creativetrax.com> wrote:
>> What I'm talking about is a lightweight tinymce-like control that would
>> be able to sections of represent Sage code with a graphical widget, like
>> replacing Graph({0:[2,3], 1:[3],2:[3,4]}) with Rado's graph editor, or a
>> symbolic expression with Davide's equation editor.
>
> Jason,
>
> I really like your idea of toggling back-and-forth between a widget
> and more standard textual input.
>
> I've got a grander vision for graphs.  Tell me if I'm just dreaming.
> Here's how it would go:
>
> G = graph.PetersenGraph()
> G.visual_edit()
> <new window opens with G in a graph editor>
> <move vertices around in edit window>
> G.num_edges()  # in old window
> 15
> <remove an edge in edit window>
> G.num_edges()  # in old window
> 14
>
> and so on.  If the notebook can communicate with a running Sage
> process, could a graph-edit window/page also communicate with the same
> process and update the graph's data structure in lock-step with the
> actions performed in the editor?  Or am I being naive?

No. This can and will work fine. In fact it already *does* with
interact. Here's a tutorial:

(1) Paste this into a cell:

G=None
@interact
def f(n=(3..8)):
global G
G = graphs.CompleteGraph(n)

(2) In another cell type

print len(G.edges())

and get 3 as output.

(3) Drag the slider

(4) In yet another cell type

print len(G.edges())

and get 10 (say) as output.

> And then I want to do it all in an interact.  ;-)  See a graph,
> twiddle it with the mouse, various properties (planarity, degrees,
> girth, etc) all update in response.  Never even have to know what a
> dictionary is, yet can fruitfully explore interesting properties as a
> graph is adjusted/created.  I think folks doing research/teaching with
> graphs would find this capability a great complement to all the
> computational support graphs have (and what's coming along soon).
>
> I'm really glad to see both you and Rado interested in this, and I'll
> do what I can to help, but I think I'll be relegated to testing (and
> being a critic - in the good sense of the word).
>
> Rob
>
> >
>



--
William Stein
Associate Professor of Mathematics
University of Washington
http://wstein.org

Jason Grout

unread,
Jul 2, 2009, 11:34:28 AM7/2/09
to sage-...@googlegroups.com
Rob Beezer wrote:
> On Jul 1, 10:59 pm, Jason Grout <jason-s...@creativetrax.com> wrote:
>> What I'm talking about is a lightweight tinymce-like control that would
>> be able to sections of represent Sage code with a graphical widget, like
>> replacing Graph({0:[2,3], 1:[3],2:[3,4]}) with Rado's graph editor, or a
>> symbolic expression with Davide's equation editor.
>
> Jason,
>
> I really like your idea of toggling back-and-forth between a widget
> and more standard textual input.
>
> I've got a grander vision for graphs. Tell me if I'm just dreaming.
> Here's how it would go:
>
> G = graph.PetersenGraph()
> G.visual_edit()
> <new window opens with G in a graph editor>
> <move vertices around in edit window>
> G.num_edges() # in old window
> 15
> <remove an edge in edit window>
> G.num_edges() # in old window
> 14
>


I was primarily thinking of a way to *input* things with widgets, such
that the state (and widget) could be exactly reconstructed only from the
text when the notebook page was reloaded. It seems like it is a simpler
concept since you only have to rely on the text of the worksheet.

In your case, when the worksheet is reloaded, are all your graphical
changes to G lost? I was trying to think of a way to avoid this.
(Hence the insistence that any widget correspond to an exactly
equivalent piece of text in a cell, so that the widget could be
reconstructed from the text, and vice versa.)

Once you have that, though, you could do something like William's
concept with an @interact to continuously reset a graph to a different
value. I could see something like William's suggestion:

@interact
def (g=Widget('Graph()')):
global G = g

That would provide a graph control that keeps updating the global G.
Then you have the case of your prior example. In fact, it could be
arranged that G.visual_edit() pops up a cell that does exactly the above
code.

In this case, Widget(A) constructs a widget from the text A. Or you
could just have @interact automatically put Rado's graph editor in when
you do g=Graph().

Thanks for the discussion!

Jason


William Stein

unread,
Jul 3, 2009, 11:17:06 AM7/3/09
to sage-...@googlegroups.com

Thanks! This is now

http://sagetrac.org/sage_trac/ticket/6459

William

Rob Beezer

unread,
Jul 3, 2009, 2:04:24 PM7/3/09
to sage-devel
On Jul 2, 8:08 am, William Stein <wst...@gmail.com> wrote:
> No.  This can and will work fine.  In fact it already *does* with
> interact.  Here's a tutorial:

Hi William,

Thanks for the tutorial - I'll play with that idea some. Once I wrap
my head around the other ideas and approaches being discussed.

More discussion along these lines at:
http://groups.google.com/group/sage-devel/browse_thread/thread/eea3e7faf475db6

Rob
Reply all
Reply to author
Forward
0 new messages