import os, sys
|
|
import lesscpy
|
|
from shutil import copyfile, rmtree
|
|
from jupyter_core.paths import jupyter_config_dir, jupyter_data_dir
|
|
from glob import glob
|
|
from tempfile import mkstemp
|
|
|
|
# path to local site-packages/jupyterthemes
|
|
package_dir = os.path.dirname(os.path.realpath(__file__))
|
|
|
|
# path to user jupyter-themes dir
|
|
user_dir = os.path.join(os.path.expanduser('~'), '.jupyter-themes')
|
|
|
|
# path to save tempfile with style_less before reading/compiling
|
|
_, tempfile = mkstemp('.less')
|
|
_, vimtemp = mkstemp('.less')
|
|
|
|
# path to install custom.css file (~/.jupyter/custom/)
|
|
jupyter_home = jupyter_config_dir()
|
|
jupyter_data = jupyter_data_dir()
|
|
|
|
jupyter_custom = os.path.join(jupyter_home, 'custom')
|
|
jupyter_custom_fonts = os.path.join(jupyter_custom, 'fonts')
|
|
jupyter_customcss = os.path.join(jupyter_custom, 'custom.css')
|
|
jupyter_customjs = os.path.join(jupyter_custom, 'custom.js')
|
|
jupyter_nbext = os.path.join(jupyter_data, 'nbextensions')
|
|
|
|
# theme colors, layout, and font directories
|
|
layouts_dir = os.path.join(package_dir, 'layout')
|
|
styles_dir = os.path.join(package_dir, 'styles')
|
|
styles_dir_user = os.path.join(user_dir, 'styles')
|
|
fonts_dir = os.path.join(package_dir, 'fonts')
|
|
defaults_dir = os.path.join(package_dir, 'defaults')
|
|
|
|
# default custom.css/js files to override JT on reset
|
|
defaultCSS = os.path.join(defaults_dir, 'custom.css')
|
|
defaultJS = os.path.join(defaults_dir, 'custom.js')
|
|
|
|
# layout files for notebook, codemirror, cells, mathjax, & vim ext
|
|
nb_style = os.path.join(layouts_dir, 'notebook.less')
|
|
cm_style = os.path.join(layouts_dir, 'codemirror.less')
|
|
cl_style = os.path.join(layouts_dir, 'cells.less')
|
|
ex_style = os.path.join(layouts_dir, 'extras.less')
|
|
vim_style = os.path.join(layouts_dir, 'vim.less')
|
|
comp_style = os.path.join(layouts_dir, 'completer.less')
|
|
theme_name_file = os.path.join(jupyter_custom, 'current_theme.txt')
|
|
|
|
|
|
def fileOpen(filename, mode):
|
|
if sys.version_info[0]==3:
|
|
return open(filename, mode, encoding='utf8', errors='ignore')
|
|
else:
|
|
return open(filename, mode)
|
|
|
|
def check_directories():
|
|
# Ensure all install dirs exist
|
|
if not os.path.isdir(jupyter_home):
|
|
os.makedirs(jupyter_home)
|
|
if not os.path.isdir(jupyter_custom):
|
|
os.makedirs(jupyter_custom)
|
|
if not os.path.isdir(jupyter_custom_fonts):
|
|
os.makedirs(jupyter_custom_fonts)
|
|
if not os.path.isdir(jupyter_data):
|
|
os.makedirs(jupyter_data)
|
|
if not os.path.isdir(jupyter_nbext):
|
|
os.makedirs(jupyter_nbext)
|
|
|
|
|
|
def less_to_css(style_less):
|
|
""" write less-compiled css file to jupyter_customcss in jupyter_dir
|
|
"""
|
|
with fileOpen(tempfile, 'w') as f:
|
|
f.write(style_less)
|
|
os.chdir(package_dir)
|
|
style_css = lesscpy.compile(tempfile)
|
|
style_css += '\n\n'
|
|
return style_css
|
|
|
|
def write_final_css(style_css):
|
|
# install style_css to .jupyter/custom/custom.css
|
|
with fileOpen(jupyter_customcss, 'w') as custom_css:
|
|
custom_css.write(style_css)
|
|
|
|
|
|
def install_precompiled_theme(theme):
|
|
# for Python 3.5, install selected theme from precompiled defaults
|
|
compiled_dir = os.path.join(styles_dir, 'compiled')
|
|
compiled_dir_user = os.path.join(styles_dir_user, 'compiled')
|
|
|
|
if (os.path.isdir(compiled_dir_user) and
|
|
'{}.css'.format(theme) in os.listdir(compiled_dir_user)):
|
|
theme_src = os.path.join(compiled_dir_user, '{}.css'.format(theme))
|
|
else:
|
|
theme_src = os.path.join(compiled_dir, '{}.css'.format(theme))
|
|
theme_dst = os.path.join(jupyter_custom, 'custom.css')
|
|
copyfile(theme_src, theme_dst)
|
|
|
|
def send_fonts_to_jupyter(font_file_path):
|
|
fname = font_file_path.split(os.sep)[-1]
|
|
copyfile(font_file_path, os.path.join(jupyter_custom_fonts, fname))
|
|
|
|
|
|
def delete_font_files():
|
|
for fontfile in os.listdir(jupyter_custom_fonts):
|
|
abspath = os.path.join(jupyter_custom_fonts, fontfile)
|
|
os.remove(abspath)
|
|
|
|
|
|
def convert_fontsizes(fontsizes):
|
|
# if triple digits, move decimal (105 --> 10.5)
|
|
fontsizes = [str(fs) for fs in fontsizes]
|
|
for i, fs in enumerate(fontsizes):
|
|
if len(fs) >= 3:
|
|
fontsizes[i] = '.'.join([fs[:-1], fs[-1]])
|
|
elif int(fs) > 25:
|
|
fontsizes[i] = '.'.join([fs[0], fs[-1]])
|
|
return fontsizes
|
|
|
|
|
|
def set_font_properties(style_less,
|
|
nbfont=None,
|
|
tcfont=None,
|
|
monofont=None,
|
|
monosize=11,
|
|
tcfontsize=13,
|
|
nbfontsize=13,
|
|
prfontsize=95,
|
|
dffontsize=93,
|
|
outfontsize=85,
|
|
mathfontsize=100,
|
|
dfonts=False):
|
|
"""Parent function for setting notebook, text/md, and
|
|
codecell font-properties
|
|
"""
|
|
|
|
fontsizes = [monosize, nbfontsize, tcfontsize, prfontsize, dffontsize, outfontsize]
|
|
monosize, nbfontsize, tcfontsize, prfontsize, dffontsize, outfontsize = convert_fontsizes(fontsizes)
|
|
if dfonts==True:
|
|
monofont, tcfont, nbfont = ['monospace', 'sans-serif', 'sans-serif']
|
|
else:
|
|
if monofont is not None:
|
|
monofont, monofpath = stored_font_dicts(monofont)
|
|
style_less = import_fonts(style_less, monofont, monofpath)
|
|
else:
|
|
monofont='monospace'
|
|
if tcfont is not None:
|
|
tcfont, tcfontpath = stored_font_dicts(tcfont)
|
|
style_less = import_fonts(style_less, tcfont, tcfontpath)
|
|
else:
|
|
tcfont='sans-serif'
|
|
if nbfont is not None:
|
|
if nbfont == 'proxima':
|
|
nbfont, tcfont = ["'Proxima Nova'"]*2
|
|
style_less = proxima_nova_imports(style_less)
|
|
else:
|
|
nbfont, nbfontpath = stored_font_dicts(nbfont)
|
|
style_less = import_fonts(style_less, nbfont, nbfontpath)
|
|
else:
|
|
nbfont='sans-serif'
|
|
|
|
style_less += '/* Set Font-Type and Font-Size Variables */\n'
|
|
# font names and fontfamily info for codecells, notebook & textcells
|
|
style_less += '@monofont: {}; \n'.format(monofont)
|
|
style_less += '@notebook-fontfamily: {}; \n'.format(nbfont)
|
|
style_less += '@text-cell-fontfamily: {}; \n'.format(tcfont)
|
|
# font size for codecells, main notebook, notebook-sub, & textcells
|
|
style_less += '@monofontsize: {}pt; \n'.format(monosize)
|
|
style_less += '@monofontsize-sub: {}pt; \n'.format(float(monosize) - 1)
|
|
style_less += '@nb-fontsize: {}pt; \n'.format(nbfontsize)
|
|
style_less += '@nb-fontsize-sub: {}pt; \n'.format(float(nbfontsize) - 1)
|
|
style_less += '@text-cell-fontsize: {}pt; \n'.format(tcfontsize)
|
|
style_less += '@df-header-fontsize: {}pt; \n'.format(float(dffontsize) + 1)
|
|
style_less += '@df-fontsize: {}pt; \n'.format(dffontsize)
|
|
style_less += '@output-font-size: {}pt; \n'.format(outfontsize)
|
|
style_less += '@prompt-fontsize: {}pt; \n'.format(prfontsize)
|
|
style_less += '@mathfontsize: {}%; \n'.format(mathfontsize)
|
|
style_less += '\n\n'
|
|
style_less += '/* Import Theme Colors and Define Layout Variables */\n'
|
|
return style_less
|
|
|
|
|
|
def import_fonts(style_less, fontname, font_subdir):
|
|
"""Copy all custom fonts to ~/.jupyter/custom/fonts/ and
|
|
write import statements to style_less
|
|
"""
|
|
|
|
ftype_dict = {'woff2': 'woff2',
|
|
'woff': 'woff',
|
|
'ttf': 'truetype',
|
|
'otf': 'opentype',
|
|
'svg': 'svg'}
|
|
|
|
define_font = (
|
|
"@font-face {{font-family: {fontname};\n\tfont-weight:"
|
|
"{weight};\n\tfont-style: {style};\n\tsrc: local('{fontname}'),"
|
|
"\n\turl('fonts{sepp}{fontfile}') format('{ftype}');}}\n")
|
|
fontname = fontname.split(',')[0]
|
|
fontpath = os.path.join(fonts_dir, font_subdir)
|
|
for fontfile in os.listdir(fontpath):
|
|
if '.txt' in fontfile or 'DS_' in fontfile:
|
|
continue
|
|
weight = 'normal'
|
|
style = 'normal'
|
|
if 'medium' in fontfile:
|
|
weight = 'medium'
|
|
elif 'ital' in fontfile:
|
|
style = 'italic'
|
|
ft = ftype_dict[fontfile.split('.')[-1]]
|
|
style_less += define_font.format(
|
|
fontname=fontname,
|
|
weight=weight,
|
|
style=style,
|
|
sepp='/',
|
|
fontfile=fontfile,
|
|
ftype=ft)
|
|
send_fonts_to_jupyter(os.path.join(fontpath, fontfile))
|
|
|
|
return style_less
|
|
|
|
|
|
def style_layout(style_less,
|
|
theme='grade3',
|
|
cursorwidth=2,
|
|
cursorcolor='default',
|
|
cellwidth='980',
|
|
lineheight=170,
|
|
margins='auto',
|
|
vimext=False,
|
|
toolbar=False,
|
|
nbname=False,
|
|
kernellogo=False,
|
|
altprompt=False,
|
|
altmd=False,
|
|
altout=False,
|
|
hideprompt=False):
|
|
"""Set general layout and style properties of text and code cells"""
|
|
|
|
# write theme name to ~/.jupyter/custom/ (referenced by jtplot.py)
|
|
with fileOpen(theme_name_file, 'w') as f:
|
|
f.write(theme)
|
|
|
|
if (os.path.isdir(styles_dir_user) and
|
|
'{}.less'.format(theme) in os.listdir(styles_dir_user)):
|
|
theme_relpath = os.path.relpath(
|
|
os.path.join(styles_dir_user, theme), package_dir)
|
|
else:
|
|
theme_relpath = os.path.relpath(
|
|
os.path.join(styles_dir, theme), package_dir)
|
|
|
|
style_less += '@import "{}";\n'.format(theme_relpath)
|
|
|
|
textcell_bg = '@cc-input-bg'
|
|
promptText = '@input-prompt'
|
|
promptBG = '@cc-input-bg'
|
|
promptPadding = '.25em'
|
|
promptBorder = '2px solid @prompt-line'
|
|
tcPromptBorder = '2px solid @tc-prompt-std'
|
|
promptMinWidth = 11.5
|
|
outpromptMinWidth = promptMinWidth # remove + 3 since it will overlay output print() text
|
|
tcPromptWidth = promptMinWidth + 3
|
|
tcPromptFontsize = "@prompt-fontsize"
|
|
ccOutputBG = '@cc-output-bg-default'
|
|
|
|
if theme == 'grade3':
|
|
textcell_bg = '@notebook-bg'
|
|
if altprompt:
|
|
promptPadding = '.1em'
|
|
promptMinWidth = 8
|
|
outpromptMinWidth = promptMinWidth + 3
|
|
tcPromptWidth = promptMinWidth + 3
|
|
promptText = 'transparent'
|
|
tcPromptBorder = '2px solid transparent'
|
|
if altmd:
|
|
textcell_bg = '@notebook-bg'
|
|
tcPromptBorder = '2px dotted @tc-border-selected'
|
|
if altout:
|
|
ccOutputBG = '@notebook-bg'
|
|
if margins != 'auto':
|
|
margins = '{}px'.format(margins)
|
|
if '%' not in cellwidth:
|
|
cellwidth = str(cellwidth) + 'px'
|
|
|
|
style_less += '@container-margins: {};\n'.format(margins)
|
|
style_less += '@cell-width: {}; \n'.format(cellwidth)
|
|
style_less += '@cc-line-height: {}%; \n'.format(lineheight)
|
|
style_less += '@text-cell-bg: {}; \n'.format(textcell_bg)
|
|
style_less += '@cc-prompt-width: {}ex; \n'.format(promptMinWidth)
|
|
style_less += '@cc-prompt-bg: {}; \n'.format(promptBG)
|
|
style_less += '@cc-output-bg: {}; \n'.format(ccOutputBG)
|
|
style_less += '@prompt-text: {}; \n'.format(promptText)
|
|
style_less += '@prompt-padding: {}; \n'.format(promptPadding)
|
|
style_less += '@prompt-border: {}; \n'.format(promptBorder)
|
|
style_less += '@prompt-min-width: {}ex; \n'.format(promptMinWidth)
|
|
style_less += '@out-prompt-min-width: {}ex; \n'.format(outpromptMinWidth)
|
|
style_less += '@tc-prompt-width: {}ex; \n'.format(tcPromptWidth)
|
|
style_less += '@tc-prompt-border: {}; \n'.format(tcPromptBorder)
|
|
style_less += '@cursor-width: {}px; \n'.format(cursorwidth)
|
|
style_less += '@cursor-info: @cursor-width solid {}; \n'.format(
|
|
cursorcolor)
|
|
style_less += '@tc-prompt-fontsize: {}; \n'.format(tcPromptFontsize)
|
|
style_less += '\n\n'
|
|
|
|
# read-in notebook.less (general nb style)
|
|
with fileOpen(nb_style, 'r') as notebook:
|
|
style_less += notebook.read() + '\n'
|
|
|
|
# read-in cells.less (cell layout)
|
|
with fileOpen(cl_style, 'r') as cells:
|
|
style_less += cells.read() + '\n'
|
|
|
|
# read-in extras.less (misc layout)
|
|
with fileOpen(ex_style, 'r') as extras:
|
|
style_less += extras.read() + '\n'
|
|
|
|
# read-in codemirror.less (syntax-highlighting)
|
|
with fileOpen(cm_style, 'r') as codemirror:
|
|
style_less += codemirror.read() + '\n'
|
|
with fileOpen(comp_style, 'r') as codemirror:
|
|
style_less += codemirror.read() + '\n'
|
|
|
|
style_less += toggle_settings(
|
|
toolbar, nbname, hideprompt, kernellogo) + '\n'
|
|
if vimext:
|
|
set_vim_style(theme)
|
|
|
|
return style_less
|
|
|
|
|
|
def toggle_settings(
|
|
toolbar=False, nbname=False, hideprompt=False, kernellogo=False):
|
|
"""Toggle main notebook toolbar (e.g., buttons), filename,
|
|
and kernel logo."""
|
|
|
|
toggle = ''
|
|
if toolbar:
|
|
toggle += 'div#maintoolbar {margin-left: 8px !important;}\n'
|
|
toggle += '.toolbar.container {width: 100% !important;}\n'
|
|
else:
|
|
toggle += 'div#maintoolbar {display: none !important;}\n'
|
|
if nbname:
|
|
toggle += ('span.save_widget span.filename {margin-left: 8px; height: initial;'
|
|
'font-size: 100%; color: @nb-name-fg; background-color:'
|
|
'@cc-input-bg;}\n')
|
|
toggle += ('span.save_widget span.filename:hover {color:'
|
|
'@nb-name-hover; background-color: @cc-input-bg;}\n')
|
|
toggle += ('#menubar {padding-top: 4px; background-color:'
|
|
'@notebook-bg;}\n')
|
|
else:
|
|
toggle += '#header-container {display: none !important;}\n'
|
|
if hideprompt:
|
|
toggle += 'div.prompt.input_prompt {display: none !important;}\n'
|
|
toggle += 'div.prompt.output_prompt {width: 5ex !important;}\n'
|
|
toggle += 'div.out_prompt_overlay.prompt:hover {width: 5ex !important; min-width: 5ex !important;}\n'
|
|
toggle += (
|
|
'.CodeMirror-gutters, .cm-s-ipython .CodeMirror-gutters'
|
|
'{ position: absolute; left: 0; top: 0; z-index: 3; width: 2em; '
|
|
'display: inline-block !important; }\n')
|
|
toggle += ('div.cell.code_cell .input { border-left: 5px solid @cm-gutters !important; border-bottom-left-radius: 5px; border-top-left-radius: 5px; }\n')
|
|
if kernellogo:
|
|
toggle += '@kernel-logo-display: block;'
|
|
else:
|
|
toggle += '@kernel-logo-display: none;'
|
|
|
|
return toggle
|
|
|
|
|
|
def proxima_nova_imports(style_less):
|
|
|
|
style_less += """@font-face {
|
|
font-family: 'Proxima Nova Bold';
|
|
src: url('fonts/Proxima Nova Alt Bold-webfont.eot');
|
|
src: url('fonts/Proxima Nova Alt Bold-webfont.eot?#iefix') format('embedded-opentype'),
|
|
url('fonts/Proxima Nova Alt Bold-webfont.woff2') format('woff2'),
|
|
url('fonts/Proxima Nova Alt Bold-webfont.woff') format('woff'),
|
|
url('fonts/Proxima Nova Alt Bold-webfont.ttf') format('truetype'),
|
|
url('fonts/Proxima Nova Alt Bold-webfont.svg#proxima_nova_altbold') format('svg');
|
|
font-weight: 600;
|
|
font-style: normal;
|
|
}
|
|
|
|
@font-face {
|
|
font-family: 'Proxima Nova';
|
|
src: url('fonts/Proxima Nova Alt Regular-webfont.eot');
|
|
src: url('fonts/Proxima Nova Alt Regular-webfont.eot?#iefix') format('embedded-opentype'),
|
|
url('fonts/Proxima Nova Alt Regular-webfont.woff') format('woff'),
|
|
url('fonts/Proxima Nova Alt Regular-webfont.ttf') format('truetype'),
|
|
url('fonts/Proxima Nova Alt Regular-webfont.svg#proxima_nova_altregular') format('svg');
|
|
font-weight: 400;
|
|
font-style: normal;
|
|
}"""
|
|
|
|
font_subdir = os.path.join(fonts_dir, "sans-serif/proximasans")
|
|
fontpath = os.path.join(fonts_dir, font_subdir)
|
|
for fontfile in os.listdir(font_subdir):
|
|
send_fonts_to_jupyter(os.path.join(fontpath, fontfile))
|
|
|
|
return style_less
|
|
|
|
|
|
def set_mathjax_style(style_css, mathfontsize):
|
|
"""Write mathjax settings, set math fontsize
|
|
"""
|
|
|
|
jax_style = """<script>
|
|
MathJax.Hub.Config({
|
|
"HTML-CSS": {
|
|
/*preferredFont: "TeX",*/
|
|
/*availableFonts: ["TeX", "STIX"],*/
|
|
styles: {
|
|
scale: %d,
|
|
".MathJax_Display": {
|
|
"font-size": %s,
|
|
}
|
|
}
|
|
}
|
|
});\n</script>
|
|
""" % (int(mathfontsize), '"{}%"'.format(str(mathfontsize)))
|
|
|
|
style_css += jax_style
|
|
return style_css
|
|
|
|
|
|
|
|
def set_vim_style(theme):
|
|
"""Add style and compatibility with vim notebook extension"""
|
|
|
|
vim_jupyter_nbext = os.path.join(jupyter_nbext, 'vim_binding')
|
|
|
|
if not os.path.isdir(vim_jupyter_nbext):
|
|
os.makedirs(vim_jupyter_nbext)
|
|
|
|
vim_less = '@import "styles{}";\n'.format(''.join([os.sep, theme]))
|
|
|
|
with open(vim_style, 'r') as vimstyle:
|
|
vim_less += vimstyle.read() + '\n'
|
|
with open(vimtemp, 'w') as vtemp:
|
|
vtemp.write(vim_less)
|
|
os.chdir(package_dir)
|
|
vim_css = lesscpy.compile(vimtemp)
|
|
vim_css += '\n\n'
|
|
|
|
# install vim_custom_css to ...nbextensions/vim_binding/vim_binding.css
|
|
vim_custom_css = os.path.join(vim_jupyter_nbext, 'vim_binding.css')
|
|
with open(vim_custom_css, 'w') as vim_custom:
|
|
vim_custom.write(vim_css)
|
|
|
|
|
|
def reset_default(verbose=False):
|
|
"""Remove custom.css and custom fonts"""
|
|
paths = [jupyter_custom, jupyter_nbext]
|
|
|
|
for fpath in paths:
|
|
custom = '{0}{1}{2}.css'.format(fpath, os.sep, 'custom')
|
|
try:
|
|
os.remove(custom)
|
|
except Exception:
|
|
pass
|
|
try:
|
|
delete_font_files()
|
|
except Exception:
|
|
check_directories()
|
|
delete_font_files()
|
|
|
|
copyfile(defaultCSS, jupyter_customcss)
|
|
copyfile(defaultJS, jupyter_customjs)
|
|
|
|
if os.path.exists(theme_name_file):
|
|
os.remove(theme_name_file)
|
|
|
|
if verbose:
|
|
print("Reset css and font defaults in:\n{} &\n{}".format(*paths))
|
|
|
|
|
|
def set_nb_theme(name):
|
|
"""Set theme from within notebook """
|
|
from IPython.core.display import HTML
|
|
styles_dir = os.path.join(package_dir, 'styles/compiled/')
|
|
css_path = glob('{0}/{1}.css'.format(styles_dir, name))[0]
|
|
customcss = open(css_path, "r").read()
|
|
|
|
return HTML(''.join(['<style> ', customcss, ' </style>']))
|
|
|
|
|
|
def get_colors(theme='grade3', c='default', get_dict=False):
|
|
if theme == 'grade3':
|
|
cdict = {'default': '#ff711a',
|
|
'b': '#1e70c7',
|
|
'o': '#ff711a',
|
|
'r': '#e22978',
|
|
'p': '#AA22FF',
|
|
'g': '#2ecc71'}
|
|
else:
|
|
cdict = {'default': '#0095ff',
|
|
'b': '#0095ff',
|
|
'o': '#ff914d',
|
|
'r': '#DB797C',
|
|
'p': '#c776df',
|
|
'g': '#94c273'}
|
|
|
|
cdict['x'] = '@cc-input-fg'
|
|
|
|
if get_dict:
|
|
return cdict
|
|
|
|
return cdict[c]
|
|
|
|
|
|
def get_alt_prompt_text_color(theme):
|
|
altColors = {'grade3': '#FF7823',
|
|
'oceans16': '#667FB1',
|
|
'chesterish': '#0b98c8',
|
|
'onedork': '#94c273',
|
|
'monokai': '#94c273'}
|
|
|
|
return altColors[theme]
|
|
|
|
|
|
def stored_font_dicts(fontcode, get_all=False):
|
|
fonts = {'mono':
|
|
{'anka': ['Anka/Coder', 'anka-coder'],
|
|
'anonymous': ['Anonymous Pro', 'anonymous-pro'],
|
|
'aurulent': ['Aurulent Sans Mono', 'aurulent'],
|
|
'bitstream': ['Bitstream Vera Sans Mono', 'bitstream-vera'],
|
|
'bpmono': ['BPmono', 'bpmono'],
|
|
'code': ['Code New Roman', 'code-new-roman'],
|
|
'consolamono': ['Consolamono', 'consolamono'],
|
|
'cousine': ['Cousine', 'cousine'],
|
|
'dejavu': ['DejaVu Sans Mono', 'dejavu'],
|
|
'droidmono': ['Droid Sans Mono', 'droidmono'],
|
|
'fira': ['Fira Mono', 'fira'],
|
|
'firacode': ['Fira Code', 'firacode'],
|
|
'generic': ['Generic Mono', 'generic'],
|
|
'hack': ['Hack', 'hack'],
|
|
'hasklig': ['Hasklig', 'hasklig'],
|
|
'iosevka' : ['Iosevka', 'iosevka'],
|
|
'inputmono': ['Input Mono', 'inputmono'],
|
|
'inconsolata': ['Inconsolata-g', 'inconsolata-g'],
|
|
'liberation': ['Liberation Mono', 'liberation'],
|
|
'meslo': ['Meslo', 'meslo'],
|
|
'office': ['Office Code Pro', 'office-code-pro'],
|
|
'oxygen': ['Oxygen Mono', 'oxygen'],
|
|
'roboto': ['Roboto Mono', 'roboto'],
|
|
'saxmono': ['saxMono', 'saxmono'],
|
|
'source': ['Source Code Pro', 'source-code-pro'],
|
|
'sourcemed': ['Source Code Pro Medium', 'source-code-medium'],
|
|
'ptmono': ['PT Mono', 'ptmono'],
|
|
'ubuntu': ['Ubuntu Mono', 'ubuntu']},
|
|
'sans':
|
|
{'droidsans': ['Droid Sans', 'droidsans'],
|
|
'opensans': ['Open Sans', 'opensans'],
|
|
'ptsans': ['PT Sans', 'ptsans'],
|
|
'sourcesans': ['Source Sans Pro', 'sourcesans'],
|
|
'robotosans': ['Roboto', 'robotosans'],
|
|
'latosans': ['Lato', 'latosans'],
|
|
'exosans': ['Exo_2', 'exosans'],
|
|
'proxima': ['Proxima Nova', 'proximasans']},
|
|
'serif':
|
|
{'ptserif': ['PT Serif', 'ptserif'],
|
|
'ebserif': ['EB Garamond', 'ebserif'],
|
|
'loraserif': ['Lora', 'loraserif'],
|
|
'merriserif': ['Merriweather', 'merriserif'],
|
|
'crimsonserif': ['Crimson Text', 'crimsonserif'],
|
|
'georgiaserif': ['Georgia', 'georgiaserif'],
|
|
'neutonserif': ['Neuton', 'neutonserif'],
|
|
'cardoserif': ['Cardo Serif', 'cardoserif'],
|
|
'goudyserif': ['Goudy Serif', 'goudyserif']}}
|
|
if get_all:
|
|
return fonts
|
|
if fontcode in list(fonts['mono']):
|
|
fontname, fontdir = fonts['mono'][fontcode]
|
|
fontfam = 'monospace'
|
|
elif fontcode in list(fonts['sans']):
|
|
fontname, fontdir = fonts['sans'][fontcode]
|
|
fontfam = 'sans-serif'
|
|
elif fontcode in list(fonts['serif']):
|
|
fontname, fontdir = fonts['serif'][fontcode]
|
|
fontfam = 'serif'
|
|
else:
|
|
print("\n\tOne of the fonts you requested is not available\n\tSetting all fonts to default")
|
|
return ''
|
|
fontdir = os.sep.join([fontfam, fontdir])
|
|
return '"{}", {}'.format(fontname, fontfam), fontdir
|