Issues rendering MathJax using Sphinx due to HTML-CSS renderer - python

I just upgraded to the following:
Sphinx==1.8.5
nbconvert==5.4.1
pandoc==1.0.2
I have always been able to render math in docs via a jupyter notebook using Sphinx (the way it is done for seaborn). However, after upgrading, the math no longer renders! If I right click where the equation should be, I can change the math renderer to either "svg" or "CommonHTML" and everything is fine - it just doesn't render with the default "HTML-CSS" math renderer for whatever reason. My question is: how can I change the default renderer in my config file?
What I tried:
conf.py
...
extensions = [
...
'sphinx.ext.mathjax'
...
]
...
mathjax_config = {
'jax': ['input/TeX', 'output/CommonHTML']
}
However, this didn't change the default renderer like I thought it should. Does anyone know how to change the default renderer for MathJax within Sphinx?
Here is a gif:
Also, it would appear that MathJax is being loaded from CDN with a preferred config:

I am not sure how MathJax worked for you before, but based on the Sphinx-documentation MathJax is not included in Sphinx by default. You have to specify the mathjax_path in your conf.py either using a local version or a server hosted one from cdnjs for example.

While I wasn't able to get the mathjax_config approach to work, I was able to set the mathjax_path to a specific output processor, still through the CDN, which worked using CommonHTML.
So, an answer that works is to edit the conf.py file to include a line with:
...
mathjax_path = "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML"
...

Related

Syntax highlighting on readthedocs.io of sphinx code-block

I'm using RTD + Sphinx for my project ( redgrease = https://github.com/lyngon/redgrease ) and it seems like the syntax highlighting of code-blocks isn't working on the readthedocs.io page.
It only displays black text in a box.
E.g. see list item 3 at:
https://redgrease.readthedocs.io/en/latest/intro.html#intro-redgrease
The syntax highlighting works fine when I build locally (with sphinx-build) as well as in VS Code using the reStructuredText plugin.
Working (local)
Not working (readthedocs.io)
The code blocks are all indented (as they appear inside lists), similar to this:
#. :ref:`Server-side Redis commands <red_commands>`.
Allowing for ... blah blah ...
It is ... yada yada ...
.. code-block:: python
:emphasize-lines: 8, 11, 13
import redgrease
import redgrease.utils
# ... moar codes ..
What might be going on?
Do i need some extension or add some config option?
I don't have much trickery going on in the 'conf.py' nor '.readthedocs.yml'.
(see repo)
The reason was painfully simple.
I had by mistake pinned a really old version of 'sphinx-rtd-theme' in my 'requirements.txt' file.
I had pinned version 0.1.5 instead of the latest 0.5.1
My local env simply had a more recent version.
Doh! 🤦

Making Sphinx detect changes to auxiliary configuration/template files

I'm using Sphinx (v1.4.9, with Python 3.5.1 on Windows 7, 64-bit) to write a document set with MathJax enabled. I wanted to define custom LaTeX commands to clean up my source, so I implemented this approach by adding _templates\layout.html:
{% extends "!layout.html" %}
{% set script_files = script_files + ["_static/mjconf.js"] %}
and defining my custom commands in _static\mjconf.js:
MathJax.Hub.Config({
TeX: {
Macros: {
dsetarr: ['{\\small \\textsf{#1 Array } \\mathsf{(#2)} }', 2],
dsettype: ['{\\small \\textsf{#1}}', 1],
mtt: ['{\\texttt{#1}}' ,1],
sgn: ['{\\mathrm{sgn}#1}', 1]
}
}
});
This is all working great.
However, whenever I edit mjconf.js to add a new command or revise an existing one, Sphinx doesn't recognize that the configuration has changed and so a simple make html doesn't rebuild the docs like it does after an edit to conf.py. I have to make clean before the make html in order to see the effects of the changes to these custom MathJax commands.
How can I configure Sphinx to react to an edited mjconf.js by rebuilding the entire documentation set, just like it does for an edited conf.py?
There's make html -a, but that will not reflect updates to cross-references in your documentation. This would be the fastest option, though, if you have no cross-reference updates.
There's also make html -E in case you have cross-references that must be updated, too.
Finally there is make clean html, which deletes (cleans) the build directory, if your makefile has it, then builds HTML again.
In order to enable invocations such as make html -E as recommended by Steve Piercy, I changed my make.bat from this:
set BUILDDIR=build
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source
set I18NSPHINXOPTS=%SPHINXOPTS% source
if NOT "%PAPER%" == "" (
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
)
to this:
set BUILDDIR=build
set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source %2
set I18NSPHINXOPTS=%SPHINXOPTS% source
if NOT "%PAPER%" == "" (
set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS%
)
The only change was appending %2 to the line initializing %ALLSPHINXOPTS%.

How to use PyCharm for GIMP plugin development?

