##// END OF EJS Templates
make automatic __doc__ inheritance...
Paul Ivanov -
Show More
@@ -23,6 +23,7 b' import subprocess'
23 23 import sys
24 24 import json
25 25 import copy
26 from types import FunctionType
26 27 from shutil import rmtree
27 28 from markdown import markdown
28 29
@@ -40,7 +41,6 b' from IPython.nbformat.v3.nbjson import BytesEncoder'
40 41 from IPython.utils import path, py3compat
41 42
42 43 # local
43 from decorators import DocInherit
44 44 from lexers import IPythonLexer
45 45
46 46
@@ -48,9 +48,6 b' from lexers import IPythonLexer'
48 48 # Utility functions
49 49 #-----------------------------------------------------------------------------
50 50
51 def DocInherit(f):
52 return f
53
54 51 def remove_fake_files_url(cell):
55 52 """Remove from the cell source the /files/ pseudo-path we use.
56 53 """
@@ -233,8 +230,37 b' def coalesce_streams(outputs):'
233 230 class ConversionException(Exception):
234 231 pass
235 232
233 class DocStringInheritor(type):
234 """
235 This metaclass will walk the list of bases until the desired
236 superclass method is found AND if that method has a docstring and only
237 THEN does it attach the superdocstring to the derived class method.
238
239 Please use carefully, I just did the metaclass thing by following
240 Michael Foord's Metaclass tutorial
241 (http://www.voidspace.org.uk/python/articles/metaclasses.shtml), I may
242 have missed a step or two.
243
244 source:
245 http://groups.google.com/group/comp.lang.python/msg/26f7b4fcb4d66c95
246 by Paul McGuire
247 """
248 def __new__(meta, classname, bases, classDict):
249 newClassDict = {}
250 for attributeName, attribute in classDict.items():
251 if type(attribute) == FunctionType:
252 # look through bases for matching function by name
253 for baseclass in bases:
254 if hasattr(baseclass, attributeName):
255 basefn = getattr(baseclass,attributeName)
256 if basefn.__doc__:
257 attribute.__doc__ = basefn.__doc__
258 break
259 newClassDict[attributeName] = attribute
260 return type.__new__(meta, classname, bases, newClassDict)
236 261
237 262 class Converter(object):
263 __metaclass__ = DocStringInheritor
238 264 default_encoding = 'utf-8'
239 265 extension = str()
240 266 figures_counter = 0
@@ -505,12 +531,10 b' class ConverterRST(Converter):'
505 531 extension = 'rst'
506 532 heading_level = {1: '=', 2: '-', 3: '`', 4: '\'', 5: '.', 6: '~'}
507 533
508 @DocInherit
509 534 def render_heading(self, cell):
510 535 marker = self.heading_level[cell.level]
511 536 return ['{0}\n{1}\n'.format(cell.source, marker * len(cell.source))]
512 537
513 @DocInherit
514 538 def render_code(self, cell):
515 539 if not cell.input:
516 540 return []
@@ -524,19 +548,16 b' class ConverterRST(Converter):'
524 548
525 549 return lines
526 550
527 @DocInherit
528 551 def render_markdown(self, cell):
529 552 #return [cell.source]
530 553 return [markdown2rst(cell.source)]
531 554
532 @DocInherit
533 555 def render_raw(self, cell):
534 556 if self.raw_as_verbatim:
535 557 return ['::', '', indent(cell.source), '']
536 558 else:
537 559 return [cell.source]
538 560
539 @DocInherit
540 561 def render_pyout(self, output):
541 562 lines = ['Out[%s]:' % output.prompt_number, '']
542 563
@@ -549,37 +570,29 b' class ConverterRST(Converter):'
549 570
550 571 return lines
551 572
552 @DocInherit
553 573 def render_pyerr(self, output):
554 574 # Note: a traceback is a *list* of frames.
555 575 return ['::', '', indent(remove_ansi('\n'.join(output.traceback))), '']
556 576
557 @DocInherit
558 577 def _img_lines(self, img_file):
559 578 return ['.. image:: %s' % img_file, '']
560 579
561 @DocInherit
562 580 def render_display_format_text(self, output):
563 581 return rst_directive('.. parsed-literal::', output.text)
564 582
565 @DocInherit
566 583 def _unknown_lines(self, data):
567 584 return rst_directive('.. warning:: Unknown cell') + [data]
568 585
569 @DocInherit
570 586 def render_display_format_html(self, output):
571 587 return rst_directive('.. raw:: html', output.html)
572 588
573 @DocInherit
574 589 def render_display_format_latex(self, output):
575 590 return rst_directive('.. math::', output.latex)
576 591
577 @DocInherit
578 592 def render_display_format_json(self, output):
579 593 return rst_directive('.. raw:: json', output.json)
580 594
581 595
582 @DocInherit
583 596 def render_display_format_javascript(self, output):
584 597 return rst_directive('.. raw:: javascript', output.javascript)
585 598
@@ -611,11 +624,9 b' class ConverterMarkdown(Converter):'
611 624 self.show_prompts = show_prompts
612 625 self.inline_prompt = inline_prompt
613 626
614 @DocInherit
615 627 def render_heading(self, cell):
616 628 return ['{0} {1}'.format('#'*cell.level, cell.source), '']
617 629
618 @DocInherit
619 630 def render_code(self, cell):
620 631 if not cell.input:
621 632 return []
@@ -640,18 +651,15 b' class ConverterMarkdown(Converter):'
640 651 lines.append('')
641 652 return lines
642 653
643 @DocInherit
644 654 def render_markdown(self, cell):
645 655 return [cell.source, '']
646 656
647 @DocInherit
648 657 def render_raw(self, cell):
649 658 if self.raw_as_verbatim:
650 659 return [indent(cell.source), '']
651 660 else:
652 661 return [cell.source, '']
653 662
654 @DocInherit
655 663 def render_pyout(self, output):
656 664 lines = []
657 665
@@ -668,45 +676,32 b' class ConverterMarkdown(Converter):'
668 676 lines.append('')
669 677 return lines
670 678
671 @DocInherit
672 679 def render_pyerr(self, output):
673 680 # Note: a traceback is a *list* of frames.
674 681 return [indent(remove_ansi('\n'.join(output.traceback))), '']
675 682
676 @DocInherit
677 683 def _img_lines(self, img_file):
678 684 return ['', '![](%s)' % img_file, '']
679 685
680 @DocInherit
681 686 def render_display_format_text(self, output):
682 687 return [indent(output.text)]
683 688
684 @DocInherit
685 689 def _unknown_lines(self, data):
686 690 return ['Warning: Unknown cell', data]
687 691
688 @DocInherit
689 692 def render_display_format_html(self, output):
690 693 return [output.html]
691 694
692 @DocInherit
693 695 def render_display_format_latex(self, output):
694 696 return ['LaTeX::', indent(output.latex)]
695 697
696 @DocInherit
697 698 def render_display_format_json(self, output):
698 699 return ['JSON:', indent(output.json)]
699 700
700 @DocInherit
701 701 def render_display_format_javascript(self, output):
702 702 return ['JavaScript:', indent(output.javascript)]
703 703
704 704
705 def return_list(x):
706 """Ensure that x is returned as a list or inside one"""
707 return x if isinstance(x, list) else [x]
708
709
710 705 # decorators for HTML output
711 706 def output_container(f):
712 707 """add a prompt-area next to an output"""
@@ -811,13 +806,11 b' class ConverterHTML(Converter):'
811 806 def optional_footer(self):
812 807 return ['</body>', '</html>']
813 808
814 @DocInherit
815 809 @text_cell
816 810 def render_heading(self, cell):
817 811 marker = cell.level
818 812 return [u'<h{1}>\n {0}\n</h{1}>'.format(cell.source, marker)]
819 813
820 @DocInherit
821 814 def render_code(self, cell):
822 815 if not cell.input:
823 816 return []
@@ -847,19 +840,16 b' class ConverterHTML(Converter):'
847 840
848 841 return lines
849 842
850 @DocInherit
851 843 @text_cell
852 844 def render_markdown(self, cell):
853 845 return [markdown(cell.source)]
854 846
855 @DocInherit
856 847 def render_raw(self, cell):
857 848 if self.raw_as_verbatim:
858 849 return self.in_tag('pre', cell.source)
859 850 else:
860 851 return [cell.source]
861 852
862 @DocInherit
863 853 @output_container
864 854 def render_pyout(self, output):
865 855 for fmt in ['html', 'latex', 'png', 'jpeg', 'svg', 'text']:
@@ -870,13 +860,11 b' class ConverterHTML(Converter):'
870 860
871 861 render_display_data = render_pyout
872 862
873 @DocInherit
874 863 @output_container
875 864 def render_stream(self, output):
876 865 return self._ansi_colored(output.text)
877 866
878 867
879 @DocInherit
880 868 @output_container
881 869 def render_pyerr(self, output):
882 870 # Note: a traceback is a *list* of frames.
@@ -885,46 +873,36 b' class ConverterHTML(Converter):'
885 873 # stb =
886 874 return self._ansi_colored('\n'.join(output.traceback))
887 875
888 @DocInherit
889 876 def _img_lines(self, img_file):
890 877 return ['<img src="%s">' % img_file, '</img>']
891 878
892 @DocInherit
893 879 def _unknown_lines(self, data):
894 880 return ['<h2>Warning:: Unknown cell</h2>'] + self.in_tag('pre', data)
895 881
896 882
897 @DocInherit
898 883 def render_display_format_png(self, output):
899 884 return ['<img src="data:image/png;base64,%s"></img>' % output.png]
900 885
901 @DocInherit
902 886 def render_display_format_svg(self, output):
903 887 return [output.svg]
904 888
905 @DocInherit
906 889 def render_display_format_jpeg(self, output):
907 890 return ['<img src="data:image/jpeg;base64,%s"></img>' % output.jpeg]
908 891
909 @DocInherit
910 892 def render_display_format_text(self, output):
911 893 return self._ansi_colored(output.text)
912 894
913 @DocInherit
914 895 def render_display_format_html(self, output):
915 896 return [output.html]
916 897
917 @DocInherit
918 898 def render_display_format_latex(self, output):
919 899 return [output.latex]
920 900
921 @DocInherit
922 901 def render_display_format_json(self, output):
923 902 # html ignores json
924 903 return []
925 904
926 905
927 @DocInherit
928 906 def render_display_format_javascript(self, output):
929 907 return [output.javascript]
930 908
@@ -947,7 +925,6 b' class ConverterBloggerHTML(ConverterHTML):'
947 925 def optional_footer(self):
948 926 return []
949 927
950
951 928 class ConverterLaTeX(Converter):
952 929 """Converts a notebook to a .tex file suitable for pdflatex.
953 930
@@ -1033,12 +1010,10 b' class ConverterLaTeX(Converter):'
1033 1010 # Retun value must be a string
1034 1011 return '\n'.join(final)
1035 1012
1036 @DocInherit
1037 1013 def render_heading(self, cell):
1038 1014 marker = self.heading_map[cell.level]
1039 1015 return ['%s{%s}' % (marker, cell.source) ]
1040 1016
1041 @DocInherit
1042 1017 def render_code(self, cell):
1043 1018 if not cell.input:
1044 1019 return []
@@ -1063,7 +1038,6 b' class ConverterLaTeX(Converter):'
1063 1038 return lines
1064 1039
1065 1040
1066 @DocInherit
1067 1041 def _img_lines(self, img_file):
1068 1042 return self.in_env('center',
1069 1043 [r'\includegraphics[width=6in]{%s}' % img_file, r'\par'])
@@ -1075,11 +1049,9 b' class ConverterLaTeX(Converter):'
1075 1049 img_file])
1076 1050 return self._img_lines(pdf_file)
1077 1051
1078 @DocInherit
1079 1052 def render_markdown(self, cell):
1080 1053 return [markdown2latex(cell.source)]
1081 1054
1082 @DocInherit
1083 1055 def render_pyout(self, output):
1084 1056 lines = []
1085 1057
@@ -1092,27 +1064,23 b' class ConverterLaTeX(Converter):'
1092 1064
1093 1065 return lines
1094 1066
1095 @DocInherit
1096 1067 def render_pyerr(self, output):
1097 1068 # Note: a traceback is a *list* of frames.
1098 1069 return self.in_env('traceback',
1099 1070 self.in_env('verbatim',
1100 1071 remove_ansi('\n'.join(output.traceback))))
1101 1072
1102 @DocInherit
1103 1073 def render_raw(self, cell):
1104 1074 if self.raw_as_verbatim:
1105 1075 return self.in_env('verbatim', cell.source)
1106 1076 else:
1107 1077 return [cell.source]
1108 1078
1109 @DocInherit
1110 1079 def _unknown_lines(self, data):
1111 1080 return [r'{\vspace{5mm}\bf WARNING:: unknown cell:}'] + \
1112 1081 self.in_env('verbatim', data)
1113 1082
1114 1083
1115 @DocInherit
1116 1084 def render_display_format_text(self, output):
1117 1085 lines = []
1118 1086
@@ -1121,27 +1089,24 b' class ConverterLaTeX(Converter):'
1121 1089
1122 1090 return lines
1123 1091
1124 @DocInherit
1125 1092 def render_display_format_html(self, output):
1126 1093 return []
1127 1094
1128 @DocInherit
1129 1095 def render_display_format_latex(self, output):
1130 1096 if type(output.latex) == type([]):
1131 1097 return output.latex
1132 1098 return [output.latex]
1133 1099
1134 @DocInherit
1135 1100 def render_display_format_json(self, output):
1136 1101 # latex ignores json
1137 1102 return []
1138 1103
1139 1104
1140 @DocInherit
1141 1105 def render_display_format_javascript(self, output):
1142 1106 # latex ignores javascript
1143 1107 return []
1144 1108
1109
1145 1110 class ConverterNotebook(Converter):
1146 1111 """
1147 1112 A converter that is essentially a null-op.
@@ -1186,48 +1151,37 b' class ConverterNotebook(Converter):'
1186 1151 }"""
1187 1152 return s.split('\n')
1188 1153
1189 @DocInherit
1190 1154 def render_heading(self, cell):
1191 1155 return cell_to_lines(cell)
1192 1156
1193 @DocInherit
1194 1157 def render_code(self, cell):
1195 1158 return cell_to_lines(cell)
1196 1159
1197 @DocInherit
1198 1160 def render_markdown(self, cell):
1199 1161 return cell_to_lines(cell)
1200 1162
1201 @DocInherit
1202 1163 def render_raw(self, cell):
1203 1164 return cell_to_lines(cell)
1204 1165
1205 @DocInherit
1206 1166 def render_pyout(self, output):
1207 1167 return cell_to_lines(output)
1208 1168
1209 @DocInherit
1210 1169 def render_pyerr(self, output):
1211 1170 return cell_to_lines(output)
1212 1171
1213 @DocInherit
1214 1172 def render_display_format_text(self, output):
1215 1173 return [output.text]
1216 1174
1217 @DocInherit
1218 1175 def render_display_format_html(self, output):
1219 1176 return [output.html]
1220 1177
1221 @DocInherit
1222 1178 def render_display_format_latex(self, output):
1223 1179 return [output.latex]
1224 1180
1225 @DocInherit
1226 1181 def render_display_format_json(self, output):
1227 1182 return [output.json]
1228 1183
1229 1184
1230 @DocInherit
1231 1185 def render_display_format_javascript(self, output):
1232 1186 return [output.javascript]
1233 1187
@@ -1258,11 +1212,9 b' class ConverterPy(Converter):'
1258 1212 "returns every line in input as commented out"
1259 1213 return "# "+input.replace("\n", "\n# ")
1260 1214
1261 @DocInherit
1262 1215 def render_heading(self, cell):
1263 1216 return ['#{0} {1}'.format('#'*cell.level, cell.source), '']
1264 1217
1265 @DocInherit
1266 1218 def render_code(self, cell):
1267 1219 if not cell.input:
1268 1220 return []
@@ -1279,18 +1231,15 b' class ConverterPy(Converter):'
1279 1231 lines.extend(conv_fn(output))
1280 1232 return lines
1281 1233
1282 @DocInherit
1283 1234 def render_markdown(self, cell):
1284 1235 return [self.comment(cell.source), '']
1285 1236
1286 @DocInherit
1287 1237 def render_raw(self, cell):
1288 1238 if self.raw_as_verbatim:
1289 1239 return [self.comment(indent(cell.source)), '']
1290 1240 else:
1291 1241 return [self.comment(cell.source), '']
1292 1242
1293 @DocInherit
1294 1243 def render_pyout(self, output):
1295 1244 lines = []
1296 1245
@@ -1307,36 +1256,28 b' class ConverterPy(Converter):'
1307 1256 lines.append('')
1308 1257 return lines
1309 1258
1310 @DocInherit
1311 1259 def render_pyerr(self, output):
1312 1260 # Note: a traceback is a *list* of frames.
1313 1261 return [indent(remove_ansi('\n'.join(output.traceback))), '']
1314 1262
1315 @DocInherit
1316 1263 def _img_lines(self, img_file):
1317 1264 return [ self.comment('image file: %s' % img_file), '']
1318 1265
1319 @DocInherit
1320 1266 def render_display_format_text(self, output):
1321 1267 return [self.comment(indent(output.text))]
1322 1268
1323 @DocInherit
1324 1269 def _unknown_lines(self, data):
1325 1270 return [self.comment('Warning: Unknown cell'+ str(data))]
1326 1271
1327 @DocInherit
1328 1272 def render_display_format_html(self, output):
1329 1273 return [self.comment(output.html)]
1330 1274
1331 @DocInherit
1332 1275 def render_display_format_latex(self, output):
1333 1276 return []
1334 1277
1335 @DocInherit
1336 1278 def render_display_format_json(self, output):
1337 1279 return []
1338 1280
1339 @DocInherit
1340 1281 def render_display_format_javascript(self, output):
1341 1282 return []
1342 1283
1 NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now