##// END OF EJS Templates
Merge pull request #4680 from dbarbeau/minimal-pandoc...
Jonathan Frederic -
r14882:d0c65777 merge
parent child Browse files
Show More
1 NO CONTENT: new file 100644
NO CONTENT: new file 100644
@@ -0,0 +1,62 b''
1 """Test Pandoc module"""
2 #-----------------------------------------------------------------------------
3 # Copyright (C) 2014 The IPython Development Team
4 #
5 # Distributed under the terms of the BSD License. The full license is in
6 # the file COPYING, distributed as part of this software.
7 #-----------------------------------------------------------------------------
8
9 #-----------------------------------------------------------------------------
10 # Imports
11 #-----------------------------------------------------------------------------
12 import os
13
14 from IPython.testing import decorators as dec
15
16 from IPython.nbconvert.tests.base import TestsBase
17 from .. import pandoc
18
19 #-----------------------------------------------------------------------------
20 # Classes and functions
21 #-----------------------------------------------------------------------------
22 class TestPandoc(TestsBase):
23 """Collection of Pandoc tests"""
24
25 def __init__(self, *args, **kwargs):
26 super(TestPandoc, self).__init__(*args, **kwargs)
27 self.original_env = os.environ.copy()
28
29 @dec.onlyif_cmds_exist('pandoc')
30 def test_pandoc_available(self):
31 """ Test behaviour that pandoc functions raise PandocMissing as documented """
32 pandoc.clean_cache()
33
34 os.environ["PATH"] = ""
35 assert pandoc_function_raised_missing(pandoc.get_pandoc_version) == True
36 assert pandoc_function_raised_missing(pandoc.check_pandoc_version) == True
37 assert pandoc_function_raised_missing(pandoc.pandoc, "", "markdown", "html") == True
38
39 # original_env["PATH"] should contain pandoc
40 os.environ["PATH"] = self.original_env["PATH"]
41 assert pandoc_function_raised_missing(pandoc.get_pandoc_version) == False
42 assert pandoc_function_raised_missing(pandoc.check_pandoc_version) == False
43 assert pandoc_function_raised_missing(pandoc.pandoc, "", "markdown", "html") == False
44
45 @dec.onlyif_cmds_exist('pandoc')
46 def test_minimal_version(self):
47 original_minversion = pandoc._minimal_version
48
49 pandoc._minimal_version = "120.0"
50 assert not pandoc.check_pandoc_version()
51
52 pandoc._minimal_version = pandoc.get_pandoc_version()
53 assert pandoc.check_pandoc_version()
54
55
56 def pandoc_function_raised_missing(f, *args, **kwargs):
57 try:
58 f(*args, **kwargs)
59 except pandoc.PandocMissing:
60 return True
61 else:
62 return False
@@ -0,0 +1,3 b''
1 * PandocMissing exceptions will be raised if Pandoc is unavailable
2 * Recommended Pandoc version for use with nbconvert is 1.12.1
3 * warnings will be printed if the version is not good.
@@ -1,6 +1,6 b''
1 """Utility for calling pandoc"""
1 """Utility for calling pandoc"""
2 #-----------------------------------------------------------------------------
2 #-----------------------------------------------------------------------------
3 # Copyright (c) 2013 the IPython Development Team.
3 # Copyright (c) 2014 the IPython Development Team.
4 #
4 #
5 # Distributed under the terms of the Modified BSD License.
5 # Distributed under the terms of the Modified BSD License.
6 #
6 #
@@ -10,33 +10,29 b''
10 #-----------------------------------------------------------------------------
10 #-----------------------------------------------------------------------------
11 # Imports
11 # Imports
12 #-----------------------------------------------------------------------------
12 #-----------------------------------------------------------------------------
13
14 from __future__ import print_function
13 from __future__ import print_function
15
14
16 # Stdlib imports
15 # Stdlib imports
17 import subprocess
16 import subprocess
17 import re
18 import warnings
18 from io import TextIOWrapper, BytesIO
19 from io import TextIOWrapper, BytesIO
19
20
20 # IPython imports
21 # IPython imports
21 from IPython.utils.py3compat import cast_bytes
22 from IPython.utils.py3compat import cast_bytes
23 from IPython.utils.version import check_version
24 from IPython.utils.process import is_cmd_found, FindCmdError
22
25
23 from .exceptions import ConversionException
26 from .exceptions import ConversionException
24
27
25 #-----------------------------------------------------------------------------
28 #-----------------------------------------------------------------------------
26 # Classes and functions
29 # Classes and functions
27 #-----------------------------------------------------------------------------
30 #-----------------------------------------------------------------------------
28
31 _minimal_version = "1.12.1"
29 class PandocMissing(ConversionException):
30 """Exception raised when Pandoc is missing. """
31 pass
32
33
32
34 def pandoc(source, fmt, to, extra_args=None, encoding='utf-8'):
33 def pandoc(source, fmt, to, extra_args=None, encoding='utf-8'):
35 """Convert an input string in format `from` to format `to` via pandoc.
34 """Convert an input string in format `from` to format `to` via pandoc.
36
35
37 This function will raise an error if pandoc is not installed.
38 Any error messages generated by pandoc are printed to stderr.
39
40 Parameters
36 Parameters
41 ----------
37 ----------
42 source : string
38 source : string
@@ -50,21 +46,83 b" def pandoc(source, fmt, to, extra_args=None, encoding='utf-8'):"
50 -------
46 -------
51 out : unicode
47 out : unicode
52 Output as returned by pandoc.
48 Output as returned by pandoc.
49
50 Exceptions
51 ----------
52 This function will raise PandocMissing if pandoc is not installed.
53 Any error messages generated by pandoc are printed to stderr.
54
53 """
55 """
54 command = ['pandoc', '-f', fmt, '-t', to]
56 cmd = ['pandoc', '-f', fmt, '-t', to]
55 if extra_args:
57 if extra_args:
56 command.extend(extra_args)
58 cmd.extend(extra_args)
57 try:
59
58 p = subprocess.Popen(command,
60 # this will raise an exception that will pop us out of here
59 stdin=subprocess.PIPE, stdout=subprocess.PIPE
61 check_pandoc_version()
60 )
62
61 except OSError as e:
63 # we can safely continue
62 raise PandocMissing(
64 p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
63 "The command '%s' returned an error: %s.\n" %(" ".join(command), e) +
64 "Please check that pandoc is installed:\n" +
65 "http://johnmacfarlane.net/pandoc/installing.html"
66 )
67 out, _ = p.communicate(cast_bytes(source, encoding))
65 out, _ = p.communicate(cast_bytes(source, encoding))
68 out = TextIOWrapper(BytesIO(out), encoding, 'replace').read()
66 out = TextIOWrapper(BytesIO(out), encoding, 'replace').read()
69 return out.rstrip('\n')
67 return out.rstrip('\n')
70
68
69
70 def get_pandoc_version():
71 """Gets the Pandoc version if Pandoc is installed.
72
73 Return
74 ------
75 If the minimal version is not met, it will probe Pandoc for its version, cache it and return that value.
76 If the minimal version is met, it will return the cached version and stop probing Pandoc
77 (unless `clean_cache()` is called).
78
79 Exceptions
80 ----------
81 PandocMissing will be raised if pandoc is unavailable.
82 """
83 global __version
84
85 if __version is None:
86 if not is_cmd_found('pandoc'):
87 raise PandocMissing()
88
89 out = subprocess.check_output( ['pandoc', '-v'], universal_newlines=True)
90 pv_re = re.compile(r'(\d{0,3}\.\d{0,3}\.\d{0,3})')
91 __version = pv_re.search(out).group(0)
92 return __version
93
94
95 def check_pandoc_version():
96 """Returns True if minimal pandoc version is met.
97
98 Exceptions
99 ----------
100 PandocMissing will be raised if pandoc is unavailable.
101 """
102 v = get_pandoc_version()
103 ok = check_version(v , _minimal_version )
104 if not ok:
105 warnings.warn( "You are using an old version of pandoc (%s)\n" % v +
106 "Recommended version is %s.\nTry updating." % _minimal_version +
107 "http://johnmacfarlane.net/pandoc/installing.html.\nContinuing with doubts...",
108 RuntimeWarning, stacklevel=2)
109 return ok
110
111 #-----------------------------------------------------------------------------
112 # Exception handling
113 #-----------------------------------------------------------------------------
114 class PandocMissing(ConversionException):
115 """Exception raised when Pandoc is missing. """
116 def __init__(self, *args, **kwargs):
117 super(PandocMissing, self).__init__( "Pandoc wasn't found.\n" +
118 "Please check that pandoc is installed:\n" +
119 "http://johnmacfarlane.net/pandoc/installing.html" )
120
121 #-----------------------------------------------------------------------------
122 # Internal state management
123 #-----------------------------------------------------------------------------
124 def clean_cache():
125 global __version
126 __version = None
127
128 __version = None
General Comments 0
You need to be logged in to leave comments. Login now