1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 from inspect import formatargspec, getargspec, getdoc
27 from re import match, search
28 from string import letters, lowercase, lstrip, punctuation, replace, rstrip, split, upper, whitespace
29 import sys
30
31
32 sys.path.append(sys.path[0])
33 sys.path[0] = '../..'
34
35
36 from prompt.interpreter import Interpreter
37
38
40 - def __init__(self, file='docstring.tex'):
41 """Fetch all the docstrings of the user functions and format them LaTeX style."""
42
43
44 self.script_file = None
45 self.intro_string = ''
46 self.dummy_mode = 1
47
48
49 self.table_count = 1
50
51
52 interpreter = Interpreter(self)
53
54
55 self.get_blacklist()
56
57
58 self.file = open(file, 'w')
59
60
61 names = sorted(interpreter._locals.keys())
62
63
64 for name in names:
65
66 if name in self.blacklist:
67 continue
68
69
70 object = interpreter._locals[name]
71
72
73 if hasattr(object, '__relax_help__'):
74
75 self.doc_user_class(name, object)
76 continue
77
78
79 if not hasattr(object, '__doc__') or not object.__doc__:
80 continue
81
82
83 self.parse_docstring(name, object)
84
85
86 self.file.close()
87
88
90 """Allow the function text to be broken nicely across lines.
91
92 The '\' character will be added later by the latex_special_chars() method.
93 """
94
95
96 text = replace(text, "(", "(\linebreak[0]")
97
98
99 for char in letters:
100 text = replace(text, ".%s" % char, ".\linebreak[0]%s" % char)
101
102
103 text = replace(text, "=", "=\linebreak[0]")
104
105
106 text = replace(text, "\linebreak", "linebreak")
107
108
109 return text
110
111
113 """Document the user class."""
114
115
116 names = sorted(dir(parent_object))
117
118
119 for name in names:
120
121 if search('^_', name):
122 continue
123
124
125 object = getattr(parent_object, name)
126
127
128 if not hasattr(object, '__doc__') or not object.__doc__:
129 continue
130
131
132 self.parse_docstring(parent_name + '.' + name, object)
133
134
136 """Maintained list of objects in the interpreter namespace which should not be documented."""
137
138
139 self.blacklist = []
140
141
142 self.blacklist.append('pi')
143 self.blacklist.append('script')
144
145
147 """Function of inserting index marks into the text."""
148
149
150 if bold:
151 end_string = '|textbf}'
152 else:
153 end_string = '}'
154
155
156 for i in xrange(len(self.entries)):
157
158 if index+2 < len(self.words) and self.entries[i][2] == 3 and search(self.entries[i][0], self.words[index] + ' ' + self.words[index+1] + ' ' + self.words[index+2]):
159 self.words[index] = self.words[index] + '\\index{' + self.entries[i][1] + end_string
160
161
162 elif index+1 < len(self.words) and self.entries[i][2] == 2 and search(self.entries[i][0], self.words[index] + ' ' + self.words[index+1]):
163 self.words[index] = self.words[index] + '\\index{' + self.entries[i][1] + end_string
164
165
166 elif self.entries[i][2] == 1 and search(self.entries[i][0], self.words[index]):
167 self.words[index] = self.words[index] + '\\index{' + self.entries[i][1] + end_string
168
169
171 """Function for returning a data structure containing all words which should be indexed."""
172
173
174 self.entries = []
175
176
177
178
179 self.entries.append(['AIC', 'model selection!AIC'])
180 self.entries.append(['AICc', 'model selection!AICc'])
181 self.entries.append(['angle', 'angles'])
182 self.entries.append(['anisotropic', 'diffusion!anisotropic'])
183 self.entries.append(['ANOVA', 'model selection!ANOVA'])
184 self.entries.append(['asymmetric', 'diffusion!ellipsoid (asymmetric)'])
185 self.entries.append(['axially symmetric', 'diffusion!spheroid (axially symmetric)'])
186
187 self.entries.append(['BIC', 'model selection!BIC'])
188 self.entries.append(['BFGS', 'minimisation techniques!BFGS'])
189 self.entries.append(['bond length', 'bond length'])
190 self.entries.append(['bootstrap', 'model selection!bootstrap'])
191 self.entries.append(['bound', 'parameter!bounds'])
192 self.entries.append(['Brownian', 'diffusion!Brownian'])
193 self.entries.append(['bzip2', 'compression!bzip2'])
194
195 self.entries.append(['cauchy', 'minimisation techniques!Cauchy point'])
196 self.entries.append(['CG-Steihaug', 'minimisation techniques!CG-Steihaug'])
197 self.entries.append(['chemical exchange', 'chemical exchange'])
198 self.entries.append(['chi-squared', 'chi-squared'])
199 self.entries.append(['compression', 'compression'])
200 self.entries.append(['conjugate gradient', 'minimisation techniques!conjugate gradient'])
201 self.entries.append(['constraint', 'constraint'])
202 self.entries.append(['copy', 'copy'])
203 self.entries.append(['correlation time', 'correlation time'])
204 self.entries.append(['cross-validation', 'model selection!cross-validation'])
205
206 self.entries.append(['dasha', 'software!Dasha'])
207 self.entries.append(['Dasha', 'software!Dasha'])
208 self.entries.append(['delete', 'delete'])
209 self.entries.append(['diffusion tensor', 'diffusion!tensor'])
210 self.entries.append(['display', 'display'])
211 self.entries.append(['dogleg', 'minimisation techniques!dogleg'])
212
213 self.entries.append(['eigenvalue', 'eigenvalues'])
214 self.entries.append(['elimination', 'model elimination'])
215 self.entries.append(['ellipsoid', 'diffusion!ellipsoid (asymmetric)'])
216 self.entries.append(['Euler angle', 'Euler angles'])
217 self.entries.append(['exact trust region', 'minimisation techniques!exact trust region'])
218
219 self.entries.append(['Fletcher-Reeves', 'minimisation techniques!Fletcher-Reeves'])
220 self.entries.append(['floating point', 'floating point number'])
221
222 self.entries.append(['grace', 'software!Grace'])
223 self.entries.append(['Grace', 'software!Grace'])
224 self.entries.append(['gzip', 'compression!gzip'])
225
226 self.entries.append(['Hestenes-Stiefel', 'minimisation techniques!Hestenes-Stiefel'])
227 self.entries.append(['hypothesis testing', 'model selection!hypothesis testing'])
228
229 self.entries.append(['isotropic', 'diffusion!sphere (isotropic)'])
230
231 self.entries.append(['Levenberg-Marquardt', 'minimisation techniques!Levenberg-Marquardt'])
232 self.entries.append(['limit', 'parameter!limit'])
233
234 self.entries.append(['map', 'map'])
235 self.entries.append(['method of [Mm]ultipliers', 'minimisation techniques!Method of Multipliers'])
236 self.entries.append(['minimise', 'minimisation'])
237 self.entries.append(['minimisation', 'minimisation'])
238 self.entries.append(['model elimination', 'model elimination'])
239 self.entries.append(['modelfree4', 'software!Modelfree'])
240 self.entries.append(['Modelfree4', 'software!Modelfree'])
241 self.entries.append(['modelling', 'modelling'])
242 self.entries.append(['molecule', 'molecule'])
243 self.entries.append(['molmol', 'software!MOLMOL'])
244 self.entries.append(['Molmol', 'software!MOLMOL'])
245
246 self.entries.append(['opendx', 'software!OpenDX'])
247 self.entries.append(['OpenDX', 'software!OpenDX'])
248 self.entries.append(['optimise', 'optimise'])
249 self.entries.append(['order parameter', 'order parameter'])
250
251 self.entries.append(['newton', 'minimisation techniques!Newton'])
252 self.entries.append(['newton-CG', 'minimisation techniques!Newton conjugate gradient'])
253 self.entries.append(['NMR', 'NMR'])
254
255 self.entries.append(['PDB', 'PDB'])
256 self.entries.append(['Polak-Ribi.*re', 'minimisation techniques!Polak-Ribiere@Polak-Ribi\`ere'])
257 self.entries.append(['Polak-Ribi.*re +', 'minimisation techniques!Polak-Ribiere@Polak-Ribi\`ere +'])
258 self.entries.append(['plot', 'plot'])
259 self.entries.append(['python', 'Python'])
260
261 self.entries.append(['read', 'read'])
262 self.entries.append(['regular expression', 'regular expression'])
263 self.entries.append(['relaxation', 'relaxation'])
264 self.entries.append(['rotation', 'rotation'])
265
266 self.entries.append(['sequence', 'sequence'])
267 self.entries.append(['script', 'scripting!script file'])
268 self.entries.append(['scripting', 'scripting'])
269 self.entries.append(['simplex', 'minimisation techniques!simplex'])
270 self.entries.append(['sphere', 'diffusion!sphere (isotropic)'])
271 self.entries.append(['spheroid', 'diffusion!spheroid (axially symmetric)'])
272 self.entries.append(['sparky', 'software!Sparky'])
273 self.entries.append(['Sparky', 'software!Sparky'])
274 self.entries.append(['steepest descent', 'minimisation techniques!steepest descent'])
275
276 self.entries.append(['tar', 'tar'])
277
278 self.entries.append(['uncompressed', 'compression!uncompressed'])
279
280 self.entries.append(['write', 'write'])
281
282 self.entries.append(['xeasy', 'software!XEasy'])
283 self.entries.append(['Xeasy', 'software!XEasy'])
284 self.entries.append(['XEasy', 'software!XEasy'])
285
286
287 for i in xrange(len(self.entries)):
288
289 self.entries[i].append(len(split(self.entries[i][0], ' ')))
290
291
292 if search(self.entries[i][0][0], lowercase):
293 self.entries[i][0] = '[' + upper(self.entries[i][0][0]) + self.entries[i][0][0] + ']' + self.entries[i][0][1:]
294
295
296 self.entries[i][0] = '^' + self.entries[i][0]
297
298
299 self.entries[i].reverse()
300
301
302 self.entries.sort(reverse=1)
303 for i in xrange(len(self.entries)):
304 self.entries[i].reverse()
305
306
308 """Change the keyword label to bold sans serif font."""
309
310
311 string = ''
312
313
314 while True:
315
316 if self.i+1 > len(self.docstring_lines) or (self.docstring_lines[self.i] == '' and self.docstring_lines[self.i+1] == ''):
317 self.i = self.i + 1
318 break
319
320
321 if self.docstring_lines[self.i] == '':
322 string = string + ' \n '
323
324
325 else:
326 string = string + self.docstring_lines[self.i] + ' '
327
328
329 self.i = self.i + 1
330
331
332 self.section.append(string)
333 self.section_type.append('keywords')
334
335
479
480
482 """Function for changing the quotes for LaTeX processing."""
483
484
485 new_string = ''
486 in_quote = 0
487
488
489 for i in xrange(len(string)):
490
491 if search('\'', string[i]):
492
493 if not in_quote and (i == 0 or not search('[a-z]', string[i-1])):
494 new_string = new_string + '`'
495 in_quote = 1
496 continue
497
498
499 else:
500 in_quote = 0
501
502
503 new_string = new_string + string[i]
504
505 return new_string
506
507
509 """Function for handling LaTeX special characters."""
510
511
512 string = replace(string, '\\', 'This is a backslash to be replaced at the end of this functioN')
513
514
515 for char in "#$%&_{}":
516 string = replace(string, char, '\\'+char)
517
518
519 for char in "^~":
520 string = replace(string, char, '\\'+char+'{}')
521
522
523 string = replace(string, 'This is a backslash to be replaced at the end of this functioN', '$\\backslash$')
524
525
526 string = replace(string, 'linebreak[0]', '\linebreak[0]')
527
528
529 return string
530
531
533 """Function for creating LaTeX lists."""
534
535
536 string = lstrip(self.docstring_lines[self.i])
537
538
539 j = self.i
540 while True:
541
542 j = j + 1
543
544
545 if len(self.docstring_lines) <= j:
546 list_spacing = 0
547 break
548
549
550 if len(self.docstring_lines[j]) == 0:
551
552 if len(self.docstring_lines) <= j+1:
553 list_spacing = 0
554
555
556 elif search('^ ', self.docstring_lines[j+1]):
557 list_spacing = 1
558
559
560 else:
561 list_spacing = 0
562
563
564 break
565
566
567 if not list_spacing:
568
569 string = string + ' \n '
570
571
572 while True:
573
574 self.i = self.i + 1
575
576
577 if self.i >= len(self.docstring_lines) or len(self.docstring_lines[self.i]) == 0:
578 break
579
580
581 string = string + lstrip(self.docstring_lines[self.i]) + ' \n '
582
583
584 else:
585
586 while True:
587
588 self.i = self.i + 1
589
590
591 if self.i >= len(self.docstring_lines):
592 break
593
594
595 if len(self.docstring_lines[self.i]) == 0:
596
597 string = string + ' \n '
598
599
600 continue
601
602
603 if self.i >= len(self.docstring_lines) or not search('^ ', (self.docstring_lines[self.i])):
604 break
605
606
607 string = string + ' ' + lstrip(self.docstring_lines[self.i])
608
609
610 self.i = self.i - 1
611
612
613 self.section.append(string)
614 self.section_type.append('list')
615
616
617 - def num_to_text(self, num):
618 """Convert the number to text.
619 @param num: The number to convert.
620 @type num: int
621 @return: The number in the format of 'First', 'Second', 'Third', etc.
622 @rtype: str
623 """
624
625
626 list = ['First',
627 'Second',
628 'Third',
629 'Fourth',
630 'Fifth',
631 'Sixth',
632 'Seventh',
633 'Eighth',
634 'Ninth',
635 'Tenth',
636 'Eleventh',
637 'Twelfth'
638 ]
639
640
641 return list[num-1]
642
643
645 """Function for extracting the paragraphs from the docstring."""
646
647
648 string = self.docstring_lines[self.i]
649
650
651 while True:
652
653 self.i = self.i + 1
654
655
656 if self.i >= len(self.docstring_lines):
657 break
658
659
660 if len(self.docstring_lines[self.i]) == 0:
661 break
662
663
664 if search('^___', self.docstring_lines[self.i]):
665 break
666
667
668 if search('^ ', self.docstring_lines[self.i]):
669 break
670
671
672 string = string + ' ' + self.docstring_lines[self.i]
673
674
675 self.i = self.i - 1
676
677
678 self.section.append(string)
679 self.section_type.append('paragraph')
680
681
683 """Function for creating the LaTeX file."""
684
685
686
687
688
689 sys.stdout.write("User function: %s().\n" % function)
690
691
692 docstring = getdoc(object)
693
694
695 self.docstring_lines = split(docstring, "\n")
696
697
698 self.section = []
699 self.section_type = []
700
701
702
703
704
705 self.section.append(function)
706 self.section_type.append('subsection')
707
708
709
710
711
712
713 self.section.append('Synopsis')
714 self.section_type.append('subsubsection')
715
716
717 self.section.append(self.docstring_lines[0])
718 self.section_type.append('paragraph')
719
720
721
722
723
724
725 self.section.append('Defaults')
726 self.section_type.append('subsubsection')
727
728
729 args, varargs, varkw, defaults = getargspec(object)
730
731
732 arguments = formatargspec(args, varargs, varkw, defaults)
733
734
735 self.section.append(arguments)
736 self.section_type.append('arguments')
737
738
739
740
741
742
743 self.i = 1
744 while True:
745
746 self.i = self.i + 1
747
748
749 if self.i >= len(self.docstring_lines):
750 break
751
752
753 self.docstring_lines[self.i] = rstrip(self.docstring_lines[self.i])
754
755
756 if self.docstring_lines[self.i] == '':
757 continue
758
759
760 if self.i+1 < len(self.docstring_lines) and search('^~~~', self.docstring_lines[self.i+1]):
761
762 self.section_title = self.docstring_lines[self.i]
763 self.section.append(self.docstring_lines[self.i])
764 self.section_type.append('subsubsection')
765
766
767 self.i = self.i + 2
768 continue
769
770
771 if search('^Keyword ', self.section_title):
772 self.keywords()
773
774
775 elif search('---', self.docstring_lines[self.i]):
776 self.verbatim()
777
778
779 elif search('^relax>', self.docstring_lines[self.i]) or search('^\$ ', self.docstring_lines[self.i]):
780 self.relax_examples()
781
782
783 elif search('^___', self.docstring_lines[self.i]):
784 self.tables()
785
786
787 elif search('^ ', self.docstring_lines[self.i]):
788 self.lists()
789
790
791 else:
792 self.paragraph()
793
794
795
796
797
798
799
800 self.index_entries()
801
802
803 for i in xrange(len(self.section)):
804
805 st = self.section_type[i]
806
807
808 if st == 'arguments' or st == 'example':
809 self.section[i] = self.break_functions(self.section[i])
810 self.section[i] = self.latex_quotes(self.section[i])
811
812
813 if not st == 'verbatim':
814 self.section[i] = self.latex_special_chars(self.section[i])
815
816
817 if not st == 'arguments' and not st == 'verbatim' and not st == 'example' and not st == 'subsection':
818 self.section[i] = self.latex_formatting(self.section[i])
819
820
821 if not st == 'arguments' and not st == 'verbatim' and not st == 'example':
822
823 self.words = split(self.section[i], ' ')
824
825
826 self.in_quote = 0
827
828
829 for j in xrange(len(self.words)):
830
831 if st == 'subsection' or st == 'subsubsection':
832 self.indexing(j, bold=1)
833 else:
834 self.indexing(j, bold=0)
835
836
837 self.quotes(j)
838
839
840 if j == 0:
841 self.section[i] = self.words[j]
842 else:
843 self.section[i] = self.section[i] + ' ' + self.words[j]
844
845
846
847
848
849
850 longtable = {"molmol.macro_write": [3],
851 "pymol.macro_write": [2]
852 }
853
854
855 self.file.write(" \n\n\n")
856
857
858 self.file.write(" \\vspace{20pt}\n")
859 self.file.write(" \\rule{\columnwidth}{2pt}\n")
860 self.file.write(" \\vspace{-30pt}\n")
861
862
863 table_sub_count = 1
864 for i in xrange(len(self.section)):
865
866 st = self.section_type[i]
867
868
869 if st == 'subsection':
870
871 user_fn = self.section[i] + '()'
872
873
874 user_fn = replace(user_fn, '.', '\-.')
875 user_fn = replace(user_fn, '\_', '\-\_')
876
877
878 self.file.write(" \n\n \\subsection{" + user_fn + "}")
879
880
881 table_sub_count = 1
882
883
884 elif st == 'subsubsection':
885 self.file.write(" \n \\subsubsection{" + self.section[i] + "}")
886
887
888 elif st == 'arguments':
889 self.file.write("\\begin{flushleft}\n")
890 self.file.write("\\textsf{\\textbf{" + self.latex_special_chars(self.break_functions(function)) + "}" + self.section[i] + "}\n")
891 self.file.write("\\end{flushleft}\n")
892
893
894 elif st == 'keywords':
895
896 lines = split(self.section[i], '\n')
897
898
899 for line in lines:
900
901 line_elements = split(line, ':')
902
903
904 if len(line_elements) > 2:
905 sys.stderr.write("Keyword failure in: " + repr(line) + " \n ")
906 sys.exit()
907
908
909 self.file.write("\\keyword{" + line_elements[0] + ":}" + line_elements[1] + " \n\n ")
910
911
912
913 elif st == 'verbatim':
914 self.file.write("{\\footnotesize \\begin{verbatim} \n " + self.section[i] + "\\end{verbatim}}")
915
916
917 elif st == 'example':
918 self.file.write("\\example{" + self.section[i] + "}")
919
920
921 elif st == 'table':
922
923 self.file.write("(see table~\\ref{table%s}) \n " % self.table_count)
924
925
926 lines = split(self.section[i], '\n')
927
928
929 if function in longtable.keys() and table_sub_count in longtable[function]:
930
931 self.file.write("\\onecolumn\n ")
932 self.file.write("\\begin{center}\n ")
933 self.file.write("\\begin{longtable}{" + (int(lines[0]))*"l" + "}\n\n ")
934 self.file.write("\\caption{%s table for the %s user function.}\n\n " % (self.num_to_text(table_sub_count), user_fn))
935 self.file.write("\\\\\n \\toprule \n ")
936
937
938 elements = split(lines[1], 'SEPARATOR')
939 self.file.write(elements[0])
940 for j in range(1, len(elements)):
941 self.file.write('&' + elements[j])
942 self.file.write(" \\\\\n ")
943
944
945 self.file.write("\\midrule\n ")
946 self.file.write("\\endhead\n\n ")
947 self.file.write("\\bottomrule\n ")
948 self.file.write("\\endfoot\n\n ")
949
950
951 self.file.write("\\label{table%s}\n\n " % self.table_count)
952
953
954 for line in lines[2:-1]:
955
956 elements = split(line, 'SEPARATOR')
957
958
959 self.file.write(elements[0])
960 for j in range(1, len(elements)):
961 self.file.write('&' + elements[j])
962 self.file.write(" \\\\\n ")
963
964
965 self.file.write("\\end{longtable}\n ")
966 self.file.write("\\end{center}\n ")
967 self.file.write("\\twocolumn\n ")
968
969
970 else:
971
972 self.file.write("\\begin{table*}\n ")
973 self.file.write("\\begin{scriptsize}\n ")
974 self.file.write("\\begin{center}\n ")
975
976
977 self.file.write("\\caption{%s table for the %s user function.}\n " % (self.num_to_text(table_sub_count), user_fn))
978
979
980 self.file.write("\\begin{tabular}{" + (int(lines[0]))*"l" + "}\n ")
981 self.file.write("\\toprule\n ")
982
983
984 elements = split(lines[1], 'SEPARATOR')
985 self.file.write(elements[0])
986 for j in range(1, len(elements)):
987 self.file.write('&' + elements[j])
988 self.file.write(" \\\\\n ")
989
990
991 self.file.write("\\midrule\n ")
992
993
994 for line in lines[2:-1]:
995
996 elements = split(line, 'SEPARATOR')
997
998
999 self.file.write(elements[0])
1000 for j in range(1, len(elements)):
1001 self.file.write('&' + elements[j])
1002 self.file.write(" \\\\\n ")
1003
1004
1005 self.file.write("\\bottomrule\n ")
1006 self.file.write("\\label{table%s}\n " % self.table_count)
1007 self.file.write("\\end{tabular}\n ")
1008 self.file.write("\\end{center}\n ")
1009 self.file.write("\\end{scriptsize}\n ")
1010 self.file.write("\\end{table*}\n ")
1011
1012
1013 self.table_count = self.table_count + 1
1014 table_sub_count = table_sub_count + 1
1015
1016
1017 elif st == 'list':
1018
1019 lines = split(self.section[i], '\n')
1020
1021
1022 if len(lines[-1]) == 0:
1023 lines = lines[:-1]
1024
1025
1026 elements = split(lines[0], ':')
1027
1028
1029 if len(elements) > 2:
1030 sys.stderr.write("Error: Badly formatted list element.\n")
1031 sys.stderr.write("The element is: " + repr(lines[i]) + "\n")
1032 sys.exit()
1033
1034
1035 if len(elements) == 1:
1036 list_type = 0
1037
1038
1039 else:
1040 list_type = 1
1041
1042
1043 if list_type == 1:
1044 self.file.write("\\begin{description} \n ")
1045 else:
1046 self.file.write("\\begin{itemize} \n ")
1047
1048
1049 for j in xrange(len(lines)):
1050
1051 if list_type == 0:
1052 self.file.write("\\item[] " + lstrip(lines[j]) + ' \n ')
1053
1054
1055 else:
1056
1057 elements = split(lines[j], ':')
1058
1059
1060 if len(elements) != 2:
1061 continue
1062
1063
1064 self.file.write("\\item[" + lstrip(elements[0]) + " --]" + elements[1] + ' \n ')
1065
1066
1067 if list_type == 1:
1068 self.file.write("\\end{description} \n ")
1069 else:
1070 self.file.write("\\end{itemize} \n ")
1071
1072
1073 else:
1074 self.file.write(self.section[i] + ' \n ')
1075
1076
1077 self.file.write(" \n\n ")
1078
1079
1081 """Function for placing quotes within the quote environment."""
1082
1083
1084 elements = split(self.words[index], "'")
1085
1086
1087 if len(elements) == 3:
1088 self.words[index] = elements[0] + '\quotecmd{' + elements[1] + '}' + elements[2]
1089
1090
1091 elif len(elements) > 3:
1092 sys.stderr.write('Unknown quote: ' + repr(self.words[index]))
1093 sys.exit()
1094
1095
1096 if len(elements) == 2:
1097
1098 if not self.in_quote and not search('[a-z]$', elements[0]):
1099 self.words[index] = elements[0] + '\quotecmd{' + elements[1]
1100 self.in_quote = 1
1101
1102
1103 elif self.in_quote:
1104 self.words[index] = elements[0] + '}' + elements[1]
1105 self.in_quote = 0
1106
1107
1109 """Use typewriter font for relax examples."""
1110
1111
1112 string = self.docstring_lines[self.i]
1113
1114
1115 while True:
1116
1117 self.i = self.i + 1
1118
1119
1120 if self.i >= len(self.docstring_lines) or self.docstring_lines[self.i] == '' or search('^relax>', self.docstring_lines[self.i]) or search('^\$ ', self.docstring_lines[self.i]):
1121 self.i = self.i - 1
1122 break
1123
1124
1125 string = string + ' ' + lstrip(self.docstring_lines[self.i])
1126
1127
1128 string = self.break_functions(string)
1129
1130
1131 self.section.append(string)
1132 self.section_type.append('example')
1133
1134
1136 """Only replace in safe places within the text."""
1137
1138
1139
1140
1141 string = replace(string, '0'+text, '0'+latex)
1142 string = replace(string, '1'+text, '1'+latex)
1143 string = replace(string, '2'+text, '2'+latex)
1144 string = replace(string, '3'+text, '3'+latex)
1145 string = replace(string, '4'+text, '4'+latex)
1146 string = replace(string, '5'+text, '5'+latex)
1147 string = replace(string, '6'+text, '6'+latex)
1148 string = replace(string, '7'+text, '7'+latex)
1149 string = replace(string, '8'+text, '8'+latex)
1150 string = replace(string, '9'+text, '9'+latex)
1151
1152
1153 string = replace(string, ' '+text+',', ' '+latex+',')
1154 string = replace(string, ' '+text+'.', ' '+latex+'.')
1155 string = replace(string, ' '+text+' ', ' '+latex+' ')
1156 string = replace(string, ' '+text+';', ' '+latex+';')
1157 string = replace(string, ' '+text+':', ' '+latex+':')
1158
1159
1160 string = replace(string, '['+text+']', '['+latex+']')
1161 string = replace(string, '['+text+' ', '['+latex+' ')
1162 string = replace(string, '['+text+',', '['+latex+',')
1163 string = replace(string, '['+text+';', '['+latex+';')
1164 string = replace(string, ' '+text+']', ' '+latex+']')
1165
1166
1167 string = replace(string, '('+text+')', '('+latex+')')
1168 string = replace(string, '('+text+' ', '('+latex+' ')
1169 string = replace(string, '('+text+',', '('+latex+',')
1170 string = replace(string, '('+text+';', '('+latex+';')
1171 string = replace(string, ' '+text+')', ' '+latex+')')
1172
1173
1174 string = replace(string, '{'+text+' ', '{'+latex+' ')
1175 string = replace(string, '{'+text+',', '{'+latex+',')
1176 string = replace(string, '{'+text+';', '{'+latex+';')
1177 string = replace(string, ' '+text+'\\', ' '+latex+'\\')
1178
1179
1180 string = replace(string, '`'+text+'\'', '`'+latex+'\'')
1181 string = replace(string, '`'+text+' ', '`'+latex+' ')
1182 string = replace(string, '`'+text+',', '`'+latex+',')
1183 string = replace(string, '`'+text+'.', '`'+latex+'.')
1184 string = replace(string, '`'+text+';', '`'+latex+';')
1185 string = replace(string, ' '+text+'\'', ' '+latex+'\'')
1186
1187
1188 substring = replace(string[-len(text)-1:], ' '+text, ' '+latex)
1189 string = string[0:-len(text)-1] + substring
1190
1191 substring = replace(string[-len(text)-1:], '.'+text, '.'+latex)
1192 string = string[0:-len(text)-1] + substring
1193
1194 string = replace(string, ' '+text+'\n', ' '+latex+'\n')
1195 string = replace(string, '.'+text+'\n', '.'+latex+'\n')
1196
1197
1198 string = replace(string, ' '+text+'\^', ' '+latex+'\^')
1199 string = replace(string, '('+text+'\^', '('+latex+'\^')
1200 string = replace(string, '\n'+text+'\^', '\n'+latex+'\^')
1201
1202
1203 if search('^'+text+'['+punctuation+']', string) or search('^'+text+'['+whitespace+']', string) or search('\n'+text+'['+punctuation+']', string) or search('\n'+text+'['+whitespace+']', string):
1204 string = replace(string, text+' ', latex+' ')
1205 string = replace(string, text+',', latex+',')
1206 string = replace(string, text+'.', latex+'.')
1207 string = replace(string, text+';', latex+';')
1208 string = replace(string, text+']', latex+']')
1209 string = replace(string, text+')', latex+')')
1210 string = replace(string, text+'^', latex+'^')
1211 string = replace(string, text+'\\', latex+'\\')
1212 string = replace(string, text+'\'', latex+'\'')
1213 string = replace(string, text+'\n', latex+'\n')
1214
1215
1216
1217 return string
1218
1219
1221 """Function for creating LaTeX tables."""
1222
1223
1224 self.i = self.i + 1
1225
1226
1227 num_col = len(split(self.docstring_lines[self.i], '|'))
1228 string = repr(num_col-2) + ' \n '
1229
1230
1231 if num_col == 1:
1232 sys.stderr.write('Not a table!')
1233 sys.exit()
1234
1235
1236 self.i = self.i + 1
1237
1238
1239 headings = split(self.docstring_lines[self.i], '|')
1240 headings = headings[1:-1]
1241 for j in xrange(len(headings)):
1242 headings[j] = lstrip(rstrip(headings[j]))
1243
1244
1245 string = string + headings[0]
1246 for j in range(1, len(headings)):
1247 string = string + " SEPARATOR " + headings[j]
1248 string = string + ' \n '
1249
1250
1251 self.i = self.i + 3
1252
1253
1254 while True:
1255
1256 if self.i >= len(self.docstring_lines) or search('^\\|_', self.docstring_lines[self.i]):
1257 self.i = self.i + 1
1258 break
1259
1260
1261 columns = split(self.docstring_lines[self.i], '|')
1262
1263
1264 if len(columns) > 1:
1265 string = string + lstrip(rstrip(columns[1]))
1266 for j in range(2, len(columns)-1):
1267 string = string + " SEPARATOR " + lstrip(rstrip(columns[j]))
1268 string = string + ' \n '
1269 else:
1270 string = string + columns[0] + ' \n '
1271
1272
1273 self.i = self.i + 1
1274
1275
1276 self.section.append(string)
1277 self.section_type.append('table')
1278
1279
1281 """Function for extracting the verbatim docstring section."""
1282
1283
1284 string = ''
1285
1286
1287 while True:
1288
1289 self.i = self.i + 1
1290
1291
1292 if self.i >= len(self.docstring_lines) or search('---', self.docstring_lines[self.i]):
1293 self.i = self.i + 1
1294 break
1295
1296
1297 string = string + self.docstring_lines[self.i] + ' \n '
1298
1299
1300 self.section.append(string)
1301 self.section_type.append('verbatim')
1302