From 8ac945a4262911d77e948a0543c2562cb226bfaa Mon Sep 17 00:00:00 2001 From: Tim Burks Date: Sun, 14 Apr 2013 17:42:33 -0700 Subject: [PATCH] Release version 2.1, fixes to doc.nu document generation script --- Nukefile | 2 +- nu/doc.nu | 800 +++++++++++++++++++++++++++--------------------------- objc/Nu.m | 4 +- 3 files changed, 406 insertions(+), 400 deletions(-) diff --git a/Nukefile b/Nukefile index 14d8951..023d4cc 100644 --- a/Nukefile +++ b/Nukefile @@ -4,7 +4,7 @@ (ifDarwin (then (NSString stringWithShellCommand:"xcode-select -print-path")) (else nil))) -(global VERSION '(2 0 2)) #(major minor tweak) +(global VERSION '(2 1 0)) #(major minor tweak) (task "version" is (set now (NSCalendarDate date)) diff --git a/nu/doc.nu b/nu/doc.nu index 3334f40..ef8a0fc 100644 --- a/nu/doc.nu +++ b/nu/doc.nu @@ -21,36 +21,36 @@ (global TAB 9) (class NSString - ;; Create a copy of a string with leading whitespace removed. - (- (id) strip is - (set i 0) - (while (and (< i (self length)) - (or (eq (self characterAtIndex:i) SPACE) - (eq (self characterAtIndex:i) TAB))) - (set i (+ i 1))) - (self substringFromIndex:i)) - ;; Test to see whether a string begins with a specified substring. - (- (id) beginsWithString:(id) string is - (set range (self rangeOfString:string)) - (and range (eq (range first) 0))) - ;; Shorthand method to write files using UTF8 encodings. - (- (id) writeToFile:(id) fileName is - (puts "writing #{fileName}") - (self writeToFile:fileName atomically:NO encoding:NSUTF8StringEncoding error:(set perror ((NuReference alloc) init))))) + ;; Create a copy of a string with leading whitespace removed. + (- (id) strip is + (set i 0) + (while (and (< i (self length)) + (or (eq (self characterAtIndex:i) SPACE) + (eq (self characterAtIndex:i) TAB))) + (set i (+ i 1))) + (self substringFromIndex:i)) + ;; Test to see whether a string begins with a specified substring. + (- (id) beginsWithString:(id) string is + (set range (self rangeOfString:string)) + (and range (eq (range first) 0))) + ;; Shorthand method to write files using UTF8 encodings. + (- (id) writeToFile:(id) fileName is + (puts "writing #{fileName}") + (self writeToFile:fileName atomically:NO encoding:NSUTF8StringEncoding error:(set perror ((NuReference alloc) init))))) (class NSDate - ;; Generate a string representation of the same form as this one: - ;; - ;; "Thursday, 30 Aug 2007" - (- (id) descriptionForDocumentation is - (self descriptionWithCalendarFormat:"%A, %d %b %Y" timeZone:nil locale:nil))) + ;; Generate a string representation of the same form as this one: + ;; + ;; "Thursday, 30 Aug 2007" + (- (id) descriptionForDocumentation is + (self descriptionWithCalendarFormat:"%A, %d %b %Y" timeZone:nil locale:nil))) (class NSRegularExpressionCheckingResult - ;; Compare matches by their location. This allows arrays of matches to be sorted. - (- (NSComparisonResult) compare: (id) other is - (set self-start ((self range) first)) - (set other-start ((other range) first)) - (self-start compare: other-start))) + ;; Compare matches by their location. This allows arrays of matches to be sorted. + (- (NSComparisonResult) compare: (id) other is + (set self-start ((self range) first)) + (set other-start ((other range) first)) + (self-start compare: other-start))) ;; Matches one part of a selector. (set selector-pattern /(\w+:)\s*\(([\w<>]+\s*\*?)\)\s*(\w+)\s*/) @@ -81,7 +81,7 @@ ;; Match Objective-C documentation comments. (set objc-comment-pattern - /(?U)\/\*!((.|\n)+)\*\//) + /\/\*!((.|\n)+?)\*\//) ;; Match Nu comments. (set nu-comment-pattern @@ -90,181 +90,182 @@ ;; @abstract NuDoc class for building file descriptions. ;; @discussion NuDoc creates one instance of this class for each source file that it reads. (class NuDocFileInfo is NSObject - - ;; Get the file description for a named file. - (+ (id) infoForFileNamed:(id)name is - (unless (set fileInfo ($files objectForKey:name)) - (set fileInfo ((NuDocFileInfo alloc) initWithName:name)) - ($files setObject:fileInfo forKey:name)) - fileInfo) - - ;; Initialize a description for a named file. - (- (id) initWithName:(id) name is - (super init) - (set @name name) - (set @niceName (NSMutableString stringWithString:name)) - (@niceName replaceOccurrencesOfString:"." withString:"_" options:0 range:(list 0 (@niceName length))) - (@niceName replaceOccurrencesOfString:"/" withString:"_" options:0 range:(list 0 (@niceName length))) - (set @discussion (NSMutableString string)) - (set @methods (NSMutableArray array)) - (set @classes (NSMutableArray array)) - self) - - ;; Generate a link to the html description of the file. - (- (id) linkWithPrefix:(id) prefix is - (set link <<-END + + ;; Get the file description for a named file. + (+ (id) infoForFileNamed:(id)name is + (unless (set fileInfo ($files objectForKey:name)) + (set fileInfo ((NuDocFileInfo alloc) initWithName:name)) + ($files setObject:fileInfo forKey:name)) + fileInfo) + + ;; Initialize a description for a named file. + (- (id) initWithName:(id) name is + (super init) + (set @name name) + (set @niceName (NSMutableString stringWithString:name)) + (@niceName replaceOccurrencesOfString:"." withString:"_" options:0 range:(list 0 (@niceName length))) + (@niceName replaceOccurrencesOfString:"/" withString:"_" options:0 range:(list 0 (@niceName length))) + (set @discussion (NSMutableString string)) + (set @methods (NSMutableArray array)) + (set @classes (NSMutableArray array)) + self) + + ;; Generate a link to the html description of the file. + (- (id) linkWithPrefix:(id) prefix is + (set link <<-END #{@name}END) - link) - - ;; Set the raw comments associated with a file. - (- (void) setComments:(id) comments is - (set @comments comments) - (self parseFileComments)) - - ;; Extract information from one line of file comments. - (- (void) parseFileCommentLine:(id) line is - (cond ((or (line beginsWithString:"@class") - (line beginsWithString:"@category") - (line beginsWithString:"@method") - (line beginsWithString:"@function")) (set @finished YES)) - ((line beginsWithString:"!/") nil) - ((line beginsWithString:"@header") - (set @file (line substringFromIndex:(+ 1 ("@header" length))))) - ((line beginsWithString:"@file") - (set @file (line substringFromIndex:(+ 1 ("@file" length))))) - ((line beginsWithString:"@copyright") - (set @copyright (line substringFromIndex:(+ 1 ("@copyright" length))))) - ((line beginsWithString:"@abstract") - (set @abstract (line substringFromIndex:(+ 1 ("@abstract" length))))) - ((line beginsWithString:"@info") - (set @info (line substringFromIndex:(+ 1 ("@info" length))))) - ((and (not @finished) (line beginsWithString:"@discussion")) - (set @discussion (NSMutableString string)) - (@discussion appendString:(line substringFromIndex:(+ 1 ("@discussion" length))))) - ((and (not @finished) (eq line "") (!= @discussion "")) - (@discussion appendString:"