I need to develop a plugin for GIMP and would like to stay with PyCharm for Python editing, etc.
FYI, I'm on Windows.
After directing PyCharm to use the Python interpreter included with GIMP:
I also added a path to gimpfu.py to get rid of the error on from gimpfu import *:
This fixes the error on the import, even when set to Excluded.
I experimented with setting this directory to Sources, Resources and Excluded and still get errors for constants such as RGBA-IMAGE, TRANSPARENT_FILL, NORMAL_MODE, etc.
Any idea on how to contort PyCharm into playing nice for GIMP plugin development?
Not really running any code from PyCharm, it's really just being used as a nice code editor, facilitate revisions control, etc.
As you find this variables are part of .pyd files (dll files for Python). PyCharm can't get signatures for content of this files.
For Python builtins (like abs, all, any, etc.) PyCharm has it's own .py files that uses only for signatures and docs. You can see it if you'll click on some of this funcs and go to it's declaration:
PyCharm will open builtins.py file in it's folder with following content:
def abs(*args, **kwargs): # real signature unknown
""" Return the absolute value of the argument. """
pass
def all(*args, **kwargs): # real signature unknown
"""
Return True if bool(x) is True for all values x in the iterable.
If the iterable is empty, return True.
"""
pass
def any(*args, **kwargs): # real signature unknown
"""
Return True if bool(x) is True for any x in the iterable.
If the iterable is empty, return False.
"""
pass
As you see functions are defined and documented, but have no implementation, because their implementation created with C and placed somewhere in binary file.
Pycharm can't provide such wrapper for every library. Usually people who created .pyd files provide their .py wrappers (for example, PyQt module: no native python implementation, just signatures).
Looks like Gimp doesn't have such wrapper for some of variables. Only way I see is to create some sort of own wrapper manually. For example, create gimpfu_signatures.py with following content:
RGBA_IMAGE = 1
TRANSPARENT_FILL = 2
NORMAL_MODE = 3
And import it while you're creating plugin:
from gimpfu import *
from gimpfu_signatures import * # comment on release
Not elegant, but better then nothing.
...
One more note about gimpfu.py's path. If I understand correctly, you just added this path to project. It may work, but correct way is to add it to project's PYTHONPATH (in project preferences). See this link for detailed manual.

XCode Formatting issue for python files

I have used xcode to create several python scripts. It appears in the editor fine, however, when I attempt to look at the code through the terminal, I'm seeing that new lines are being encoded as "^M". This is problematic, since I am collaborating through github, and the diff features do not work when this is being done.
E.g.:
Source:
#############
#
# test.py
#
# by Author
#
#############
if __name__ == "__main__":
print "This is a test"
When I save this through another editor (PyCharmer) and more it via the console, I get the output as expected. When I create a new file via xcode, past the same text, and save, I get the following:
#############^M#^M# test.py^M#^M# by Author^M#^M#############^Mif __name__ == "__main__":^M print "This is a test"
Out of curiosity, I tried creating a test .cc file, and the same formatting issue did not arise, so if you want bonus points, explaining the inconsistency would be interesting as well.
In the latest Xcode 6, if I create a new external-build-system project, set the build tool to /usr/bin/python or /usr/local/bin/python3, create a new file named test.py in that project, Xcode recognizes its type (which you can see in the File Inspector panel of the assistant editor) as "Default — Python script", and its text settings (which you can also see in the File Inspector) as:
Text Encoding: Unicode (UTF-8)
Line Endings: Default — OS X / Unix (LF)
Indent Using: Spaces
Widths: Tab: 4 Indent: 4
Wrap lines: checked
And I get Python syntax coloring, tab completions, etc.
If that's not right—in particular, if you see Line Endings as "Classic Mac OS (CR)"—you can change it for the current file right there in the panel.
That fixes the current file. It may not fix the next file you create, but try it and see.
If not: In Xcode 4 and 5, you could easily change the default settings for each language, but that no longer seems to be exposed in Xcode 6. However, you may want to try going to the "Text Editing" pane of the "Preferences" dialog, and making sure "Default line endings" is set to "OS X / Unix (LF)", and maybe that "Convert existing files on save" is checked. This will help if you've got your default settings to Classic Mac, but C/ObjC/C++ overriding that with Unix. If, on the other hand, you somehow have a leftover override for Python from an earlier version of Xcode, I'm not sure how you can undo it short of wiping all of your Xcode settings and starting clean.
From a quick search, this answer has a very detailed version of some of the steps involved in configuring Python projects to handle things like the Run and Debug commands and so on, which may also be tangentially helpful.

What's the official way of storing settings for Python programs?

