Open Jeitan opened 5 years ago
The feature probably doesn't work with a local style. You're welcome to submit a pull request to fix it.
Well, okay ... but could you clarify when one should using c.JupyterWidget.style_sheet
, and why it crashes? This is the notes in an auto-generated config file with no changes:
## A CSS stylesheet. The stylesheet can contain classes for:
# 1. Qt: QPlainTextEdit, QFrame, QWidget, etc
# 2. Pygments: .c, .k, .o, etc. (see PygmentsHighlighter)
# 3. QtConsole: .error, .in-prompt, .out-prompt, etc
#c.JupyterWidget.style_sheet = ''
If that's wrong, it should probably be changed. I also don't understand what the difference is between the two specifications in the config in the first place.
@dalthviz, could you provide a little help here?
So I have done some digging, and I admit to still being thoroughly turned around regarding where/what object/what initialization all of this is going on in, but think I've discovered at least one thing that looks inconsistent, but also something really weird.
In qtconsoleapp.py, in the init_colors
method of JupyterQtConsoleApp
, it pulls style sheets from two sources: a) self.stylesheet
and b) self.config.JupyterWidget.style_sheet
. From some debugging outputs, I have learned that the command line specification --stylesheet=
goes into (a), the config line c.JupyterQtConsoleApp.stylesheet
also goes into (a), and the config line c.JupyterWidget.style_sheet
goes into (b). (So it is (b) that makes it crash ... it opens fine but quits as soon as I type a single key).
There is a discrepancy with how (a) and (b) are handled, because toward the end of the function, the file path in (a) actually gets opened and read, with the resulting string going into a variable sheet
, which is then assigned to widget.style_sheet
(and I think widget is a highlighter object?). If both (a) and (b) are given, this overwrites whatever was in (b). However, if there is nothing in (a) but we do have (b), (b) gets assigned to widget.style_sheet
without being read first - so when (a) is active a string with CSS in it is being used, if (b) is active it's just a file path. I couldn't tell if that is handled gracefully further down the object hierarchy?
I thought at first that might be why it dies when I try to use c.JupyterWidget.style_sheet
. However, I modified the code (I set up a qtdev environment as per the guidelines) and added the same read functionality, and have verified that the exact same string (containing CSS) is being assigned to widget.style_sheet
, but when I use the config it still dies...
I also noted that perhaps it would fix the missing syntax highlighting (even for option (a)) if widget._syntax_style_changed()
were also called in the if sheet:
block, but that had no apparent effect.
I think this may be above my level of familiarity, because at this point I'm completely stumped.
@Jeitan sorry for the delay to respond. After reviewing this, as far as I can tell, the widget
you found is a JupyterWidget
instance. In the past, we used the style_sheet
attribute (which should be a string like the ones in the default template at qtconsole/styles.py
) in PR #217 to change the color scheme of the console. On the other hand you have the syntax_style
attribute of the JupyterWidget
which is the the pygments Style
subclass that will be used for the highligther
of the JupyterWidget
instance. In spyder-ide/spyder#4000 we implemented a way to create the Style
subclass on the fly but using the config of color schemes available in Spyder as a base to build it. Hope this give you some inside of what's going on with the stylesheet
setting.
@dalthviz Thanks for the explanation! I perused the PRs you mentioned, and now I can kind of see how things ended up. If I have some free time at some point I might try to see if I can get some sort of local style input working ... maybe by looking at what Spyder does.
@dalthviz I have the same issue, but after going through https://github.com/jupyter/qtconsole/pull/217 it appears to be the case that syntax_style
is hard coded to the set of builtin pygment styles. Am I right about my analysis? (A temporary fix was to register a plugin for pygments)
@daegontaven awesome! As far as I remember what I did in that PR was to create some methods to set the syntax_style
using the available pygment styles via the GUI, so it make sense that you can add custom syntax styles registring plugins for pygments. Also, I think that the PR more than hardcoding the syntax_style
lets you handle the syntax_style
attribute of the console changing it using the available pygments styles, althougth if you have a valid custom Style
subclass you could potentialy set it with set_syntax_style
at qtconsole/mainwindow.py
. Maybe what we need here is to provide a way to set programatically a class for syntax_style
using the info of style provided with the stylesheet argument (something that probably needs the dynamic creation of a Style
subclass in a similar way as in spyder-ide/spyder#4000 and more specifically spyder/utils/ipython/style.py
).
Some of that was a bit hard to follow for me (sorry), but I'm all for that last sentence! At some point in the past I looked into a pygments plugin (since I'm not admin and can't modify the pygments/styles directory), but I got pretty confused pretty quickly since I've never had the need to use setuptools. I'm not a programmer, merely a scientist who programs :P. So having a stylesheet-type input would be lovely!
@dalthviz My use case is specifically to set syntax style from RichJupyterWidget
in another application.
jupyter_widget = RichJupyterWidget()
jupyter_widget.style_sheet = get_theme_contents(
"dracula",
"jupyter.css"
) # Custom method that grabs a stylesheet css file
jupyter_widget.syntax_style = "dracula"
The above works in so far as I register a pygments plugin in advance. It does not work if i try to set a pygments Style
class for jupyter_widget.syntax_style
since it only accepts strings as seen here:
https://github.com/jupyter/qtconsole/blob/b2fa483b06972403de81550b04318f5554a066ba/qtconsole/jupyter_widget.py#L90-L95
There is no way to set it from RichJupyterWidget
. That would be a nice feature and I assume it would also solve the issue @Jeitan is facing.
@daegontaven you are right, reviewing more in deep what we did for Spyder, we reimplemented the method _syntax_style_changed
from the RichJupyterWidget
to set the highlighter style (_highlighter._style
) to the class we generated dynamically. Maybe adding a way to set the style of the highlighter is what we need here :)
(Trying to confirm my understanding)
We can not use local CSS files with qtconsole? Would it work if I upload the file to an HTTP server and use --stylesheet=https://.../theme.css
?
Right now it doesn't work locally nor via web.
I am trying to apply a custom style to Jupyter QtConsole, and am finding that I can influence the style using one of Pygments' builtin styles(
jupyter qtconsole --style=native
), and I can influence the Qt and prompts (.in-prompt, etc.) using a stylesheet, but I cannot influence the syntax style using a stylesheet. In particular, I have a file I obtained by doingpygmentize -S native -f html > native.css
, but then when I tryjupyter qtconsole --stylesheet=native.css
, nothing happens to the style. It also appears to not work when specified inc.JupyterQtConsoleApp.stylesheet
in the config file (the Qt parts change, but the style parts don't). When I put it intoc.JupyterWidget.style_sheet
in the config, it actually makes qtconsole crash. I can't tell from the documentation why this doesn't work ... the config notes near the latter seem to indicate that all should be just fine.I am trying to use some custom styles I like, and I must do it by config or by command line - I have no control over the installation so I cannot put a new style into Pygments' folder in site-packages.
The systems I actually work on are all offline, but it also appears not to work in the developer version I'm testing with from the most recent code, it says 4.5.0.dev0. Python 3.7.3, pyqt 5.9.2.