More documentation tidyups

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@11972 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-Macdonald 2002-01-03 20:17:28 +00:00
parent 7ba655f9b8
commit 4ff38f06f1
5 changed files with 332 additions and 104 deletions

View file

@ -18,7 +18,11 @@ Thu Jan 3 19:38:42 2002 Nicola Pero <n.pero@mi.flashnet.it>
* Header/Foundation/GSXML.h: Correction standards complience
* Source/GSXML.m: A few documentation tidyups
* Tools/autogsdoc.m: Some tidyups for improved performance.
* Tools/autogsdoc.m: Some tidyups for improved performance
and added code to relocate html documents.
* Source/AGSIndex.[hm]: Minor API change to ease index handling,
bugfix for class index generation.
* Source/AGSHtml.m: Made index handling more consistent.
2002-01-02 Adam Fedor <fedor@gnu.org>

View file

@ -149,7 +149,7 @@ static NSMutableSet *textNodes = nil;
isRef: (BOOL)f
{
NSString *s;
NSString *kind = (f == YES) ? @"href" : @"name";
NSString *kind = (f == YES) ? @"rel=\"gsdoc\" href" : @"name";
NSString *hash = (f == YES) ? @"#" : @"";
if (f == NO || (s = [localRefs globalRef: r type: t]) != nil)
@ -172,8 +172,6 @@ static NSMutableSet *textNodes = nil;
* the html element is returned (&lt;a ...&gt;).<br />
* If the boolean f is YES, then the link is a reference to somewhere,
* otherwise the link is an anchor for some element being output.<br />
* The method will try to infer the unit in which the element was
* defined if the value of u is nil.<br />
* If there is an error, the method returns nil.
*/
- (NSString*) makeLink: (NSString*)r
@ -182,110 +180,60 @@ static NSMutableSet *textNodes = nil;
isRef: (BOOL)f
{
NSString *s = nil;
BOOL isLocal = YES;
NSString *kind = (f == YES) ? @"href" : @"name";
NSString *kind = (f == YES) ? @"rel=\"gsdoc\" href" : @"name";
NSString *hash = (f == YES) ? @"#" : @"";
/*
* No unit specified ... try to infer it.
*/
if (u == nil)
if (f == YES)
{
/*
* If we are currently inside a class, category, or protocol
* we see if the required item exists in that unit and if so,
* we assume that this is the unit to be used.
*/
if (unit != nil)
if (u == nil)
{
s = [localRefs unitRef: r type: t unit: unit];
if (s != nil)
{
u = unit;
}
else
{
NSString *x = unit;
/*
* Try stepping up superclasses until we find a match.
*/
while (x != nil)
{
x = [localRefs globalRef: x type: @"super"];
if (x != nil)
{
s = [localRefs unitRef: r type: t unit: x];
if (s != nil)
{
u = x;
break;
}
}
}
}
u = unit;
}
/*
* If we are making a reference, and we have not found it in the
* current unit, we check all known references to see if the item
* is uniquely documented somewhere.
*/
if (u == nil && f == YES)
s = base;
}
else if (u == nil)
{
u = unit;
s = [localRefs unitRef: r type: t unit: &u];
if (s == nil)
{
NSDictionary *d;
d = [localRefs unitRef: r type: t];
if ([d count] == 0)
{
isLocal = NO;
d = [globalRefs unitRef: r type: t];
}
if ([d count] == 1)
{
/*
* Record the class where the item is documented
* and the file where that documentation occurs.
*/
u = [[d allKeys] objectAtIndex: 0];
s = [d objectForKey: u];
}
u = unit;
s = [globalRefs unitRef: r type: t unit: &u];
}
}
else
{
NSString *tmp = u;
/*
* Simply look up the reference.
*/
s = [localRefs unitRef: r type: t unit: u];
if (s == nil && f == YES)
s = [localRefs unitRef: r type: t unit: &u];
if (s == nil)
{
isLocal = NO;
s = [globalRefs unitRef: r type: t unit: u];
u = tmp;
s = [globalRefs unitRef: r type: t unit: &u];
}
}
/**
* There are only two types of unit specific element ... methods
* and instance variables. The names within a unit are unique
* since you can't have two methods or two variables with the
* same name in a unit, and all method names contain either a
* a plus or minus as a prefix, while no variables do.<br />
* This means that we do not need to incorporate any type
* information into anchors and references for methods or
* instance varibales.
*/
if (s != nil)
{
if (isLocal == YES)
NSString *sep = @"";
if ([t isEqual: @"ivariable"] == YES)
{
s = [NSString stringWithFormat: @"<a %@=\"%@%@%@\">",
kind, hash, u, r];
sep = @"*";
}
if ([s isEqual: base] == YES)
{
s = [NSString stringWithFormat: @"<a %@=\"%@%@$%@%@%@\">",
kind, hash, t, u, sep, r];
}
else
{
s = [s stringByAppendingPathExtension: @"html"];
s = [NSString stringWithFormat: @"<a %@=\"%@%@%@%@\">",
kind, s, hash, u, r];
s = [NSString stringWithFormat: @"<a %@=\"%@%@%@$%@%@%@\">",
kind, s, hash, t, u, sep, r];
}
}
return s;
@ -822,7 +770,12 @@ static NSMutableSet *textNodes = nil;
NSArray *a = [dict allKeys];
unsigned c = [a count];
unsigned i;
NSString *sep = @"";
if ([type isEqual: @"ivariable"])
{
sep = @"*";
}
a = [a sortedArrayUsingSelector: @selector(compare:)];
[buf appendString: indent];
@ -850,9 +803,10 @@ static NSMutableSet *textNodes = nil;
NSString *file = [units objectForKey: u];
[buf appendString: indent];
[buf appendFormat:
@"<li><a href=\"%@.html#%@%@\">%@ in %@</a></li>\n",
file, u, ref, ref, u];
[buf appendFormat: @"<li><a rel=\"gsdoc\" href="];
[buf appendFormat: @"\"%@.html#%@$%@%@%@\">",
file, type, u, sep, ref];
[buf appendFormat: @"%@ in %@</a></li>\n", ref, u];
}
}
else
@ -877,8 +831,8 @@ static NSMutableSet *textNodes = nil;
}
[buf appendString: indent];
[buf appendFormat:
@"<li><a href=\"%@.html#%@$%@\">%@</a></li>\n",
[buf appendString: @"<li><a rel=\"gsdoc\" href="];
[buf appendFormat: @"\"%@.html#%@$%@\">%@</a></li>\n",
file, type, ref, text];
}
}

