##// END OF EJS Templates
nbconvert.utils.pandoc:...
Daniel B. Vasquez -
Show More
@@ -0,0 +1,65 b''
1 """Test Pandoc module"""
2
3 #-----------------------------------------------------------------------------
4 # Copyright (C) 2013 The IPython Development Team
5 #
6 # Distributed under the terms of the BSD License. The full license is in
7 # the file COPYING, distributed as part of this software.
8 #-----------------------------------------------------------------------------
9
10 #-----------------------------------------------------------------------------
11 # Imports
12 #-----------------------------------------------------------------------------
13
14 import os
15
16 from .base import TestsBase
17 from ..utils import pandoc
18
19 from IPython.testing import decorators as dec
20
21 #-----------------------------------------------------------------------------
22 # Constants
23 #-----------------------------------------------------------------------------
24
25
26 #-----------------------------------------------------------------------------
27 # Classes and functions
28 #-----------------------------------------------------------------------------
29
30 class TestPandoc(TestsBase):
31 """Collection of Pandoc tests"""
32
33 def __init__(self, *args, **kwargs):
34 super(TestPandoc, self).__init__(*args, **kwargs)
35 self.original_env = os.environ.copy()
36
37 @dec.onlyif_cmds_exist('pandoc')
38 def test_pandoc_available(self):
39 """ Test behaviour of pandoc_available() """
40 os.environ["PATH"] = ""
41 assert not pandoc.pandoc_available()
42 try:
43 pandoc.pandoc_available(failmode="raise")
44 except pandoc.PandocMissing:
45 assert True
46
47 os.environ["PATH"] = self.original_env["PATH"]
48 assert pandoc.pandoc_available()
49 try:
50 pandoc.pandoc_available(failmode="raise")
51 except pandoc.PandocMissing:
52 assert False
53
54 @dec.onlyif_cmds_exist('pandoc')
55 def test_minimal_version(self):
56 original_minversion = pandoc.minimal_version
57
58 pandoc.minimal_version = "120.0"
59 assert not pandoc.check_pandoc_version()
60
61 pandoc.minimal_version = pandoc.get_pandoc_version()
62 assert pandoc.check_pandoc_version()
63
64
65
@@ -22,6 +22,7 b' from io import TextIOWrapper, BytesIO'
22 # IPython imports
22 # IPython imports
23 from IPython.utils.py3compat import cast_bytes
23 from IPython.utils.py3compat import cast_bytes
24 from IPython.utils.version import check_version
24 from IPython.utils.version import check_version
25 from IPython.utils.process import find_cmd, FindCmdError
25
26
26
27
27 from .exceptions import ConversionException
28 from .exceptions import ConversionException
@@ -33,14 +34,25 b' from .exceptions import ConversionException'
33 # module root level so that the import of this module is not fatal.
34 # module root level so that the import of this module is not fatal.
34 #----------------------------------------------------------------------------
35 #----------------------------------------------------------------------------
35
36
37 # command line to make pandoc print it's version. It is also the
38 # easiest way to make pandoc return at all.
39 __pandoc_version_call = ['pandoc', '-v']
40
36 class PandocMissing(ConversionException):
41 class PandocMissing(ConversionException):
37 """Exception raised when Pandoc is missing. """
42 """Exception raised when Pandoc is missing. """
38 def __init__(self, cmd, exc, *args, **kwargs):
43 def __init__(self, cmd, exc, *args, **kwargs):
39 super(PandocMissing, self).__init__( "The command '%s' returned an error: %s.\n" %(" ".join(cmd), exc) +
44 super(PandocMissing, self).__init__( "The command '%s' returned an error: %s.\n" %(" ".join(cmd), exc) +
40 "Please check that pandoc is installed:\n" +
45 "Please check that pandoc is installed:\n" +
41 "http://johnmacfarlane.net/pandoc/installing.html" )
46 "http://johnmacfarlane.net/pandoc/installing.html" )
47 self.exc = exc
48
49 def __bool__(self):
50 return False
51
52 __nonzero__ = __bool__
53
42
54
43 def pandoc_available(failmode="return", warn=False, alt=None):
55 def pandoc_available(failmode="return", warn=False):
44 """Is pandoc available. Only tries to call Pandoc
56 """Is pandoc available. Only tries to call Pandoc
45 and inform you that it succeeded or failed.
57 and inform you that it succeeded or failed.
46
58
@@ -52,49 +64,57 b' def pandoc_available(failmode="return", warn=False, alt=None):'
52 the exception returned by subprocess.check_call.
64 the exception returned by subprocess.check_call.
53 - warn : bool
65 - warn : bool
54 issue a user warning if pandoc is not available.
66 issue a user warning if pandoc is not available.
55 - alt: list of strings
56 command to print in the error (not used as actual call)
57
67
58 Return
68 Return
59 ------
69 ------
60 out : (Bool, Exception)
70 out : (Bool, Exception)
61 On success will return (True, None). On failure and failmode=="return"
71 On success will return True. On failure and failmode=="return"
62 will return (False, OSError instance)
72 will return False-valued PandocMissing instance
63 """
73 """
64
74
65 cmd = ["pandoc", "-v"]
66
67 try:
75 try:
68 out = subprocess.check_output(cmd, universal_newlines=True)
76 find_cmd("pandoc")
69 return True, None
77 return True
70 except OSError as e:
78 except FindCmdError as e:
71 if warn:
79 if warn:
72 warnings.warn(
80 warnings.warn(
73 "Pandoc cannot be found (calling %s failed).\n" % " ".join(alt or cmd) +
81 "Pandoc cannot be found (calling %s failed).\n" % " ".join(alt or __pandoc_version_call) +
74 "Please check that pandoc is installed:\n" +
82 "Please check that pandoc is installed:\n" +
75 "http://johnmacfarlane.net/pandoc/installing.html"
83 "http://johnmacfarlane.net/pandoc/installing.html"
76 )
84 )
77
85
86 exc = PandocMissing("pandoc", e)
78 if failmode == "return":
87 if failmode == "return":
79 return False, e
88 return exc
80 else:
89 else:
81 raise PandocMissing(alt or cmd, e)
90 raise exc
82
91
83
92
84 #-----------------------------------------------------------------------------
93 #-----------------------------------------------------------------------------
85 # Classes and functions
94 # Classes and functions
86 #-----------------------------------------------------------------------------
95 #-----------------------------------------------------------------------------
96 minimal_version = "1.12.1"
87
97
98 # The following holds cached values about the pandoc executable.
99 def clean_cache(new=False):
100 if new:
101 global __cache
102 cache = {}
103 __cache = cache
104 else:
105 cache = __cache
106 cache.clear()
107
108 cache['version_ok'] = False
109 cache['version'] = None
110 return cache
111
112 __cache = clean_cache(new=True)
88
113
89 minimal_version = "1.12.1"
90 minimal_version_ok = False
91
114
92 def pandoc(source, fmt, to, extra_args=None, encoding='utf-8'):
115 def pandoc(source, fmt, to, extra_args=None, encoding='utf-8'):
93 """Convert an input string in format `from` to format `to` via pandoc.
116 """Convert an input string in format `from` to format `to` via pandoc.
94
117
95 This function will raise PandocMissing if pandoc is not installed.
96 Any error messages generated by pandoc are printed to stderr.
97
98 Parameters
118 Parameters
99 ----------
119 ----------
100 source : string
120 source : string
@@ -108,6 +128,12 b" def pandoc(source, fmt, to, extra_args=None, encoding='utf-8'):"
108 -------
128 -------
109 out : unicode
129 out : unicode
110 Output as returned by pandoc.
130 Output as returned by pandoc.
131
132 Exceptions
133 ----------
134 This function will raise PandocMissing if pandoc is not installed.
135 Any error messages generated by pandoc are printed to stderr.
136
111 """
137 """
112 cmd = ['pandoc', '-f', fmt, '-t', to]
138 cmd = ['pandoc', '-f', fmt, '-t', to]
113 if extra_args:
139 if extra_args:
@@ -125,32 +151,43 b" def pandoc(source, fmt, to, extra_args=None, encoding='utf-8'):"
125
151
126 def get_pandoc_version():
152 def get_pandoc_version():
127 """Gets the Pandoc version if Pandoc is installed.
153 """Gets the Pandoc version if Pandoc is installed.
154
155 Return
156 ------
157 If the minimal version is not met, it will probe Pandoc for its version, cache it and return that value.
158 If the minimal version is met, it will return the cached version and stop probing Pandoc
159 (unless `clean_cache()` is called).
160
161 Exceptions
162 ----------
128 PandocMissing will be raised if pandoc is unavailable.
163 PandocMissing will be raised if pandoc is unavailable.
129 """
164 """
130 try:
165
131 if not minimal_version_ok:
166 if __cache['version_ok'] and __cache['version']:
132 raise AttributeError()
167 return __cache['version']
133 else:
168 else:
134 return pandoc.version
169 pandoc_available(failmode="raise")
135 except AttributeError:
170 out = subprocess.check_output(__pandoc_version_call, universal_newlines=True)
136 # if pandoc is missing let the exception bubble us out of here
137 pandoc_available(failmode="raise")
138 cmd = ["pandoc", "-v"]
139 out = subprocess.check_output(cmd, universal_newlines=True)
140 pv_re = re.compile(r'(\d{0,3}\.\d{0,3}\.\d{0,3})')
171 pv_re = re.compile(r'(\d{0,3}\.\d{0,3}\.\d{0,3})')
141 pandoc.version = pv_re.search(out).group(0)
172 __cache['version'] = version = pv_re.search(out).group(0)
142 return pandoc.version
173 return version
174
143
175
144 def check_pandoc_version():
176 def check_pandoc_version():
145 """Returns True if minimal pandoc version is met.
177 """Returns True if minimal pandoc version is met.
178
179 Exceptions
180 ----------
146 PandocMissing will be raised if pandoc is unavailable.
181 PandocMissing will be raised if pandoc is unavailable.
147 """
182 """
148 global minimal_version_ok
183 ok = __cache['version_ok']
149 if not minimal_version_ok:
184 if not ok:
150 minimal_version_ok = check_version( get_pandoc_version(), minimal_version )
185 __cache['version_ok'] = ok = check_version( get_pandoc_version(), minimal_version )
151 if not minimal_version_ok:
186 if not ok:
152 warnings.warn( "You are using an old version of pandoc (%s)\n" % pandoc.version +
187 warnings.warn( "You are using an old version of pandoc (%s)\n" % __cache['version'] +
153 "Recommended version is %s.\nTry updating." % minimal_version +
188 "Recommended version is %s.\nTry updating." % minimal_version +
154 "http://johnmacfarlane.net/pandoc/installing.html.\nContinuing with doubts...",
189 "http://johnmacfarlane.net/pandoc/installing.html.\nContinuing with doubts...",
155 RuntimeWarning, stacklevel=2)
190 RuntimeWarning, stacklevel=2)
156 return minimal_version_ok
191 return __cache['version_ok']
192
193
General Comments 0
You need to be logged in to leave comments. Login now