diff --git a/faust/tools/faust2appls/faust2md b/faust/tools/faust2appls/faust2md index 2e460fcb9..54a39ee1c 100755 --- a/faust/tools/faust2appls/faust2md +++ b/faust/tools/faust2appls/faust2md @@ -1,202 +1,206 @@ -#!/usr/bin/python - -#---------------------- faust2md ----------------------- +#!/usr/bin/python3 +# +# ---------------------- faust2md ---------------------- # Usage: `faust2md [-t 4] [-c] [-f] foo.dsp > foo.md` # # Ultra simple automatic documentation system for Faust. # Creates a markdown file by extracting the comments from -# a faust file. The option -t n can be used to change the +# a Faust file. The option -t n can be used to change the # default (4) tab setting. The option -c can be used to -# include the faust code itself into the generated doc. +# include the Faust code itself into the generated doc. # And the option -f can be used to include a YAML front # matter with the name of the file and the date. # # The format of a title is : -# //############# Title Name ################# -# // markdown text.... -# // markdown text.... -# //########################################## +# //############# Title Name ################# +# // markdown text.... +# // markdown text.... +# //########################################## # # The format of a section is : -# //============== Section Name ============== -# // markdown text.... -# // markdown text.... -# //========================================== +# //============== Section Name ============== +# // markdown text.... +# // markdown text.... +# //========================================== # # The format of a comment is : -# //-------------- foo(x,y) ------------------ -# // markdown text.... -# // markdown text.... -# //------------------------------------------ -# everything else is considered faust code. +# //-------------- foo(x,y) ------------------ +# // markdown text.... +# // markdown text.... +# //------------------------------------------ +# everything else is considered Faust code. # The translation is the following: # ## foo(x,y) -# markdown text.... -# markdown text.... -#-------------------------------------------------------- +# markdown text.... +# markdown text.... +# ------------------------------------------------------ +import sys +import re +import datetime +import getopt -import sys, re, datetime, string, getopt # Outdent a comment line by n characters in # order to remove the prefix "// " def outdent(line, n): - if len(line) <= n: - return "\n" - else: - return line[n:] + if len(line) <= n: + return "\n" + else: + return line[n:] + # Match the first line of a title # of type "//**** Title ****" # at least 3 * are needed def matchBeginTitle(line): - return re.search(r'^\s*//#{3,}\s*([^#]+)#{3,}', line) + return re.search(r'^\s*//#{3,}\s*([^#]+)#{3,}', line) + # Match the last line of a title # of type "//********" # or a blank line def matchEndTitle(line): - return re.search(r'^\s*((//#{3,})|(\s*))$', line) + return re.search(r'^\s*((//#{3,})|(\s*))$', line) + # Match the first line of a section # of type "//==== Section ====" # at least 3 = are needed def matchBeginSection(line): - return re.search(r'^\s*//={3,}\s*([^=]+)={3,}', line) + return re.search(r'^\s*//={3,}\s*([^=]+)={3,}', line) + # Match the last line of a section # of type "//=======" # or a blank line def matchEndSection(line): - return re.search(r'^\s*((//={3,})|(\s*))$', line) + return re.search(r'^\s*((//={3,})|(\s*))$', line) + # Match the first line of a comment # of type "//--- foo(x,y) ----" # at least 3 - are needed def matchBeginComment(line): - return re.search(r'^\s*//-{3,}\s*([^-]+)-{3,}', line) + return re.search(r'^\s*//-{3,}\s*([^-]+)-{3,}', line) + # Match the last line of a comment # of type "//-----------------" # or a blank line def matchEndComment(line): - return re.search(r'^\s*((//-{3,})|(\s*))$', line) + return re.search(r'^\s*((//-{3,})|(\s*))$', line) + # Compute the indentation of a line, # that is the position of the first word character # after "// " def indentation(line): - matchComment = re.search(r'(^\s*//\s*\w)', line) - if matchComment: - return len(matchComment.group(1))-1 - else: - return 0 + matchComment = re.search(r'(^\s*//\s*\w)', line) + if matchComment: + return len(matchComment.group(1))-1 + else: + return 0 + # Indicates if a line is a comment def isComment(line): - matchComment = re.search(r'^\s*//', line) - if matchComment: - return 1 - else: - return 0 - -# Measure the indentation of a md-comment line -# that is the len of the prefix '// ' -def indentation(line): - matchComment = re.search(r'(^\s*//\s*\w)', line) - if matchComment: - return len(matchComment.group(1))-1 - else: - return 0 + matchComment = re.search(r'^\s*//', line) + if matchComment: + return 1 + else: + return 0 + # Print the front matter of the file def frontMatter(file): - print '---' - print 'file:', file - print 'date:', datetime.date.today() - print '---' - print '' + print('---') + print('file: %s' % (file,)) + print('date: %s' % (datetime.date.today(),)) + print('---') + print('') + # # THE PROGRAM STARTS HERE # - -tabsize = 4 # tabsize used for expanding tabs -codeflag = 0 # 0: no source code; 1: print also source code -frontflag = 0 # 0: no front matter; 1: print front matter -mode = 0 # 0: in code; 1: in md-comment -idt = 0 # indentation retained to outdent comment lines +tabsize = 4 # tabsize used for expanding tabs +codeflag = 0 # 0: no source code; 1: print also source code +frontflag = 0 # 0: no front matter; 1: print front matter +mode = 0 # 0: in code; 1: in md-comment +idt = 0 # indentation retained to outdent comment lines # Analyze command line arguments try: - opts, args = getopt.getopt(sys.argv[1:], "t:cf") - if not args: - raise getopt.error, "At least one file argument required" -except getopt.error, msg: - print msg - print "usage:", sys.argv[0], "[-t tabsize] [-c] [-f] file ..." - sys.exit(1) - + opts, args = getopt.getopt(sys.argv[1:], "t:cf") + if not args: + raise getopt.error("At least one file argument required") +except getopt.error as e: + print(e.msg) + print("usage: %s [-t tabsize] [-c] [-f] file ..." % (sys.argv[0],)) + sys.exit(1) for optname, optvalue in opts: - if optname == '-t': - tabsize = int(optvalue) - if optname == '-c': - codeflag = 1 - if optname == '-f': - frontflag = 1 + if optname == '-t': + tabsize = int(optvalue) + if optname == '-c': + codeflag = 1 + if optname == '-f': + frontflag = 1 + # Process all the files and print the documentation on the standard output for file in args: - with open(file) as f: - if frontflag: frontMatter(file) - for text in f: - line = string.expandtabs(text, tabsize) - if isComment(line)==0: - if mode==1: - # we are closing a md-comment - print '' - mode = 0 - if codeflag: - print '\t',line, - else: - if mode==0: # we are in code - matchComment = matchBeginComment(line) - matchSection = matchBeginSection(line) - matchTitle = matchBeginTitle(line) - if matchComment: - print '' - print "###", matchComment.group(1) - elif matchSection: - print '' - print "##", matchSection.group(1) - elif matchTitle: - print '' - print "#", matchTitle.group(1) - if matchComment or matchSection or matchTitle: - mode=1 # we just started a md-comment - idt = 0 # we have to measure the indentation - else: - # it is a comment but not a md-comment - # therefore it is part of the code - if codeflag: - print '\t',line, - else: - # we are in a md-comment - if idt==0: - # we have to measure the indentation - idt = indentation(line) - # check end of md-comment - matchComment = matchEndComment(line) - matchSection = matchEndSection(line) - matchTitle = matchEndTitle(line) - if matchComment: - print '' - print "---" - print '' - if matchComment or matchSection or matchTitle: - # end of md-comment switch back to mode O - mode = 0 - else: - # lien of content of md-comment - # we print it unindented - print outdent(line,idt), + with open(file) as f: + if frontflag: + frontMatter(file) + for text in f: + line = text.expandtabs(tabsize) + if isComment(line) == 0: + if mode == 1: + # we are closing a md-comment + print('') + mode = 0 + if codeflag: + print('\t%s' % line,) + else: + if mode == 0: # we are in code + matchComment = matchBeginComment(line) + matchSection = matchBeginSection(line) + matchTitle = matchBeginTitle(line) + if matchComment: + print('') + print("### %s" % (matchComment.group(1),)) + elif matchSection: + print('') + print("## %s" % (matchSection.group(1),)) + elif matchTitle: + print('') + print("# %s" % (matchTitle.group(1),)) + if matchComment or matchSection or matchTitle: + mode = 1 # we just started a md-comment + idt = 0 # we have to measure the indentation + else: + # it is a comment but not a md-comment + # therefore it is part of the code + if codeflag: + print('\t%s' % (line,)) + else: + # we are in a md-comment + if idt == 0: + # we have to measure the indentation + idt = indentation(line) + # check end of md-comment + matchComment = matchEndComment(line) + matchSection = matchEndSection(line) + matchTitle = matchEndTitle(line) + if matchComment: + print('') + print("---") + print('') + if matchComment or matchSection or matchTitle: + # end of md-comment switch back to mode O + mode = 0 + else: + # lien of content of md-comment + # we print it unindented + print(outdent(line, idt)),