")) - ((not @finished) - (@discussion appendString:(NSString carriageReturn)) - (@discussion appendString:line)) - (else nil))) - - ;; Extract documentation from file comments. - (- (void) parseFileComments is - (set @discussion (NSMutableString string)) - (if @comments - (if (set match (objc-comment-pattern findInString:@comments)) - (then - (set text (match groupAtIndex:1)) - (set lines (text lines)) - (lines each: - (do (original-line) - (set line (original-line strip)) - (self parseFileCommentLine:line)))) - (else - (set lines (@comments lines)) - (lines each: - (do (original-line) - (if (set match (nu-comment-pattern findInString:original-line)) - (then - (set line (match groupAtIndex:3)) - (self parseFileCommentLine:line))))))))) - - ;; Add a method description to a file's array of methods. - (- (void) addMethod: (id) method is (@methods addObject:method)) - - ;; Add a class description to a file's array of classes. - (- (void) addClass: (id) class is (@classes addObject:class))) + link) + + ;; Set the raw comments associated with a file. + (- (void) setComments:(id) comments is + (set @comments comments) + (self parseFileComments)) + + ;; Extract information from one line of file comments. + (- (void) parseFileCommentLine:(id) line is + (cond ((or (line beginsWithString:"@class") + (line beginsWithString:"@category") + (line beginsWithString:"@method") + (line beginsWithString:"@function")) (set @finished YES)) + ((line beginsWithString:"!/") nil) + ((line beginsWithString:"@header") + (set @file (line substringFromIndex:(+ 1 ("@header" length))))) + ((line beginsWithString:"@file") + (set @file (line substringFromIndex:(+ 1 ("@file" length))))) + ((line beginsWithString:"@copyright") + (set @copyright (line substringFromIndex:(+ 1 ("@copyright" length))))) + ((line beginsWithString:"@abstract") + (set @abstract (line substringFromIndex:(+ 1 ("@abstract" length))))) + ((line beginsWithString:"@info") + (set @info (line substringFromIndex:(+ 1 ("@info" length))))) + ((and (not @finished) (line beginsWithString:"@discussion")) + (set @discussion (NSMutableString string)) + (@discussion appendString:(line substringFromIndex:(+ 1 ("@discussion" length))))) + ((and (not @finished) (eq line "") (!= @discussion "")) + (@discussion appendString:"

