| 1 |  |  | #!/usr/bin/env python | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  | """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  | Pandoc filter for adding tip in LaTeX | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  | """ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  | from panflute import * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  | import os | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  | try: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  |     FileNotFoundError | 
            
                                                                                                            
                            
            
                                    
            
            
                | 12 |  |  | except NameError: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 13 |  |  |     #py2 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 14 |  |  |     FileNotFoundError = IOError | 
            
                                                                                                            
                            
            
                                    
            
            
                | 15 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 16 |  |  | def add_latex(elem, latex): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 17 |  |  |     # Is it a Span or a Code? | 
            
                                                                                                            
                            
            
                                    
            
            
                | 18 |  |  |     if isinstance(elem, Span) or isinstance(elem, Code): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 19 |  |  |         return [RawInline(latex, 'tex'), elem] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 20 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 21 |  |  |     # It is a Div or a CodeBlock | 
            
                                                                                                            
                            
            
                                    
            
            
                | 22 |  |  |     else: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 23 |  |  |         return [RawBlock(latex, 'tex'), elem] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 24 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 25 |  |  | def tip(elem, doc): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 26 |  |  |     # Is it in the right format and is it a Span, Div? | 
            
                                                                                                            
                            
            
                                    
            
            
                | 27 |  |  |     if doc.format == 'latex' and elem.tag in ['Span', 'Div', 'Code', 'CodeBlock']: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 28 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 29 |  |  |         # Is there a latex-tip-icon attribute? | 
            
                                                                                                            
                            
            
                                    
            
            
                | 30 |  |  |         if 'latex-tip-icon' in elem.attributes: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 31 |  |  |             return add_latex(elem, latex_code(elem.attributes)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 32 |  |  |         else: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 33 |  |  |             # Get the classes | 
            
                                                                                                            
                            
            
                                    
            
            
                | 34 |  |  |             classes = set(elem.classes) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 35 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 36 |  |  |             # Loop on all fontsize definition | 
            
                                                                                                            
                            
            
                                    
            
            
                | 37 |  |  |             for definition in doc.defined: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 38 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 39 |  |  |                 # Are the classes correct? | 
            
                                                                                                            
                            
            
                                    
            
            
                | 40 |  |  |                 if classes >= definition['classes']: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 41 |  |  |                     return add_latex(elem, definition['latex']) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 42 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 43 |  |  | def prepare(doc): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 44 |  |  |     # Add getIconFont library to doc | 
            
                                                                                                            
                            
            
                                    
            
            
                | 45 |  |  |     import icon_font_to_png | 
            
                                                                                                            
                            
            
                                    
            
            
                | 46 |  |  |     dir = os.path.dirname(os.path.realpath(__file__)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 |  |  |     doc.getIconFont = icon_font_to_png.IconFont( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 48 |  |  |         dir + '/pandoc_latex_tip-data/font-awesome.css', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 49 |  |  |         dir + '/pandoc_latex_tip-data/fontawesome-webfont.ttf' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 50 |  |  |     ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 51 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 52 |  |  |     # Prepare the definitions | 
            
                                                                                                            
                            
            
                                    
            
            
                | 53 |  |  |     doc.defined = [] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 54 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 55 |  |  |     # Get the meta data | 
            
                                                                                                            
                            
            
                                    
            
            
                | 56 |  |  |     meta = doc.get_metadata('pandoc-latex-tip') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 57 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 58 |  |  |     if isinstance(meta, list): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 59 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 60 |  |  |         # Loop on all definitions | 
            
                                                                                                            
                            
            
                                    
            
            
                | 61 |  |  |         for definition in meta: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 62 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 63 |  |  |             # Verify the definition | 
            
                                                                                                            
                            
            
                                    
            
            
                | 64 |  |  |             if isinstance(definition, dict) and 'classes' in definition and isinstance(definition['classes'], list): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 65 |  |  |                 add_definition(doc, definition) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 66 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 67 |  |  | def finalize(doc): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 68 |  |  |     if 'header-includes' not in doc.metadata: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 69 |  |  |         doc.metadata['header-includes'] = [] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 70 |  |  |     doc.metadata['header-includes'].append(MetaInlines(RawInline('\\usepackage{graphicx,grffile}', 'tex'))) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 71 |  |  |     doc.metadata['header-includes'].append(MetaInlines(RawInline('\\usepackage{marginnote}', 'tex'))) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 72 |  |  |     doc.metadata['header-includes'].append(MetaInlines(RawInline('\\usepackage{etoolbox}', 'tex'))) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 73 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 74 |  |  | def latex_code(prefix, images): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 75 |  |  |     latex = [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 76 |  |  |         '{', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 77 |  |  |         '\\makeatletter', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 78 |  |  |         '\\patchcmd{\\@mn@margintest}{\\@tempswafalse}{\\@tempswatrue}{}{}', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 79 |  |  |         '\\patchcmd{\\@mn@margintest}{\\@tempswafalse}{\\@tempswatrue}{}{}', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 80 |  |  |         '\\makeatother', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 81 |  |  |         prefix, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 82 |  |  |         '\\marginnote{' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 83 |  |  |     ] + images + [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 84 |  |  |         '}[0pt]', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 85 |  |  |         '\\vspace{0cm}', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 86 |  |  |         '}', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 87 |  |  |     ] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 88 |  |  |     return ''.join(latex) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 89 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 90 |  |  | def get_icons(doc, definition): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 91 |  |  |     icons = [{'name': 'exclamation-circle', 'color': 'black'}] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 92 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 93 |  |  |     # Test the icons definition | 
            
                                                                                                            
                            
            
                                    
            
            
                | 94 |  |  |     if 'icons' in definition and isinstance(definition['icons'], list): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 95 |  |  |         icons = [] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 96 |  |  |         for icon in definition['icons']: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 97 |  |  |             if isinstance(icon, str) or isinstance(icon, unicode): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 98 |  |  |                 # Simple icon | 
            
                                                                                                            
                            
            
                                    
            
            
                | 99 |  |  |                 color = 'black' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 100 |  |  |                 name = icon | 
            
                                                                                                            
                            
            
                                    
            
            
                | 101 |  |  |             elif isinstance(icon, dict) and 'color' in icon and 'name' in icon: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 102 |  |  |                 # Complex icon with name and color | 
            
                                                                                                            
                            
            
                                    
            
            
                | 103 |  |  |                 color = str(icon['color']) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 104 |  |  |                 name = str(icon['name']) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 105 |  |  |             else: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 106 |  |  |                 # Bad formed icon | 
            
                                                                                                            
                            
            
                                    
            
            
                | 107 |  |  |                 debug('[WARNING] pandoc-latex-tip: Bad formed icon') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 108 |  |  |                 break | 
            
                                                                                                            
                            
            
                                    
            
            
                | 109 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 110 |  |  |             # Lower the color | 
            
                                                                                                            
                            
            
                                    
            
            
                | 111 |  |  |             lowerColor = color.lower() | 
            
                                                                                                            
                            
            
                                    
            
            
                | 112 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 113 |  |  |             # Convert the color to black if unexisting | 
            
                                                                                                            
                            
            
                                    
            
            
                | 114 |  |  |             from PIL import ImageColor | 
            
                                                                                                            
                            
            
                                    
            
            
                | 115 |  |  |             if lowerColor not in ImageColor.colormap: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 116 |  |  |                 debug('[WARNING] pandoc-latex-tip: ' + lowerColor + ' is not a correct color name; using black') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 117 |  |  |                 lowerColor = 'black' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 118 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 119 |  |  |             # Is the icon correct? | 
            
                                                                                                            
                            
            
                                    
            
            
                | 120 |  |  |             try: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 121 |  |  |                 if name in doc.getIconFont.css_icons: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 122 |  |  |                     icons.append({'name': name, 'color': lowerColor}) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 123 |  |  |                 else: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 124 |  |  |                     debug('[WARNING] pandoc-latex-tip: ' + name + ' is not a correct icon name') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 125 |  |  |             except FileNotFoundError: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 126 |  |  |                 debug('[WARNING] pandoc-latex-tip: error in accessing to icons definition') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 127 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 128 |  |  |     return icons | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 129 |  |  |  | 
            
                                                                        
                            
            
                                    
            
            
                | 130 |  |  | def get_prefix(definition): | 
            
                                                                        
                            
            
                                    
            
            
                | 131 |  |  |     if 'position' in definition: | 
            
                                                                        
                            
            
                                    
            
            
                | 132 |  |  |         if definition['position'] == 'right': | 
            
                                                                        
                            
            
                                    
            
            
                | 133 |  |  |             return '\\normalmarginpar' | 
            
                                                                        
                            
            
                                    
            
            
                | 134 |  |  |         elif definition['position'] == 'left': | 
            
                                                                        
                            
            
                                    
            
            
                | 135 |  |  |             return '\\reversemarginpar' | 
            
                                                                        
                            
            
                                    
            
            
                | 136 |  |  |         else: | 
            
                                                                        
                            
            
                                    
            
            
                | 137 |  |  |             debug('[WARNING] pandoc-latex-tip: ' + position + ' is not a correct position; using left') | 
            
                                                                        
                            
            
                                    
            
            
                | 138 |  |  |             return '\\reversemarginpar' | 
            
                                                                        
                            
            
                                    
            
            
                | 139 |  |  |     return '\\reversemarginpar' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 140 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 141 |  |  | def get_size(definition): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 142 |  |  |    # Get the size | 
            
                                                                                                            
                            
            
                                    
            
            
                | 143 |  |  |     size = '18' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 144 |  |  |     if 'size' in definition: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 145 |  |  |         try: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 146 |  |  |             intValue = int(definition['size']) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 147 |  |  |             if intValue > 0: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 148 |  |  |                 size = str(intValue) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 149 |  |  |             else: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 150 |  |  |                 debug('[WARNING] pandoc-latex-tip: size must be greater than 0; using ' + size) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 151 |  |  |         except ValueError: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 152 |  |  |             debug('[WARNING] pandoc-latex-tip: size must be a number; using ' + size) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 153 |  |  |     return size | 
            
                                                                                                            
                            
            
                                    
            
            
                | 154 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 155 |  |  | def get_images(icons, size): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 156 |  |  |     # Generate the LaTeX image code | 
            
                                                                                                            
                            
            
                                    
            
            
                | 157 |  |  |     images = [] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 158 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 159 |  |  |     for icon in icons: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 160 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 161 |  |  |         # Get the apps dirs | 
            
                                                                                                            
                            
            
                                    
            
            
                | 162 |  |  |         from pkg_resources import get_distribution | 
            
                                                                                                            
                            
            
                                    
            
            
                | 163 |  |  |         from appdirs import AppDirs | 
            
                                                                                                            
                            
            
                                    
            
            
                | 164 |  |  |         dirs = AppDirs('pandoc_latex_tip', version = get_distribution('pandoc_latex_tip').version) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 165 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 166 |  |  |         # Get the image from the App cache folder | 
            
                                                                                                            
                            
            
                                    
            
            
                | 167 |  |  |         image = dirs.user_cache_dir + '/' + icon['color'] + '/' + icon['name'] + '.png' | 
            
                                                                                                            
                            
            
                                    
            
            
                | 168 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 169 |  |  |         # Create the image if not existing in the cache | 
            
                                                                                                            
                            
            
                                    
            
            
                | 170 |  |  |         try: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 171 |  |  |             if not os.path.isfile(image): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 172 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 173 |  |  |                 # Create the image in the cache | 
            
                                                                                                            
                            
            
                                    
            
            
                | 174 |  |  |                 doc.getIconFont.export_icon( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 175 |  |  |                     icon['name'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 176 |  |  |                     size = 512, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 177 |  |  |                     color = icon['color'], | 
            
                                                                                                            
                            
            
                                    
            
            
                | 178 |  |  |                     export_dir = dirs.user_cache_dir + '/' + icon['color'] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 179 |  |  |                 ) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 180 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 181 |  |  |             # Add the LaTeX image | 
            
                                                                                                            
                            
            
                                    
            
            
                | 182 |  |  |             images.append('\\includegraphics[width=' + size + 'pt]{' + image + '}') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 183 |  |  |         except FileNotFoundError: | 
            
                                                                                                            
                            
            
                                    
            
            
                | 184 |  |  |             debug('[WARNING] pandoc-latex-tip: error in generating image') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 185 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 186 |  |  |     return images | 
            
                                                                                                            
                            
            
                                    
            
            
                | 187 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 188 |  |  | def add_definition(doc, definition): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 189 |  |  |     # Get the classes | 
            
                                                                                                            
                            
            
                                    
            
            
                | 190 |  |  |     classes = definition['classes'] | 
            
                                                                                                            
                            
            
                                    
            
            
                | 191 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 192 |  |  |     # Get the icons | 
            
                                                                                                            
                            
            
                                    
            
            
                | 193 |  |  |     icons = get_icons(doc, definition) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 194 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 195 |  |  |     # Add a definition if correct | 
            
                                                                                                            
                            
            
                                    
            
            
                | 196 |  |  |     if bool(classes) and bool(icons): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 197 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 198 |  |  |         # Get the images | 
            
                                                                                                            
                            
            
                                    
            
            
                | 199 |  |  |         images = get_images(icons, get_size(definition)) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 200 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 201 |  |  |         # Get the prefix | 
            
                                                                                                            
                            
            
                                    
            
            
                | 202 |  |  |         prefix = get_prefix(definition) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 203 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 204 |  |  |         doc.defined.append({'classes' : set(classes), 'latex': latex_code(prefix, images)}) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 205 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 206 |  |  | def main(doc = None): | 
            
                                                                                                            
                            
            
                                    
            
            
                | 207 |  |  |     run_filter(tip, prepare = prepare, finalize = finalize, doc = doc) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 208 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 209 |  |  | if __name__ == '__main__': | 
            
                                                                                                            
                            
            
                                    
            
            
                | 210 |  |  |     main() | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 211 |  |  |  | 
            
                                                        
            
                                    
            
            
                | 212 |  |  |  |