Skip to content

Commit

Permalink
Allow loading LaTeX macros from text files
Browse files Browse the repository at this point in the history
  • Loading branch information
davethecipo committed Jan 18, 2016
1 parent 9f152e6 commit 2ad63c8
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 3 deletions.
16 changes: 14 additions & 2 deletions Readme.md
Expand Up @@ -52,6 +52,14 @@ the math output in the summary.
To restore math, [BeautifulSoup4](https://pypi.python.org/pypi/beautifulsoup4/4.4.0)
is used. If it is not installed, no summary processing will happen.

### Load custom LaTeX macros

If you use the same macros over and over, it's a good idea to not repeat yourself defining them in multiple Markdown or reStructuredText documents. What you can do instead is tell the plugin absolute paths for text files containing macro definitions.

If the same macro name has multiple definitions, the last one is used and a warning is printed to stdout.

See below in the Usage section for examples.

Usage
-----
### Templates
Expand Down Expand Up @@ -99,11 +107,15 @@ Requires [BeautifulSoup4](http://www.crummy.com/software/BeautifulSoup/bs4/doc/)
**Default Value**: `False`
* `message_style`: [string] This value controls the verbosity of the messages in the lower left-hand corner. Set it to `None` to eliminate all messages.
**Default Value**: normal
* `macros`: [list] each element of the list is a [string] containing the absolute path to a file with macro definitions.
**Default Value**: `[]`

#### Settings Examples
Make math render in blue and displaymath align to the left:
Make math render in blue, displaymath align to the left and load macros from `/home/user/latex-macros.tex`:

macros = ['/home/user/latex-macros.tex']
MATH_JAX = {'color': 'blue', 'align': 'left', 'macros': macros}

MATH_JAX = {'color':'blue','align':left}

Use the [color](http://docs.mathjax.org/en/latest/tex.html#color) and
[mhchem](http://docs.mathjax.org/en/latest/tex.html#mhchem) extensions:
Expand Down
76 changes: 76 additions & 0 deletions math.py
Expand Up @@ -71,6 +71,7 @@ def process_settings(pelicanobj):
mathjax_settings['process_summary'] = BeautifulSoup is not None # will fix up summaries if math is cut off. Requires beautiful soup
mathjax_settings['force_tls'] = 'false' # will force mathjax to be served by https - if set as False, it will only use https if site is served using https
mathjax_settings['message_style'] = 'normal' # This value controls the verbosity of the messages in the lower left-hand corner. Set it to "none" to eliminate all messages
mathjax_settings['macros'] = '{}'

# Source for MathJax
mathjax_settings['source'] = "'//cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML'"
Expand Down Expand Up @@ -192,8 +193,83 @@ def process_settings(pelicanobj):

mathjax_settings[key] = value

if key == 'macros':
text_lines = []
macros = parse_tex_macro(*value)
for macro in macros:
if 'args' in macro.keys():
# number of arguments > 1
text_lines.append("{0}: ['{1}', {2}]".format(macro['name'], macro['definition'], macro['args']))
else:
text_lines.append("{0}: '{1}'".format(macro['name'], macro['definition']))
mathjax_settings[key] = '{' + ", ".join(text_lines) + '}'


return mathjax_settings

def parse_tex_macro(*args):
"""Returns a list of from input files.
Each argument has to be an absolute path to a file. TeX macro definitions
are read and each one is translated to a dictionary containing the name
without backslash and the definition; if arguments are present, their
number is added too.
If a macro is defined multiple times, a warning is printed to stdout.
The last definition is used.
Backslashes in the definition are added in order to ensure the proper
form in the final html page.
Example:
> [{'name': 'pd',
'definition': '\\\\\\\\frac{\\\\\\\\partial #1}{\\\\\\\\partial #2}',
'args': 2},
{'name': 'R', 'definition': '\\\\\\\\mathbb{R}'}]
"""
temp_macros = []
for arg in args:
with open(arg, 'rt') as input_file:
lines = input_file.read().splitlines()
for i, command in enumerate(lines):
splitted = command.split('{')
name_number = splitted[1].split('}')
name = name_number[0].strip('\\')
# for the definition, remove the last character from the last string which is }
# remember that strings are immutable objects in python
last_def_token = splitted[-1][:-1]
splitted_def = splitted[2:-1] + [last_def_token]
complete_def = '{'.join(splitted_def).replace('\\','\\\\\\\\')
final_command = {'line': i+1, 'file': arg, 'name': name, 'definition': complete_def}
if name_number[1]:
# the number of arguments is defined, therefore name_number[1] is not null string
args_number = name_number[1].lstrip('[').rstrip(']')
final_command['args'] = args_number
temp_macros.append(final_command)
names = []
for macro in temp_macros:
names.append(macro['name'])
import collections
seen = set()
duplicate_indices = [names.index(item) for item, count in collections.Counter(names).items() if count > 1]
if len(duplicate_indices) > 0:
duplicates = []
for i in duplicate_indices:
name = temp_macros[i]['name']
duplicate = {'name': name, 'where':[]}
for j in temp_macros:
if j['name'] == name:
duplicate['where'].append((j['line'], j['file']))
duplicates.append(duplicate)
exception_text = "WARNING: macros where defined more than once, the last definition is used\n"
for dup in duplicates:
exception_text += "Macro {} defined in\n".format(dup['name'].strip('\\'))
for place in dup['where']:
exception_text += "{}, line {}\n".format(place[1], place[0])
print(exception_text)
# remove line and file keys from temp_macros (added for debug in case of duplicates)
return [{k: v for k, v in elem.items() if k in ['name', 'definition', 'args']} for elem in temp_macros]

def process_summary(article):
"""Ensures summaries are not cut off. Also inserts
mathjax script so that math will be rendered"""
Expand Down
2 changes: 1 addition & 1 deletion mathjax_script_template
Expand Up @@ -18,7 +18,7 @@ if (!document.getElementById('mathjaxscript_pelican_#%@#$@#')) {{
mathjaxscript[(window.opera ? "innerHTML" : "text")] =
"MathJax.Hub.Config({{" +
" config: ['MMLorHTML.js']," +
" TeX: {{ extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'{tex_extensions}], equationNumbers: {{ autoNumber: 'AMS' }} }}," +
" TeX: {{ extensions: ['AMSmath.js','AMSsymbols.js','noErrors.js','noUndefined.js'{tex_extensions}], equationNumbers: {{ autoNumber: 'AMS' }}, Macros: {macros} }}," +
" jax: ['input/TeX','input/MathML','output/HTML-CSS']," +
" extensions: ['tex2jax.js','mml2jax.js','MathMenu.js','MathZoom.js']," +
" displayAlign: '"+ align +"'," +
Expand Down

0 comments on commit 2ad63c8

Please sign in to comment.