Django uses real Python files for settings, Trac uses a .ini file, and some other pieces of software uses XML files to hold this information.
Are one of these approaches blessed by Guido and/or the Python community more than another?
Depends on the predominant intended audience.
If it is programmers who change the file anyway, just use python files like settings.py
If it is end users then, think about ini files.
As many have said, there is no "offical" way. There are, however, many choices. There was a talk at PyCon this year about many of the available options.
Don't know if this can be considered "official", but it is in standard library: 14.2. ConfigParser — Configuration file parser.
This is, obviously, not an universal solution, though. Just use whatever feels most appropriate to the task, without any necessary complexity (and — especially — Turing-completeness! Think about automatic or GUI configurators).
I use a shelf ( http://docs.python.org/library/shelve.html ):
shelf = shelve.open(filename)
shelf["users"] = ["David", "Abraham"]
shelf.sync() # Save
Just one more option, PyQt. Qt has a platform independent way of storing settings with the QSettings class. Underneath the hood, on windows it uses the registry and in linux it stores the settings in a hidden conf file. QSettings works very well and is pretty seemless.
There is no blessed solution as far as I know. There is no right or wrong way to storing app settings neither, xml, json or all types of files are fine as long as you are confortable with. For python I personally use pypref it's very easy, cross platform and straightforward.
pypref is very useful as one can store static and dynamic settings and preferences ...
from pypref import Preferences
# create singleton preferences instance
pref = Preferences(filename="preferences_test.py")
# create preferences dict
pdict = {'preference 1': 1, 12345: 'I am a number'}
# set preferences. This would automatically create preferences_test.py
# in your home directory. Go and check it.
pref.set_preferences(pdict)
# lets update the preferences. This would automatically update
# preferences_test.py file, you can verify that.
pref.update_preferences({'preference 1': 2})
# lets get some preferences. This would return the value of the preference if
# it is defined or default value if it is not.
print pref.get('preference 1')
# In some cases we must use raw strings. This is most likely needed when
# working with paths in a windows systems or when a preference includes
# especial characters. That's how to do it ...
pref.update_preferences({'my path': " r'C:\Users\Me\Desktop' "})
# Sometimes preferences to change dynamically or to be evaluated real time.
# This also can be done by using dynamic property. In this example password
# generator preference is set using uuid module. dynamic dictionary
# must include all modules name that must be imported upon evaluating
# a dynamic preference
pre = {'password generator': "str(uuid.uuid1())"}
dyn = {'password generator': ['uuid',]}
pref.update_preferences(preferences=pre, dynamic=dyn)
# lets pull 'password generator' preferences twice and notice how
# passwords are different at every pull
print pref.get('password generator')
print pref.get('password generator')
# those preferences can be accessed later. Let's simulate that by creating
# another preferences instances which will automatically detect the
# existance of a preferences file and connect to it
newPref = Preferences(filename="preferences_test.py")
# let's print 'my path' preference
print newPref.get('my path')
I am not sure that there is an 'official' way (it is not mentioned in the Zen of Python :) )- I tend to use the Config Parser module myself and I think that you will find that pretty common. I prefer that over the python file approach because you can write back to it and dynamically reload if you want.
One of the easiest ways which is use is using the json module.
Save the file in config.json with the details as shown below.
Saving data in the json file:
{
"john" : {
"number" : "948075049" ,
"password":"thisisit"
}
}
Reading from json file:
import json
#open the config.json file
with open('config.json') as f:
mydata = json.load(f) ;
#Now mydata is a python dictionary
print("username is " , mydata.get('john').get('number') , " password is " , mydata.get('john').get('password')) ;
It depends largely on how complicated your configuration is. If you're doing a simple key-value mapping and you want the capability to edit the settings with a text editor, I think ConfigParser is the way to go.
If your settings are complicated and include lists and nested data structures, I'd use XML or JSON and create a configuration editor.
For really complicated things where the end user isn't expected to change the settings much, or is more trusted, just create a set of Python classes and evaluate a Python script to get the configuration.
For web applications I like using OS environment variables: os.environ.get('CONFIG_OPTION')
This works especially well for settings that vary between deploys. You can read more about the rationale behind using env vars here: http://www.12factor.net/config
Of course, this only works for read-only values because changes to the environment are usually not persistent. But if you don't need write access they are a very good solution.
It is more of convenience. There is no official way per say. But using XML files would make sense as they can be manipulated by various other applications/libraries.
Not an official one but this way works well for all my Python projects.
pip install python-settings
Docs here: https://github.com/charlsagente/python-settings
You need a settings.py file with all your defined constants like:
# settings.py
DATABASE_HOST = '10.0.0.1'
Then you need to either set an env variable (export SETTINGS_MODULE=settings) or manually calling the configure method:
# something_else.py
from python_settings import settings
from . import settings as my_local_settings
settings.configure(my_local_settings) # configure() receives a python module
The utility also supports Lazy initialization for heavy to load objects, so when you run your python project it loads faster since it only evaluates the settings variable when its needed
# settings.py
from python_settings import LazySetting
from my_awesome_library import HeavyInitializationClass # Heavy to initialize object
LAZY_INITIALIZATION = LazySetting(HeavyInitializationClass, "127.0.0.1:4222")
# LazySetting(Class, *args, **kwargs)
Just configure once and now call your variables where is needed:
# my_awesome_file.py
from python_settings import settings
print(settings.DATABASE_HOST) # Will print '10.0.0.1'
why would Guido blessed something that is out of his scope? No there is nothing particular blessed.

Categories

Resources