")) + ((not @finished) + (@discussion appendString:(NSString carriageReturn)) + (@discussion appendString:line)) + (else nil))) + + ;; Extract documentation from file comments. + (- (void) parseFileComments is + (set @discussion (NSMutableString string)) + (if @comments + (if (set match (objc-comment-pattern findInString:@comments)) + (then + (set text (match groupAtIndex:1)) + (set lines (text lines)) + (lines each: + (do (original-line) + (set line (original-line strip)) + (self parseFileCommentLine:line)))) + (else + (set lines (@comments lines)) + (lines each: + (do (original-line) + (if (set match (nu-comment-pattern findInString:original-line)) + (then + (set line (match groupAtIndex:3)) + (self parseFileCommentLine:line))))))))) + + ;; Add a method description to a file's array of methods. + (- (void) addMethod: (id) method is (@methods addObject:method)) + + ;; Add a class description to a file's array of classes. + (- (void) addClass: (id) class is (@classes addObject:class))) ;; Extract information from one line of class and method comments. (macro parseClassAndMethodCommentLine () - `(progn - (cond ((line beginsWithString:"@class") - (set @class (line substringFromIndex:(+ 1 ("@class" length))))) - ((line beginsWithString:"@category") ;; category is an alias for class - (set @class (line substringFromIndex:(+ 1 ("@category" length))))) - ((line beginsWithString:"@abstract") - (set @abstract (line substringFromIndex:(+ 1 ("@abstract" length))))) - ((line beginsWithString:"@method") - (set @method (line substringFromIndex:(+ 1 ("@method" length))))) - ((line beginsWithString:"@discussion") - (set @discussion (NSMutableString string)) - (@discussion appendString:(line substringFromIndex:(+ 1 ("@discussion" length))))) - ((and (eq line "") (!= @discussion "")) - (@discussion appendString:"

")) - (else - (@discussion appendString:(NSString carriageReturn)) - (@discussion appendString:line))))) + `(progn + (cond ((line beginsWithString:"@class") + (set @class (line substringFromIndex:(+ 1 ("@class" length))))) + ((line beginsWithString:"@category") ;; category is an alias for class + (set @class (line substringFromIndex:(+ 1 ("@category" length))))) + ((line beginsWithString:"@abstract") + (set @abstract (line substringFromIndex:(+ 1 ("@abstract" length))))) + ((line beginsWithString:"@method") + (set @method (line substringFromIndex:(+ 1 ("@method" length))))) + ((line beginsWithString:"@discussion") + (set @discussion (NSMutableString string)) + (@discussion appendString:(line substringFromIndex:(+ 1 ("@discussion" length))))) + ((and (eq line "") (!= @discussion "")) + (@discussion appendString:"

