-
Notifications
You must be signed in to change notification settings - Fork 2
/
DocTOCPage.m
199 lines (164 loc) · 7.11 KB
/
DocTOCPage.m
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
/*
Copyright (C) 2010 Quentin Mathe
Authors: Quentin Mathe <quentin.mathe@gmail.com>
Date: December 2010
License: Modified BSD (see COPYING)
*/
#import "DocTOCPage.h"
#import "DocHeader.h"
#import "DocCDataType.h"
#import "DocFunction.h"
#import "DocIndex.h"
#import "DocMethod.h"
#import "GSDocParser.h"
#import "DocHTMLElement.h"
#import "DocGraphWriter.h"
@interface DocPage (Private)
- (void) addElement: (DocElement *)anElement toDictionaryNamed: (NSString *)anIvarName forKey: (NSString *)aKey;
- (ETKeyValuePair *) firstPairWithKey: (NSString *)aKey inArray: (NSArray *)anArray;
@end
@implementation DocTOCPage
- (DocHTMLElement *) HTMLRepresentationForHeader: (DocHeader *)aHeader
{
/* Pack title and overview in a header html element */
H hMeta = [DIV class: @"meta" with: [P class: @"metadesc" with: [EM with: [aHeader abstract]]]];
return [DIV class: @"header" with: [H2 with: [aHeader title]]
and: hMeta
and: [aHeader HTMLOverviewRepresentation]];
}
/* DocPageWeaver inserts the subheaders out of order, and before also their group
name is parsed and set. */
- (void) sortSubheaders
{
NSArray *elementArrays = [subheaders valueForKey: @"value"];
NSMutableArray *elements = [NSMutableArray array];
// TODO: We should use a -flattenedCollection or similar
for (NSArray *groupedElements in elementArrays)
{
[elements addObjectsFromArray: groupedElements];
}
NSSortDescriptor *groupSortDesc = [[NSSortDescriptor alloc] initWithKey: @"group" ascending: YES];
NSSortDescriptor *nameSortDesc = [[NSSortDescriptor alloc] initWithKey: @"name" ascending: YES];
[elements sortedArrayUsingDescriptors: [NSArray arrayWithObjects: groupSortDesc, nameSortDesc, nil]];
[subheaders removeAllObjects];
for (DocHeader *element in elements)
{
[self addElement: element toDictionaryNamed: @"subheaders" forKey: [element group]];
}
}
/* I renamed GraphWriter class (.h & .m) to DocGraphWriter. */
- (void) addCategoryNodeNamed: (NSString *)categoryName
className: (NSString *)className
protocolNames: (NSArray *)adoptedProtocolNames
toGraphWriter: (DocGraphWriter *)writer
{
if (categoryName == nil)
return;
[writer addNode: categoryName];
[writer setAttribute: @"URL"
with: [[DocHTMLIndex currentIndex] linkForSymbolName: categoryName ofKind: @"categories"]
on: categoryName];
[writer setAttribute: @"shape" with: @"parallelogram" on: categoryName];
[writer addEdge: categoryName to: className];
for (NSString *adoptedProtocolName in adoptedProtocolNames)
{
[writer addEdge: categoryName to: adoptedProtocolName];
}
}
/* I renamed GraphWriter class (.h & .m) to DocGraphWriter. */
- (void) addProtocolNodeNamed: (NSString *)protocolName
protocolNames: (NSArray *)adoptedProtocolNames
toGraphWriter: (DocGraphWriter *)writer
{
if (protocolName == nil)
return;
[writer addNode: protocolName];
[writer setAttribute: @"URL"
with: [[DocHTMLIndex currentIndex] linkForProtocolName: protocolName]
on: protocolName];
[writer setAttribute: @"shape" with: @"circle" on: protocolName];
/* Cluster protocols together and prevent inheritance tree distortion */
[writer setAttribute: @"group" with: @"protocols" on: protocolName];
for (NSString *adoptedProtocolName in adoptedProtocolNames)
{
[writer addEdge: protocolName to: adoptedProtocolName];
}
}
/* I renamed GraphWriter class (.h & .m) to DocGraphWriter. */
- (void) addClassNodeNamed: (NSString *)className
superclassNames: (NSString *)superclassName
protocolNames: (NSArray *)protocolNames
toGraphWriter: (DocGraphWriter *)writer
{
if (className == nil)
return;
[writer addNode: className];
[writer setAttribute: @"URL"
with: [[DocHTMLIndex currentIndex] linkForClassName: className]
on: className];
[writer setAttribute: @"shape" with: @"box" on: className];
/* Cluster classes together and prevent inheritance tree distortion due to adopted protocols */
[writer setAttribute: @"group" with: @"classes" on: className];
if (superclassName != nil)
{
[writer addEdge: className to: superclassName];
}
for (NSString *protocolName in protocolNames)
{
[writer addEdge: className to: protocolName];
}
}
- (NSString *) graphImageLinkWithGroupName: (NSString *)aName elements: (NSArray *)elements
{
DocGraphWriter *writer = [DocGraphWriter new];
NSArray *visibleSuperclassNames = (id)[[elements mappedCollection] className];
/* Size to min width from Start Document global.css and some trial-and-error tests
TODO: Find out which is the precise width based on the css. */
float inchWidth = 620 / 72;
float inchHeight = 500 / 72;
[writer setGraphAttribute: @"ratio" with: @"auto"];
[writer setGraphAttribute: @"size" with: [NSString stringWithFormat: @"%0.2f, %0.2f", inchWidth, inchHeight]];
for (DocHeader *methodGroupElement in elements)
{
NSString *superclassName = [methodGroupElement superclassName];
BOOL isVisibleSuperclass = [visibleSuperclassNames containsObject: superclassName];
/* The current element can be either a class, a protocol or a category.
Each node addition methods will insert a node or return immediately. */
[self addClassNodeNamed: [methodGroupElement className]
superclassNames: (isVisibleSuperclass ? superclassName : nil)
protocolNames: [methodGroupElement adoptedProtocolNames]
toGraphWriter: writer];
[self addProtocolNodeNamed: [methodGroupElement protocolName]
protocolNames: [methodGroupElement adoptedProtocolNames]
toGraphWriter: writer];
[self addCategoryNodeNamed: [methodGroupElement categoryName]
className: [methodGroupElement className]
protocolNames: [methodGroupElement adoptedProtocolNames]
toGraphWriter: writer];
}
// FIXME: Ugly bug hacked around
if ([aName rangeOfString: @"<p>"].location != NSNotFound)
return @"";
NSString *imgName = [NSString stringWithFormat: @"graph-%@.%@", aName, @"png"];
imgName = [imgName stringByReplacingOccurrencesOfString: @" " withString: @"_"];
NSString *imgPath = [[[DocIndex currentIndex] outputDirectory] stringByAppendingPathComponent: imgName];
[writer layout];
[writer generateFile: imgPath withFormat: @"png"];
return [NSString stringWithFormat: @"<img src=\"%@\">%@</img>", imgName, [writer generateWithFormat: @"cmapx"]];
}
- (DocHTMLElement *) HTMLOverviewRepresentationForGroupNamed: (NSString *)aGroup
{
return (DocHTMLElement *)[self graphImageLinkWithGroupName: aGroup
elements: [[self firstPairWithKey: aGroup inArray: subheaders] value]];
}
- (NSArray *) mainContentHTMLRepresentations
{
[self sortSubheaders];
NSMutableArray *reps = [NSMutableArray array];
[reps addObject: [self HTMLRepresentationWithTitle: nil
elements: subheaders
HTMLRepresentationSelector: @selector(HTMLTOCRepresentation)
groupSeparator: HR]];
return reps;
}
@end