Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/nbconvert/filters/pandoc.py: 35%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

31 statements  

1""" 

2Convert between any two formats using pandoc, 

3and related filters 

4""" 

5 

6import os 

7 

8from pandocfilters import Image, applyJSONFilters # type:ignore[import-untyped] 

9 

10from nbconvert.utils.base import NbConvertBase 

11from nbconvert.utils.pandoc import pandoc 

12 

13__all__ = ["ConvertExplicitlyRelativePaths", "convert_pandoc"] 

14 

15 

16def convert_pandoc(source, from_format, to_format, extra_args=None): 

17 """Convert between any two formats using pandoc. 

18 

19 This function will raise an error if pandoc is not installed. 

20 Any error messages generated by pandoc are printed to stderr. 

21 

22 Parameters 

23 ---------- 

24 source : string 

25 Input string, assumed to be valid in from_format. 

26 from_format : string 

27 Pandoc format of source. 

28 to_format : string 

29 Pandoc format for output. 

30 

31 Returns 

32 ------- 

33 out : string 

34 Output as returned by pandoc. 

35 """ 

36 return pandoc(source, from_format, to_format, extra_args=extra_args) 

37 

38 

39# When converting to pdf, explicitly relative references 

40# like "./" and "../" doesn't work with TEXINPUTS. 

41# So we need to convert them to absolute paths. 

42# See https://github.com/jupyter/nbconvert/issues/1998 

43class ConvertExplicitlyRelativePaths(NbConvertBase): 

44 """A converter that handles relative path references.""" 

45 

46 def __init__(self, texinputs=None, **kwargs): 

47 """Initialize the converter.""" 

48 # texinputs should be the directory of the notebook file 

49 self.nb_dir = os.path.abspath(texinputs) if texinputs else "" 

50 self.ancestor_dirs = self.nb_dir.split("/") 

51 super().__init__(**kwargs) 

52 

53 def __call__(self, source): 

54 """Invoke the converter.""" 

55 # If this is not set for some reason, we can't do anything, 

56 if self.nb_dir: 

57 return applyJSONFilters([self.action], source) 

58 return source 

59 

60 def action(self, key, value, frmt, meta): 

61 """Perform the action.""" 

62 # Convert explicitly relative paths: 

63 # ./path -> path (This should be visible to the latex engine since TEXINPUTS already has .) 

64 # ../path -> /abs_path 

65 # assuming all relative references are at the start of a given path 

66 if key == "Image": 

67 # Image seems to have this composition, according to https://github.com/jgm/pandoc-types 

68 attr, caption, [filename, typedef] = value 

69 

70 if filename[:2] == "./": 

71 filename = filename[2:] 

72 elif filename[:3] == "../": 

73 n_up = 0 

74 while filename[:3] == "../": 

75 n_up += 1 

76 filename = filename[3:] 

77 ancestors = "/".join(self.ancestor_dirs[:-n_up]) + "/" 

78 filename = ancestors + filename 

79 return Image(attr, caption, [filename, typedef]) 

80 # If not image, return "no change" 

81 return None