")) + (else + (@discussion appendString:(NSString carriageReturn)) + (@discussion appendString:line))))) ;; Extract documentation information from class and method comments. (macro parseClassAndMethodComments () - `(progn - (set @discussion (NSMutableString string)) - (if @comments - (if (set match (objc-comment-pattern findInString:@comments)) - (then - ;(puts "parsing objc comment text for #{(if @name (then @name)(else @methodName))}") - (set text (match groupAtIndex:1)) - (set lines (text lines)) - (lines each: - (do (original-line) - (set line (original-line strip)) - (parseClassAndMethodCommentLine)))) - (else - ;(puts "parsing nu comment text for #{(if @name (then @name)(else @methodName))}") - (set lines (@comments lines)) - (lines each: - (do (original-line) - (if (set match (nu-comment-pattern findInString:original-line)) - (then - (set line (match groupAtIndex:3)) - (parseClassAndMethodCommentLine)))))))))) + `(progn + (set @discussion (NSMutableString string)) + (if @comments + (if (set match (objc-comment-pattern findInString:@comments)) + (then + ;(puts "parsing objc comment text for #{(if @name (then @name)(else @methodName))}") + (set text (match groupAtIndex:1)) + (set lines (text lines)) + (lines each: + (do (original-line) + (set line (original-line strip)) + (parseClassAndMethodCommentLine)))) + (else + ;(puts "parsing nu comment text for #{(if @name (then @name)(else @methodName))}") + (set lines (@comments lines)) + (lines each: + (do (original-line) + (if (set match (nu-comment-pattern findInString:original-line)) + (then + (set line (match groupAtIndex:3)) + (parseClassAndMethodCommentLine)))))))))) ;; @abstract NuDoc class for building class descriptions. ;; @discussion NuDoc creates one instance of this class for each class that it encounters when reading source files. (class NuDocClassInfo is NSObject - - ;; Initialize a description for a named class. - (- (id) initWithName:(id) name is - (super init) - (set @name name) - (set @methods (NSMutableArray array)) - (set @files (NSMutableDictionary dictionary)) - self) - - ;; Generate a link to the html description of the class. - (- (id) linkWithPrefix:(id) prefix is - (set link <<-END + + ;; Initialize a description for a named class. + (- (id) initWithName:(id) name is + (super init) + (set @name name) + (set @superClassName nil) + (set @methods (NSMutableArray array)) + (set @files (NSMutableDictionary dictionary)) + self) + + ;; Generate a link to the html description of the class. + (- (id) linkWithPrefix:(id) prefix is + (set link <<-END #{@name}END) - link) - - ;; Generate a link to the html description of the class' superclass. - (- (id) linkToSuperClassWithPrefix:(id) prefix is - (if (set superClassInfo ($classes objectForKey:@superClassName)) - (then (superClassInfo linkWithPrefix:prefix)) - (else @superClassName))) - - ;; Get an array of descriptions of a class' class methods. - (- (id) classMethods is - (@methods select:(do (method) (eq (method methodType) "+")))) - - ;; Get an array of descriptions of a class' instance methods. - (- (id) instanceMethods is - (@methods select:(do (method) (eq (method methodType) "-")))) - - ;; Set the raw comments associated with a class. - (- (void) setComments:(id) comments is - (set @comments comments) - (parseClassAndMethodComments)) - - ;; A sorted list of the names of files containing declarations of a class and its methods. - (- (id) fileNames is ((@files allKeys) sort)) - - ;; A list of the descriptions of files containing declarations of a class and its methods. - (- (id) files is (@files allValues)) - - ;; Add a file description to the class' list. - (- (void) addFile:(id) file is - (@files setObject:file forKey:(file name)))) + link) + + ;; Generate a link to the html description of the class' superclass. + (- (id) linkToSuperClassWithPrefix:(id) prefix is + (if (set superClassInfo ($classes objectForKey:@superClassName)) + (then (superClassInfo linkWithPrefix:prefix)) + (else @superClassName))) + + ;; Get an array of descriptions of a class' class methods. + (- (id) classMethods is + (@methods select:(do (method) (eq (method methodType) "+")))) + + ;; Get an array of descriptions of a class' instance methods. + (- (id) instanceMethods is + (@methods select:(do (method) (eq (method methodType) "-")))) + + ;; Set the raw comments associated with a class. + (- (void) setComments:(id) comments is + (set @comments comments) + (parseClassAndMethodComments)) + + ;; A sorted list of the names of files containing declarations of a class and its methods. + (- (id) fileNames is ((@files allKeys) sort)) + + ;; A list of the descriptions of files containing declarations of a class and its methods. + (- (id) files is (@files allValues)) + + ;; Add a file description to the class' list. + (- (void) addFile:(id) file is + (@files setObject:file forKey:(file name)))) (set method-table-template (NuTemplate codeForString: <<-END @@ -292,189 +293,191 @@ END)) ;; @abstract NuDoc class for building method descriptions. ;; @discussion NuDoc creates one instance of this class for each method implementation that it encounters when reading source files. (class NuDocMethodInfo is NSObject - - ;; Initialize a method description from a Nu declaration. - (- (id) initWithDeclaration:(id) declaration file:(id) file class:(id) classInfo is - (super init) - (set @file file) - (set @classInfo classInfo) - (set @methodType - (case (declaration first) - ('cmethod "+") - ('imethod "-") - ('+ "+") - ('- "-") - (else "?"))) - (set @comments (declaration comments)) - (parseClassAndMethodComments) - (set @returnType (declaration second)) - (set @selectors nil) - (cond ((eq 'is (declaration fourth)) - (set @methodName "#{((declaration second) stringValue)} #{((declaration third) stringValue)}") - (set @shortMethodName "#{((declaration third) stringValue)}")) ; that's all - (else - (set cursor ((declaration cdr) cdr)) - (set @methodName ((declaration second) stringValue)) - (set @selectors ((NSMutableArray alloc) init)) - (set @types ((NSMutableArray alloc) init)) - (set @names ((NSMutableArray alloc) init)) - (while (!= (cursor car) 'is) - (@selectors addObject: ((cursor first) stringValue)) - (@types addObject: ((cursor second) stringValue)) - (@names addObject: ((cursor third) stringValue)) - (set @methodName "#{@methodName} #{((cursor first) stringValue)} #{((cursor second) stringValue)} #{((cursor third) stringValue)}") - (set cursor (((cursor cdr) cdr) cdr))) - (set @shortMethodName (@selectors componentsJoinedByString:"")) - )) - self) - - ;; Initialize a method description from an Objective-C declaration. - (- (id) initWithName:(id) name file:(id) file class:(id) classInfo is - (super init) - (set @file file) - (set @classInfo classInfo) - (set @methodType (name substringToIndex:1)) - (set @methodName (name substringFromIndex:2)) - (set @selectors nil) - (cond ((set match (signature-pattern1 findInString:name)) - ;; ARITY 1+ - (set @returnType "(#{(match groupAtIndex:2)})") + + ;; Initialize a method description from a Nu declaration. + (- (id) initWithDeclaration:(id) declaration file:(id) file class:(id) classInfo is + (super init) + (set @file file) + (set @classInfo classInfo) + (set @methodType + (case (declaration first) + ('cmethod "+") + ('imethod "-") + ('+ "+") + ('- "-") + (else "?"))) + (set @comments (declaration comments)) + (parseClassAndMethodComments) + (set @returnType (declaration second)) + (set @selectors nil) + (cond ((eq 'is (declaration fourth)) + (set @methodName "#{((declaration second) stringValue)} #{((declaration third) stringValue)}") + (set @shortMethodName "#{((declaration third) stringValue)}")) ; that's all + (else + (set cursor ((declaration cdr) cdr)) + (set @methodName ((declaration second) stringValue)) (set @selectors ((NSMutableArray alloc) init)) (set @types ((NSMutableArray alloc) init)) (set @names ((NSMutableArray alloc) init)) - (set nameToParse (match groupAtIndex:3)) - ((selector-pattern findAllInString:nameToParse) each: - (do (match2) - (@selectors addObject:(match2 groupAtIndex:1)) - (@types addObject:"(#{(match2 groupAtIndex:2)})") - (@names addObject:(match2 groupAtIndex:3)))) - (set @shortMethodName (@selectors componentsJoinedByString:""))) - - ((set match (signature-pattern0 findInString:name)) - ;; ARITY 0 - (set @returnType "(#{(match groupAtIndex:2)})") - (set @shortMethodName (match groupAtIndex:3))) - (else (puts "error! can't parse selector #{name}"))) - self) - - ;; Generate a link to the html description of the method. - (- (id) linkWithPrefix:(id) prefix is - (set link <<-END + (while (!= (cursor car) 'is) + (@selectors addObject: ((cursor first) stringValue)) + (@types addObject: ((cursor second) stringValue)) + (@names addObject: ((cursor third) stringValue)) + (set @methodName "#{@methodName} #{((cursor first) stringValue)} #{((cursor second) stringValue)} #{((cursor third) stringValue)}") + (set cursor (((cursor cdr) cdr) cdr))) + (set @shortMethodName (@selectors componentsJoinedByString:"")) + )) + self) + + ;; Initialize a method description from an Objective-C declaration. + (- (id) initWithName:(id) name file:(id) file class:(id) classInfo is + (super init) + (set @file file) + (set @classInfo classInfo) + (set @methodType (name substringToIndex:1)) + (set @methodName (name substringFromIndex:2)) + (set @selectors nil) + (cond ((set match (signature-pattern1 findInString:name)) + ;; ARITY 1+ + (set @returnType "(#{(match groupAtIndex:2)})") + (set @selectors ((NSMutableArray alloc) init)) + (set @types ((NSMutableArray alloc) init)) + (set @names ((NSMutableArray alloc) init)) + (set nameToParse (match groupAtIndex:3)) + ((selector-pattern findAllInString:nameToParse) each: + (do (match2) + (@selectors addObject:(match2 groupAtIndex:1)) + (@types addObject:"(#{(match2 groupAtIndex:2)})") + (@names addObject:(match2 groupAtIndex:3)))) + (set @shortMethodName (@selectors componentsJoinedByString:""))) + + ((set match (signature-pattern0 findInString:name)) + ;; ARITY 0 + (set @returnType "(#{(match groupAtIndex:2)})") + (set @shortMethodName (match groupAtIndex:3))) + (else (puts "error! can't parse selector #{name}"))) + self) + + ;; Generate a link to the html description of the method. + (- (id) linkWithPrefix:(id) prefix is + (set link <<-END #{@methodType} #{@shortMethodName}END) - link) - - ;; Compare methods by name, allowing method descriptions to be sorted. - (- (int) compare:(id) other is - (@shortMethodName compare:(other shortMethodName))) - - ;; Generate an html table that prettily-prints the method selector. - (- (id) tableDescription is - (eval method-table-template)) - - ;; Set the raw comments associatied with a method. - (- (void) setComments:(id) comments is - (set @comments comments) - (parseClassAndMethodComments))) + link) + + ;; Compare methods by name, allowing method descriptions to be sorted. + (- (int) compare:(id) other is + (@shortMethodName compare:(other shortMethodName))) + + ;; Generate an html table that prettily-prints the method selector. + (- (id) tableDescription is + (eval method-table-template)) + + ;; Set the raw comments associatied with a method. + (- (void) setComments:(id) comments is + (set @comments comments) + (parseClassAndMethodComments))) ;; extract documentation from nu source files (function extract-nu (file) - ;; is this really a Nu source file? - (if (and (NSString stringWithShellCommand:(+ "head -1 " file " | grep '#!'")) - (not (NSString stringWithShellCommand:(+ "head -1 " file " | grep 'nush'")))) - ;; apparently not. - (puts "skipping #{file}") - (return)) - (puts "extracting from #{file}") - (set fileInfo (NuDocFileInfo infoForFileNamed:file)) - (set code (_parser parse:(NSString stringWithContentsOfFile:file))) - ;; get file documentation from beginning of file - (if ((code second) comments) - (fileInfo setComments:((code second) comments))) - ;; code is a progn - ((code cdr) each: (do (statement) - (case (statement first) - ('class - (set className ((statement second) stringValue)) - - (unless (set classInfo ($classes valueForKey:className)) - (set classInfo ((NuDocClassInfo alloc) initWithName:className)) - ($classes setValue:classInfo forKey:className)) - (classInfo addFile:fileInfo) - (classInfo setComments: (statement comments)) - (fileInfo addClass:classInfo) - - (cond ((eq (statement third) 'is) - (set parentClassName (statement fourth)) - (classInfo setSuperClassName: ((statement fourth) stringValue)) - (set rest ((((statement cdr) cdr) cdr) cdr))) - (else - (set parentClassName nil) - (set rest ((statement cdr) cdr)))) - - (rest each: (do (statement) - (if (or (eq (statement first) 'imethod) - (eq (statement first) '-)) - (set methodInfo ((NuDocMethodInfo alloc) initWithDeclaration:statement file:fileInfo class:classInfo)) - ((classInfo methods) addObject:methodInfo) - (fileInfo addMethod:methodInfo)) - (if (or (eq (statement first) 'cmethod) - (eq (statement first) '+)) - (set methodInfo ((NuDocMethodInfo alloc) initWithDeclaration:statement file:fileInfo class:classInfo)) - ((classInfo methods) addObject:methodInfo) - (fileInfo addMethod:methodInfo))))) - ('function ;; future work - (set functionname (statement second))) - ('macro ;; future work - (set macroname (statement second))) - (else nil)))) - nil) + ;; is this really a Nu source file? + (if (and (NSString stringWithShellCommand:(+ "head -1 " file " | grep '#!'")) + (not (NSString stringWithShellCommand:(+ "head -1 " file " | grep 'nush'")))) + ;; apparently not. + (puts "skipping #{file}") + (return)) + (puts "extracting from #{file}") + (set fileInfo (NuDocFileInfo infoForFileNamed:file)) + (set code (_parser parse:(NSString stringWithContentsOfFile:file))) + ;; get file documentation from beginning of file + (if ((code second) comments) + (fileInfo setComments:((code second) comments))) + ;; code is a progn + ((code cdr) each: (do (statement) + (case (statement first) + ('class + (set className ((statement second) stringValue)) + + (unless (set classInfo ($classes valueForKey:className)) + (set classInfo ((NuDocClassInfo alloc) initWithName:className)) + ($classes setValue:classInfo forKey:className)) + (classInfo addFile:fileInfo) + (classInfo setComments: (statement comments)) + (fileInfo addClass:classInfo) + + (cond ((eq (statement third) 'is) + (set parentClassName (statement fourth)) + (classInfo setSuperClassName: ((statement fourth) stringValue)) + (set rest ((((statement cdr) cdr) cdr) cdr))) + (else + (set parentClassName nil) + (set rest ((statement cdr) cdr)))) + + (rest each: (do (statement) + (if (or (eq (statement first) 'imethod) + (eq (statement first) '-)) + (set methodInfo ((NuDocMethodInfo alloc) initWithDeclaration:statement file:fileInfo class:classInfo)) + ((classInfo methods) addObject:methodInfo) + (fileInfo addMethod:methodInfo)) + (if (or (eq (statement first) 'cmethod) + (eq (statement first) '+)) + (set methodInfo ((NuDocMethodInfo alloc) initWithDeclaration:statement file:fileInfo class:classInfo)) + ((classInfo methods) addObject:methodInfo) + (fileInfo addMethod:methodInfo))))) + ('function ;; future work + (set functionname (statement second))) + ('macro ;; future work + (set macroname (statement second))) + (else nil)))) + nil) ;; extract documentation from Objective-C source files (function extract-objc (file) - (puts "extracting from #{file}") - (set fileInfo (NuDocFileInfo infoForFileNamed:file)) - (set code (NSString stringWithContentsOfFile:file)) - (set matches (NSMutableArray array)) - (matches addObjectsFromArray:(interface-pattern findAllInString:code)) - (matches addObjectsFromArray:(implementation-pattern findAllInString:code)) - (matches addObjectsFromArray:(protocol-pattern findAllInString:code)) - (matches addObjectsFromArray:(signature-pattern findAllInString:code)) - (matches addObjectsFromArray:(objc-comment-pattern findAllInString:code)) - (matches sortUsingSelector:"compare:") - - ;; get file documentation from beginning of file - (if (and matches (matches count) (eq ((matches 0) regex) objc-comment-pattern)) - (fileInfo setComments:(((matches 0) groupAtIndex:0)))) - - (set $comments "") - (matches each: - (do (match) - (case (match regex) - (interface-pattern - (set className (match groupAtIndex:1)) - (unless (set $classInfo ($classes valueForKey:className)) - (set $classInfo ((NuDocClassInfo alloc) initWithName:className)) - ($classes setValue:$classInfo forKey:className)) - ($classInfo addFile:fileInfo) - ($classInfo setComments:$comments) - ($classInfo setSuperClassName:(match groupAtIndex:3)) - (fileInfo addClass:$classInfo) - (set $comments "")) - (signature-pattern - (set methodName (match groupAtIndex:0)) - (set methodInfo ((NuDocMethodInfo alloc) initWithName:methodName file:fileInfo class:$classInfo)) - (($classInfo methods) addObject:methodInfo) - (methodInfo setComments:$comments) - (fileInfo addMethod:methodInfo) - (set $comments "")) - (objc-comment-pattern - (set $comments "#{(match groupAtIndex:0)}")) - (else nil))))) + (puts "extracting from #{file}") + (set fileInfo (NuDocFileInfo infoForFileNamed:file)) + (set code (NSString stringWithContentsOfFile:file)) + (set matches (NSMutableArray array)) + (matches addObjectsFromArray:(interface-pattern findAllInString:code)) + (matches addObjectsFromArray:(implementation-pattern findAllInString:code)) + (matches addObjectsFromArray:(protocol-pattern findAllInString:code)) + (matches addObjectsFromArray:(signature-pattern findAllInString:code)) + (matches addObjectsFromArray:(objc-comment-pattern findAllInString:code)) + (matches sortUsingSelector:"compare:") + + ;; get file documentation from beginning of file + (if (and matches (matches count) (eq ((matches 0) regex) objc-comment-pattern)) + (fileInfo setComments:(((matches 0) groupAtIndex:0)))) + + (set $comments "") + (matches each: + (do (match) + (case (match regex) + (interface-pattern + (set className (match groupAtIndex:1)) + (unless (set $classInfo ($classes valueForKey:className)) + (set $classInfo ((NuDocClassInfo alloc) initWithName:className)) + ($classes setValue:$classInfo forKey:className)) + ($classInfo addFile:fileInfo) + ($classInfo setComments:$comments) + ($classInfo setSuperClassName:(match groupAtIndex:3)) + (fileInfo addClass:$classInfo) + (set $comments "")) + (signature-pattern + (set methodName (match groupAtIndex:0)) + (set methodInfo ((NuDocMethodInfo alloc) initWithName:methodName file:fileInfo class:$classInfo)) + (($classInfo methods) addObject:methodInfo) + (methodInfo setComments:$comments) + (fileInfo addMethod:methodInfo) + (set $comments "")) + (objc-comment-pattern + (puts "FOUND COMMENTS") + (puts (match groupAtIndex:0)) + (set $comments "#{(match groupAtIndex:0)}")) + (else nil))))) (macro site-header () - `(progn - (if (eq $sitename "programming.nu") - (then <<-END + `(progn + (if (eq $sitename "programming.nu") + (then <<-END
@@ -794,39 +797,42 @@ END)) ;; Main program starts here ;; (macro nudoc () - `(progn - (set $classes (NSMutableDictionary dictionary)) - (set $files (NSMutableDictionary dictionary)) - - (puts "Reading Source Files") - - (set nu-files (filelist "^nu/.*\.nu$")) - (nu-files each: (do (file) (extract-nu file))) - - (set tool-files (filelist "^tools/[^/\.]+$")) - (tool-files each: (do (file) (extract-nu file))) - - (set objc-files (filelist "^objc/.*\.[h]$")) - (objc-files each: (do (file) (extract-objc file))) - - (puts "Generating Documentation") - - (set $project (((((NSString stringWithShellCommand:"pwd") lines) 0) componentsSeparatedByString:"/") lastObject)) - - (set $introduction "

Here are descriptions of the classes and methods used to implement #{$project}. These descriptions were automatically extracted from the #{$project} source code using nudoc.

") - - (set $footer (eval footer-template)) - - (system "mkdir -p doc") - (system "mkdir -p doc/classes") - (system "mkdir -p doc/files") - - ((eval css-template) writeToFile:"doc/doc.css") - ((eval index-template) writeToFile:"doc/index.html") - - (($classes allValues) each: - (do (classInfo) - ((eval classinfo-template) writeToFile:"doc/classes/#{(classInfo name)}.html"))) - - (($files allValues) each: - (do (fileInfo) ((eval fileinfo-template) writeToFile:"doc/files/#{(fileInfo niceName)}.html"))))) + `(progn + (set $classes (NSMutableDictionary dictionary)) + (set $files (NSMutableDictionary dictionary)) + + (puts "Reading Source Files") + + (set nu-files (filelist "^nu/.*\.nu$")) + (nu-files each: (do (file) (extract-nu file))) + + (set tool-files (filelist "^tools/[^/\.]+$")) + (tool-files each: (do (file) (extract-nu file))) + + (set objc-files (filelist "^objc/.*\.[h]$")) + (objc-files each: (do (file) (extract-objc file))) + + (puts "Generating Documentation") + + (set $project (((((NSString stringWithShellCommand:"pwd") lines) 0) componentsSeparatedByString:"/") lastObject)) + + (set $introduction (&p "Here are descriptions of the classes and methods used to implement " + $project + ". These descriptions were automatically extracted from the " + $project " source code using nudoc.")) + + (set $footer (eval footer-template)) + + (system "mkdir -p doc") + (system "mkdir -p doc/classes") + (system "mkdir -p doc/files") + + ((eval css-template) writeToFile:"doc/doc.css") + ((eval index-template) writeToFile:"doc/index.html") + + (($classes allValues) each: + (do (classInfo) + ((eval classinfo-template) writeToFile:"doc/classes/#{(classInfo name)}.html"))) + + (($files allValues) each: + (do (fileInfo) ((eval fileinfo-template) writeToFile:"doc/files/#{(fileInfo niceName)}.html"))))) diff --git a/objc/Nu.m b/objc/Nu.m index 34f54da..0e878ca 100644 --- a/objc/Nu.m +++ b/objc/Nu.m @@ -10523,8 +10523,8 @@ - (NSString *)group { - (NSString *)groupAtIndex:(int)i { NSRange range = [self rangeAtIndex:i]; NSString *string = [self associatedObjectForKey:@"string"]; - if (string) { - return [string substringWithRange:range]; + if (string && (range.location != NSNotFound)) { + return [string substringWithRange:range]; } else { return nil; }