View file

@ -43,6 +43,6 @@
- (void) setGlobalRef: (NSString*)ref type: (NSString*)type;
- (void) setUnitRef: (NSString*)ref type: (NSString*)type;
- (NSDictionary*) unitRef: (NSString*)ref type: (NSString*)type;
- (NSString*) unitRef: (NSString*)ref type: (NSString*)type unit: (NSString*)u;
- (NSString*) unitRef: (NSString*)ref type: (NSString*)type unit: (NSString**)u;
@end
#endif

View file

@ -205,7 +205,7 @@ setDirectory(NSMutableDictionary *dict, NSString *path)
unit = [NSString stringWithFormat: @"%@(%@)",
[prop objectForKey: @"class"], [prop objectForKey: @"name"]];
[self setGlobalRef: unit type: name];
[self setGlobalRef: unit type: @"category"];
}
else if ([name isEqual: @"chapter"] == YES)
{
@ -234,6 +234,7 @@ setDirectory(NSMutableDictionary *dict, NSString *path)
}
[t setObject: tmp forKey: unit];
}
[self setGlobalRef: unit type: @"class"];
}
else if ([name isEqual: @"gsdoc"] == YES)
{
@ -355,7 +356,7 @@ setDirectory(NSMutableDictionary *dict, NSString *path)
newUnit = YES;
unit = [NSString stringWithFormat: @"(%@)",
[prop objectForKey: @"name"]];
[self setGlobalRef: unit type: name];
[self setGlobalRef: unit type: @"protocol"];
}
else if ([name isEqual: @"constant"] == YES
|| [name isEqual: @"EOEntity"] == YES
@ -515,6 +516,10 @@ setDirectory(NSMutableDictionary *dict, NSString *path)
[r setObject: base forKey: unit];
}
/**
* Return a dictionary containing info on all the units containing the
* specified method or instance variable.
*/
- (NSDictionary*) unitRef: (NSString*)ref type: (NSString*)type
{
NSDictionary *t;
@ -523,13 +528,79 @@ setDirectory(NSMutableDictionary *dict, NSString *path)
return [t objectForKey: ref];
}
- (NSString*) unitRef: (NSString*)ref type: (NSString*)type unit: (NSString*)u
/**
* Return the name of the file containing the ref and return
* the unit name in which it was found. If not found, return nil for both.
*/
- (NSString*) unitRef: (NSString*)ref type: (NSString*)type unit: (NSString**)u
{
NSString *s;
NSDictionary *t;
t = [refs objectForKey: type];
t = [t objectForKey: ref];
return [t objectForKey: u];
/**
* If ref does not occur in the index, this method returns nil.
*/
t = [self unitRef: ref type: type];
if (t == nil)
{
*u = nil;
return nil;
}
if (*u == nil)
{
/**
* If the method was given no unit to look in, then it will succeed
* and return a value if (and only if) the required reference is
* defined only in one unit.
*/
if ([t count] == 1)
{
*u = [[t allKeys] lastObject];
return [t objectForKey: *u];
}
return nil;
}
/**
* If ref exists in the unit specified, the method will succeed and
* return the name of the file in which the reference is located.
*/
s = [t objectForKey: *u];
if (s != nil)
{
return s;
}
/**
* If the unit that the method has been asked to look in is a
* category or protocol which is not found, the lookup must fail.
*/
if ([t objectForKey: *u] == nil
&& ([*u length] == 0 || [*u characterAtIndex: [*u length] - 1] == ')'))
{
*u = nil;
return nil;
}
/**
* If the unit is a class, and ref was not found in it, then this
* method will succeed if ref can be found in any superclass of the class.
*/
while (*u != nil)
{
*u = [self globalRef: *u type: @"super"];
if (*u != nil)
{
s = [t objectForKey: *u];
if (s != nil)
{
return s;
}
}
}
return nil;
}
@end

