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