View file

@ -353,6 +353,7 @@ main(int argc, char **argv, char **env)
BOOL modifiedRefs = NO;
NSDate *rDate = nil;
NSMutableArray *files = nil;
NSMutableArray *hFiles = nil;
CREATE_AUTORELEASE_POOL(outer);
CREATE_AUTORELEASE_POOL(pool);
@ -447,6 +448,7 @@ main(int argc, char **argv, char **env)
* Build an array of files to be processed.
*/
files = AUTORELEASE([[proc arguments] mutableCopy]);
hFiles = [NSMutableArray array];
[files removeObjectAtIndex: 0];
for (i = 0; i < [files count]; i++)
{
@ -463,13 +465,21 @@ main(int argc, char **argv, char **env)
&& [arg hasSuffix: @".m"] == NO
&& [arg hasSuffix: @".gsdoc"] == NO)
{
// Skip this value ... not a known file type.
NSLog(@"Unknown argument '%@' ... ignored", arg);
if ([arg hasSuffix: @".html"] == YES)
{
// Make a note of any html files found.
[hFiles addObject: [files objectAtIndex: i]];
}
else
{
// Skip this value ... not a known file type.
NSLog(@"Unknown argument '%@' ... ignored", arg);
}
[files removeObjectAtIndex: i];
i--;
}
}
if ([files count] < 1)
if ([files count] < 1 && [hFiles count] < 1)
{
NSLog(@"No filename arguments found ... giving up");
return 1;
@ -829,13 +839,14 @@ main(int argc, char **argv, char **env)
RELEASE(pool);
if (generateHtml == YES)
/*
* If we are either generating html output, or relocating existing
* html documents, we must build up the indexing information needed
* for any cross-referencing etc.
*/
if (generateHtml == YES || [hFiles count] > 0)
{
/*
* Second pass ... generate html output from gsdoc files.
*/
pool = [NSAutoreleasePool new];
/*
* Merge any external project references into the
* main cross reference index.
@ -967,6 +978,13 @@ main(int argc, char **argv, char **env)
[globalRefs mergeRefs: [projectRefs refs] override: YES];
RELEASE(pool);
}
/*
* Next pass ... generate html output from gsdoc files if required.
*/
if (generateHtml == YES)
{
pool = [NSAutoreleasePool new];
for (i = 0; i < [files count]; i++)
@ -1083,6 +1101,187 @@ main(int argc, char **argv, char **env)
RELEASE(pool);
}
/*
* Relocate existing html documents if required ... adjust all cross
* referencing within those documents.
*/
if ([hFiles count] > 0)
{
pool = [NSAutoreleasePool new];
for (i = 0; i < [hFiles count]; i++)
{
NSString *file = [hFiles objectAtIndex: i];
NSString *src;
NSString *dst;
NSString *sdir;
NSString *ddir;
if (pool != nil)
{
RELEASE(pool);
pool = [NSAutoreleasePool new];
}
file = [file lastPathComponent];
sdir = sourceDirectory;
ddir = documentationDirectory;
src = [sdir stringByAppendingPathComponent: file];
dst = [ddir stringByAppendingPathComponent: file];
/*
* If we can't find the file in the source directory, assume
* it is in the ddocumentation directory already, and just needs
* cross-refs rebuilding.
*/
if ([mgr isReadableFileAtPath: src] == NO)
{
src = dst;
}
if ([mgr isReadableFileAtPath: src] == YES)
{
NSMutableString *s;
NSRange r;
unsigned l;
unsigned p;
AGSHtml *html;
html = AUTORELEASE([AGSHtml new]);
[html setGlobalRefs: globalRefs];
[html setProjectRefs: projectRefs];
[html setLocalRefs: nil];
s = [NSMutableString stringWithContentsOfFile: src];
l = [s length];
p = 0;
r = NSMakeRange(p, l);
r = [s rangeOfString: @"<a rel=\"gsdoc\" href=\""
options: NSLiteralSearch
range: r];
while (r.length > 0)
{
NSRange replace;
NSString *repstr;
NSString *href;
NSString *type;
NSString *unit = nil;
replace.location = r.location;
p = NSMaxRange(r);
r = [s rangeOfString: @"\">"
options: NSLiteralSearch
range: NSMakeRange(p, l - p)];
if (r.length == 0)
{
NSLog(@"Unterminated gsdoc rel at %u", p);
break;
}
else
{
replace = NSMakeRange(replace.location,
r.location - replace.location);
href = [s substringWithRange:
NSMakeRange(p, r.location - p)];
p = NSMaxRange(replace);
}
/*
* Skip past the '#' to the local reference.
*/
r = [href rangeOfString: @"#"
options: NSLiteralSearch];
if (r.length == 0)
{
NSLog(@"Missing '#' in href at %u", replace.location);
break;
}
href = [href substringFromIndex: NSMaxRange(r)];
/*
* Split out the reference type information.
*/
r = [href rangeOfString: @"$"
options: NSLiteralSearch];
if (r.length == 0)
{
NSLog(@"Missing '$' in href at %u", replace.location);
break;
}
type = [href substringToIndex: r.location];
href = [href substringFromIndex: NSMaxRange(r)];
/*
* Parse unit name from method or instance variable link.
*/
if ([type isEqual: @"method"] == YES
|| [type isEqual: @"ivariable"] == YES)
{
if ([type isEqual: @"method"] == YES)
{
r = [href rangeOfString: @"-"
options: NSLiteralSearch];
if (r.length == 0)
{
r = [href rangeOfString: @"+"
options: NSLiteralSearch];
}
if (r.length > 0)
{
unit = [href substringToIndex: r.location];
href = [href substringFromIndex: NSMaxRange(r)-1];
}
}
else
{
r = [href rangeOfString: @"*"
options: NSLiteralSearch];
if (r.length > 0)
{
unit = [href substringToIndex: r.location];
href = [href substringFromIndex: NSMaxRange(r)];
}
}
if (unit == nil)
{
NSLog(@"Missing unit name terminator at %u",
replace.location);
break;
}
}
if (unit == nil)
{
repstr = [html makeLink: href
ofType: type
isRef: YES];
}
else
{
repstr = [html makeLink: href
ofType: type
inUnit: unit
isRef: YES];
}
if (repstr != nil)
{
p += ([repstr length] - replace.length);
[s replaceCharactersInRange: replace withString: repstr];
}
r = [s rangeOfString: @"<a rel=\"gsdoc\" href=\""
options: NSLiteralSearch
range: NSMakeRange(p, l - p)];
}
}
else
{
NSLog(@"No readable documentation at '%@' ... skipping", src);
}
}
RELEASE(pool);
}
RELEASE(outer);
return 0;
}