mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-09-17 08:01:27 +00:00
Merge pull request #1270 from aparajita/cappuccino
--- - Worked around a major bug in doxygen. It turns out that doxygen would not generate documentation for the first method -- or sometimes all methods (e.g. CPPredicate) -- if the ivar block for a class was missing or empty. This is solved now by inserting a dummy __doxygen__ ivar block. - Missed a text substitution - Darkened up the method header a bit to make it easier for the eye to anchor on. - Changed to centered, fixed-width layout, it results in shorter line lengths which reads more easily. - Moved support files to separate support directory. - Removed blank lines at end of multi-parameter method prototypes. - Fixed font declaration so fonts are correct in FireFox. - Added spacing between parameter descriptions in method prototype. - Fixed formatting of class description for CPPredicate. - Added a missing @endverbatim to CPExpression.j.
This commit is contained in:
@@ -71,9 +71,12 @@ CPMinusSetExpressionType = 9;
|
||||
@class CPExpression
|
||||
@brief CPExpression is used to represent expressions in a predicate.
|
||||
|
||||
Comparison operations in an CPPredicate are based on two expressions, as represented by instances of the CPExpression class. Expressions are created for constant values, key paths, and so on.
|
||||
Comparison operations in an CPPredicate are based on two expressions, as represented by instances of the CPExpression class.
|
||||
Expressions are created for constant values, key paths, and so on.
|
||||
|
||||
Generally, anywhere in the CPExpression class hierarchy where there is composite API and subtypes that may only reasonably respond to a subset of that API, invoking a method that does not make sense for that subtype will cause an exception to be thrown.
|
||||
Generally, anywhere in the CPExpression class hierarchy where there is composite API and subtypes
|
||||
that may only reasonably respond to a subset of that API, invoking a method that does not make sense
|
||||
for that subtype will cause an exception to be thrown.
|
||||
*/
|
||||
|
||||
@implementation CPExpression : CPObject
|
||||
@@ -182,12 +185,15 @@ CPMinusSetExpressionType = 9;
|
||||
Returns a new expression that will invoke one of the predefined functions.
|
||||
@param function_name The name of the function to invoke.
|
||||
@param parameters An array containing CPExpression objects that will be used as parameters during the invocation of selector.
|
||||
|
||||
For a selector taking no parameters, the array should be empty. For a selector taking one or more parameters, the array should contain one CPExpression object which will evaluate to an instance of the appropriate type for each parameter.
|
||||
|
||||
If there is a mismatch between the number of parameters expected and the number you provide during evaluation, an exception may be raised or missing parameters may simply be replaced by nil (which occurs depends on how many parameters are provided, and whether you have over- or underflow).
|
||||
@return A new expression that invokes the function name using the parameters in parameters.
|
||||
|
||||
For a selector taking no parameters, the array should be empty. For a selector taking one or more parameters,
|
||||
the array should contain one CPExpression object which will evaluate to an instance of the appropriate type for each parameter.
|
||||
|
||||
If there is a mismatch between the number of parameters expected and the number you provide during evaluation,
|
||||
an exception may be raised or missing parameters may simply be replaced by nil (which occurs depends on how many
|
||||
parameters are provided, and whether you have over- or underflow).
|
||||
|
||||
The name parameter can be one of the following predefined functions:
|
||||
@verbatim
|
||||
name parameter array contents returns
|
||||
@@ -220,6 +226,7 @@ CPMinusSetExpressionType = 9;
|
||||
now: none [CPDate now]
|
||||
|
||||
This method raises an exception immediately if the selector is invalid; it raises an exception at runtime if the parameters are incorrect.
|
||||
@endverbatim
|
||||
*/
|
||||
+ (CPExpression)expressionForFunction:(CPString)function_name arguments:(CPArray)parameters
|
||||
{
|
||||
@@ -232,7 +239,8 @@ CPMinusSetExpressionType = 9;
|
||||
@param selectorName The name of the method to be invoked.
|
||||
@param parameters An array containing CPExpression objects which can be evaluated to provide parameters for the method specified by name.
|
||||
@return An expression which will return the result of invoking the selector named name on the result of evaluating the target expression with the parameters specified by evaluating the elements of parameters.
|
||||
See the description of expressionForFunction:arguments: for examples of how to construct the parameter array.
|
||||
|
||||
See the description of \c expressionForFunction:arguments: for examples of how to construct the parameter array.
|
||||
*/
|
||||
+ (CPExpression)expressionForFunction:(CPExpression)target selectorName:(CPString)selectorName arguments:(CPArray)parameters
|
||||
{
|
||||
|
||||
@@ -36,21 +36,26 @@
|
||||
@class CPPredicate
|
||||
@brief The CPPredicate class is used to define logical conditions used to constrain a search either for a fetch or for in-memory filtering.
|
||||
|
||||
You use predicates to represent logical conditions, used for describing objects in persistent stores and in-memory filtering of objects. Although it is common to create predicates directly from instances of CPComparisonPredicate, CPCompoundPredicate, and CPExpression, you often create predicates from a format string which is parsed by the class methods on CPPredicate. Examples of predicate format strings include:
|
||||
You use predicates to represent logical conditions, used for describing objects in persistent stores
|
||||
and in-memory filtering of objects. Although it is common to create predicates directly from instances
|
||||
of CPComparisonPredicate, CPCompoundPredicate, and CPExpression, you often create predicates from a
|
||||
format string which is parsed by the class methods on CPPredicate. Examples of predicate format strings include:
|
||||
|
||||
Simple comparisons, such as grade == "7" or firstName like "Shaffiq"\n
|
||||
Case/diacritic insensitive lookups, such as name contains[cd] "itroen"\n
|
||||
Logical operations, such as (firstName like "Mark") OR (lastName like "Adderley")\n
|
||||
“Between” predicates such as date between {$YESTERDAY, $TOMORROW}.\n
|
||||
- Simple comparisons, such as <code>grade == "7"</code> or <code>firstName like "Shaffiq"</code>
|
||||
- Case/diacritic insensitive lookups, such as <code>name contains[cd] "itroen"</code>
|
||||
- Logical operations, such as <code>(firstName like "Mark") OR (lastName like "Adderley")</code>
|
||||
- “Between” predicates such as <code>date between {$YESTERDAY, $TOMORROW}</code>.
|
||||
|
||||
You can create predicates for relationships, such as:
|
||||
|
||||
group.name like "work*"\n
|
||||
ALL children.age > 12\n
|
||||
ANY children.age > 12\n
|
||||
You can create predicates for operations, such as @sum.items.price < 1000.
|
||||
- <code>group.name like "work*"</code>
|
||||
- <code>ALL children.age > 12</code>
|
||||
- <code>ANY children.age > 12</code>
|
||||
|
||||
You can also create predicates that include variables, so that the predicate can be pre-defined before substituting concrete values at runtime with evaluateWithObject:substitutionVariables: method.
|
||||
You can create predicates for operations, such as <code>\@sum.items.price < 1000</code>.
|
||||
|
||||
You can also create predicates that include variables, so that the predicate can be pre-defined before
|
||||
substituting concrete values at runtime with the \c evaluateWithObject:substitutionVariables: method.
|
||||
*/
|
||||
|
||||
@implementation CPPredicate : CPObject
|
||||
|
||||
@@ -6,7 +6,7 @@ body, table, td, div, p, dl, dd, dt, em {
|
||||
}
|
||||
|
||||
body, table, div, p {
|
||||
font: 13px normal "Lucida Grande", Helvetica, Arial, Geneva, sans-serif;
|
||||
font: normal 13px "Lucida Grande", Helvetica, Arial, Geneva, sans-serif;
|
||||
}
|
||||
|
||||
table {
|
||||
@@ -18,7 +18,7 @@ pre, code {
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 1em 0;
|
||||
margin: 0 0 1em 0;
|
||||
}
|
||||
|
||||
dl {
|
||||
@@ -47,7 +47,7 @@ em {
|
||||
|
||||
h1, h2, h3, h4 {
|
||||
font-family: "Lucida Grande", Helvetica, Arial, Geneva, sans-serif;
|
||||
margin: 2em 0 1em 0;
|
||||
margin: 1.5em 0 .5em;
|
||||
}
|
||||
|
||||
h1 {
|
||||
@@ -109,17 +109,15 @@ div.qindex, div.navtab {
|
||||
background-color: #ECEFF6;
|
||||
border: 1px solid #A4B5D6;
|
||||
text-align: center;
|
||||
margin: 2px;
|
||||
padding: 2px;
|
||||
padding: .25em;
|
||||
}
|
||||
|
||||
div.qindex, div.navpath {
|
||||
width: 100%;
|
||||
line-height: 140%;
|
||||
}
|
||||
|
||||
div.qindex+table {
|
||||
margin: 1.5em;
|
||||
div.contents div.qindex+table {
|
||||
margin: 1.5em 15px;
|
||||
}
|
||||
|
||||
div.qindex+table td {
|
||||
@@ -238,12 +236,32 @@ body {
|
||||
}
|
||||
|
||||
div.contents {
|
||||
margin: 1.5em;
|
||||
width: 1024px;
|
||||
margin: auto;
|
||||
border: 1px solid #eee;
|
||||
border-width: 0 1px;
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
/* If the first element of the contents is a table, give it some space */
|
||||
div.contents > table {
|
||||
margin-top: 1.5em;
|
||||
margin: 1.5em 0 0;
|
||||
}
|
||||
|
||||
div.contents > p,
|
||||
div.contents > h1,
|
||||
div.contents > h2,
|
||||
div.contents > dl,
|
||||
.dynheader,
|
||||
.dynsummary,
|
||||
.dyncontent {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
div.contents hr {
|
||||
margin-left: -15px;
|
||||
margin-right: -15px;
|
||||
}
|
||||
|
||||
td.indexkey {
|
||||
@@ -262,10 +280,6 @@ td.indexvalue {
|
||||
padding: .25em 0 .25em .5em;
|
||||
}
|
||||
|
||||
table tr.memlist:first-child td {
|
||||
padding-top: 1.5em;
|
||||
}
|
||||
|
||||
table tr.memlist > td {
|
||||
padding-left: .5em;
|
||||
}
|
||||
@@ -405,6 +419,7 @@ hr {
|
||||
|
||||
hr.footer {
|
||||
height: 1px;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
/* @group Member Descriptions */
|
||||
@@ -413,6 +428,7 @@ table.memberdecls {
|
||||
font-family: Consolas, "Lucida Console";
|
||||
border-spacing: 0px;
|
||||
padding: 0px;
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.mdescLeft, .mdescRight,
|
||||
@@ -470,21 +486,22 @@ table.memberdecls {
|
||||
.memname {
|
||||
white-space: nowrap;
|
||||
font: bold 105% Consolas, "Lucida Console";
|
||||
margin: .25em 0 0 .25em;
|
||||
margin: .25em 0 .1em .25em;
|
||||
}
|
||||
|
||||
.memproto {
|
||||
margin-top: 2em;
|
||||
margin: 2em -15px 0;
|
||||
border-top: 1px solid #ccc;
|
||||
padding: 6px 0px 6px 0px;
|
||||
padding: 6px 15px;
|
||||
color: #253554;
|
||||
background-color: #fbfbfb;
|
||||
background-color: #f7f7f7;
|
||||
font-family: Consolas, "Lucida Console";
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.memdoc {
|
||||
padding: .5em .5em 0;
|
||||
margin: 0 -15px;
|
||||
padding: .5em 15px 0;
|
||||
}
|
||||
|
||||
.memdoc > p {
|
||||
@@ -493,6 +510,11 @@ table.memberdecls {
|
||||
|
||||
.memdoc dl dd td {
|
||||
padding-right: 1em;
|
||||
padding-top: .5em;
|
||||
}
|
||||
|
||||
.memdoc dl dd table tr:first-child td {
|
||||
padding-top: 0;
|
||||
}
|
||||
|
||||
.memdoc dl dd table tr td:first-child {
|
||||
@@ -621,7 +643,15 @@ table.memberdecls {
|
||||
/* @end */
|
||||
|
||||
div.dynheader {
|
||||
margin-top: 8px;
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
div.dynheader.closed {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
div.dyncontent {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
address {
|
||||
@@ -700,7 +730,6 @@ div.summary
|
||||
{
|
||||
float: right;
|
||||
font-size: 90%;
|
||||
padding-right: 5px;
|
||||
width: 50%;
|
||||
text-align: right;
|
||||
}
|
||||
@@ -715,9 +744,12 @@ div.header
|
||||
background-image:url('nav_h.png');
|
||||
background-repeat:repeat-x;
|
||||
background-color: #F9FAFC;
|
||||
margin: 0;
|
||||
padding: 1.5em;
|
||||
width: 1024px;
|
||||
margin: 0 auto;
|
||||
padding: 1.5em 15px;
|
||||
border-bottom: 1px solid #C5CFE5;
|
||||
border-left: 1px solid #eee;
|
||||
border-right: 1px solid #eee;
|
||||
}
|
||||
|
||||
div.headertitle h1 {
|
||||
@@ -728,7 +760,6 @@ div.headertitle h1 {
|
||||
|
||||
.tabs, .tabs2, .tabs3 {
|
||||
background-image: url('tab_b.png');
|
||||
width: 100%;
|
||||
z-index: 101;
|
||||
font-size: 100%;
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
# $2 Generated documentation directory
|
||||
|
||||
# Do this if you want to use the utility functions
|
||||
source "$1"/processor_setup.sh
|
||||
source "$1"/support/processor_setup.sh
|
||||
|
||||
# Cleanup the files we generated to feed to doxygen
|
||||
processor_msg "Cleaning up generated header files..."
|
||||
|
||||
@@ -6,12 +6,7 @@
|
||||
# $2 Generated documentation directory
|
||||
|
||||
# Do this if you want to use the utility functions
|
||||
source "$1"/processor_setup.sh
|
||||
|
||||
# The following transforms are performed:
|
||||
# - Strip useless "[implementation]" littering the docs
|
||||
# - Change "Static Public Member Functions" to "Class Methods"
|
||||
# - Change "Public Member Functions" to "Instance Methods"
|
||||
source "$1"/support/processor_setup.sh
|
||||
|
||||
if [ ! -d "$2" ]; then
|
||||
exit 0
|
||||
@@ -19,9 +14,4 @@ fi
|
||||
|
||||
processor_msg 'Massaging text...'
|
||||
|
||||
sed -i '' -E \
|
||||
-e 's/<code> \[implementation\]<\/code>/\ /g' \
|
||||
-e 's/Static Public Member Functions/Class Methods/g' \
|
||||
-e 's/Public Member Functions/Instance Methods/g' \
|
||||
-e 's/(AppKit|Foundation)\.doc/\1/g' \
|
||||
"$2"/*.html
|
||||
exec "$1"/support/massage_text.py "$2"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
# $1 Cappuccino documentation directory
|
||||
|
||||
# Do this if you want to use the utility functions
|
||||
source "$1"/processor_setup.sh
|
||||
source "$1"/support/processor_setup.sh
|
||||
|
||||
markdown=`which markdown`
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
# $1 Cappuccino documentation directory
|
||||
|
||||
# Do this if you want to use the utility functions
|
||||
source "$1"/processor_setup.sh
|
||||
source "$1"/support/processor_setup.sh
|
||||
|
||||
if [ -d AppKit.doc ]; then
|
||||
rm -rf AppKit.doc
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
ACCESSOR_GET_TEMPLATE = <<EOS
|
||||
/*!
|
||||
Synthesized accessor method.
|
||||
Synthesized accessor method.
|
||||
*/
|
||||
- (\#{ivarType})\#{getter}
|
||||
{
|
||||
@@ -18,7 +18,7 @@ EOS
|
||||
|
||||
ACCESSOR_SET_TEMPLATE = <<EOS
|
||||
/*!
|
||||
Synthesized accessor method.
|
||||
Synthesized accessor method.
|
||||
*/
|
||||
- (void)\#{setter}:(\#{ivarType})aValue
|
||||
{
|
||||
@@ -34,109 +34,124 @@ ACCESSORS_IMPLEMENTATION_TEMPLATE = <<EOS
|
||||
\#{accessorsSource}@end
|
||||
EOS
|
||||
|
||||
DUMMY_IVAR = " id __doxygen__;"
|
||||
|
||||
|
||||
def makeHeaderFileFrom(fileName)
|
||||
# Grab the entire file (text)
|
||||
sourceFile = File.new(fileName, "r")
|
||||
source = sourceFile.read
|
||||
sourceFile.close()
|
||||
# Grab the entire file (text)
|
||||
sourceFile = File.new(fileName, "r")
|
||||
source = sourceFile.read
|
||||
sourceFile.close()
|
||||
|
||||
# Remove @accessor declarations from ivars in the source file
|
||||
sourceFile = File.new(fileName, "w")
|
||||
sourceFile.write(source.gsub(/(\s*\w+\s+\w+)\s+@accessors(\(.+?\))?;/m, "\\1;"))
|
||||
# If an implementation does not have an ivar block or an empty ivar block,
|
||||
# an one with a dummy ivar so that doxygen will parse the file correctly.
|
||||
source.gsub!(/^\s*(@implementation \s*\w+(?:\s*:\s*\w+)?)\n(\s*[^{])/, "\\1\n{\n#{DUMMY_IVAR}\n}\n\\2")
|
||||
source.gsub!(/^\s*(@implementation \s*\w+(?:\s*:\s*\w+)?)\n\s*\{\s*\}/, "\\1\n{\n#{DUMMY_IVAR}\n}")
|
||||
|
||||
# Extract all the @implementations blocks. Note, there may be
|
||||
# more than on in a given .j file.
|
||||
m = source.scan(/^\s*(@implementation\s*(\w+)\s*:\s*\w+\s*\{(.*?)\}).*?^\s*@end\s*$/m)
|
||||
sourceFile = File.new(fileName, "w")
|
||||
|
||||
return if m.length == 0
|
||||
# Remove @accessor declarations from ivars before writing the source file
|
||||
sourceFile.write(source.gsub(/(\s*\w+\s+\w+)\s+@accessors(\(.+?\))?;/m, "\\1;"))
|
||||
|
||||
for i in 0...m.length
|
||||
groups = m[i]
|
||||
declaration = groups[0]
|
||||
className = groups[1]
|
||||
ivars = groups[2]
|
||||
# Extract all the @implementations blocks. Note, there may be more than one in a given .j file.
|
||||
m = source.scan(/^\s*(@implementation\s*(\w+)\s*(?::\s*\w+)?)\s*(?:\{(.*?)\})?(.*?)^\s*@end\s*$/m)
|
||||
|
||||
# Change "implementation" to "interface", create the .h file, and write the interface
|
||||
newDeclaration = declaration.sub("@implementation", "@interface")
|
||||
newFileName = File.dirname(fileName) + "/" + className + ".h"
|
||||
f = File.new(newFileName, "a")
|
||||
return if m.length == 0
|
||||
|
||||
# Change @accessors declarations to a comment, doxygen chokes on them
|
||||
f.write("\n" + newDeclaration.gsub(/(\s*\w+\s+\w+)\s+(@accessors.*?);/m, "\\1; // \\2") + "\n@end\n")
|
||||
f.close()
|
||||
for i in 0...m.length
|
||||
groups = m[i]
|
||||
declaration = groups[0]
|
||||
className = groups[1]
|
||||
ivars = groups[2]
|
||||
|
||||
# Skip @accessors parsing for private classes
|
||||
next if className[0, 1] == "_"
|
||||
# Change "implementation" to "interface", create the .h file, and write the interface
|
||||
interfaceDeclaration = declaration.sub("@implementation", "@interface")
|
||||
interfaceFileName = File.dirname(fileName) + "/" + className + ".h"
|
||||
interfaceFile = File.new(interfaceFileName, "a")
|
||||
|
||||
# Everything after this is ivar processing
|
||||
next unless ivars
|
||||
|
||||
# Change @accessors declarations to a comment, doxygen chokes on them
|
||||
strippedIvars = ivars.gsub("@accessors", "// @accessors")
|
||||
interfaceFile.write("\n#{interfaceDeclaration}\n{#{strippedIvars}}\n@end\n")
|
||||
|
||||
# Skip @accessors if it's a private class
|
||||
next if className[0, 1] == "_"
|
||||
|
||||
writeAccessors(className, ivars, sourceFile, interfaceFile)
|
||||
end
|
||||
|
||||
sourceFile.close()
|
||||
end
|
||||
|
||||
def writeAccessors(className, ivars, sourceFile, interfaceFile)
|
||||
# See if there are any @accessors in the ivars
|
||||
accessorsMatches = ivars.scan(/\s*(\w+)\s+(\w+)\s+@accessors(\(.+?\))?;/m)
|
||||
next if accessorsMatches.length == 0
|
||||
return if accessorsMatches.length == 0
|
||||
|
||||
accessorsSource = ""
|
||||
accessorsInterface = ""
|
||||
|
||||
# Create a CPSynthesizedAccessor category for the class with synthesized
|
||||
# accessor methods for each @accessors declaration.
|
||||
for accessorIndex in 0...accessorsMatches.length
|
||||
ivarDeclaration = accessorsMatches[accessorIndex]
|
||||
attributes = ivarDeclaration[2]
|
||||
next if attributes.nil?
|
||||
ivarType = ivarDeclaration[0];
|
||||
ivar = ivarDeclaration[1];
|
||||
ivarDeclaration = accessorsMatches[accessorIndex]
|
||||
attributes = ivarDeclaration[2]
|
||||
next if attributes.nil?
|
||||
ivarType = ivarDeclaration[0];
|
||||
ivar = ivarDeclaration[1];
|
||||
|
||||
attributesMatch = attributes.scan(/(\bproperty\s*=\s*(\w+)|\b(readonly)\b|\bgetter\s*=\s*(\w+)|\bsetter\s*=\s*(\w+))/m)
|
||||
next if attributesMatch.length == 0
|
||||
attributesMatch = attributes.scan(/(\bproperty\s*=\s*(\w+)|\b(readonly)\b|\bgetter\s*=\s*(\w+)|\bsetter\s*=\s*(\w+))/m)
|
||||
next if attributesMatch.length == 0
|
||||
|
||||
getter = nil
|
||||
setter = nil
|
||||
readonly = false
|
||||
getter = nil
|
||||
setter = nil
|
||||
readonly = false
|
||||
|
||||
for attributeIndex in 0...attributesMatch.length
|
||||
if not attributesMatch[attributeIndex][1].nil? # property
|
||||
getter = attributesMatch[attributeIndex][1]
|
||||
setter = readonly ? nil : "set#{getter[0,1].upcase}#{getter[1..-1]}"
|
||||
elsif not attributesMatch[attributeIndex][2].nil? # readonly
|
||||
readonly = true
|
||||
setter = nil
|
||||
elsif not attributesMatch[attributeIndex][3].nil? # getter
|
||||
getter = attributesMatch[attributeIndex][3]
|
||||
elsif not attributesMatch[attributeIndex][4].nil? and not readonly # setter
|
||||
setter = attributesMatch[attributeIndex][4]
|
||||
for attributeIndex in 0...attributesMatch.length
|
||||
if not attributesMatch[attributeIndex][1].nil? # property
|
||||
getter = attributesMatch[attributeIndex][1]
|
||||
setter = readonly ? nil : "set#{getter[0,1].upcase}#{getter[1..-1]}"
|
||||
elsif not attributesMatch[attributeIndex][2].nil? # readonly
|
||||
readonly = true
|
||||
setter = nil
|
||||
elsif not attributesMatch[attributeIndex][3].nil? # getter
|
||||
getter = attributesMatch[attributeIndex][3]
|
||||
elsif not attributesMatch[attributeIndex][4].nil? and not readonly # setter
|
||||
setter = attributesMatch[attributeIndex][4]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Check for @accessors with no attributes
|
||||
if getter.nil? and setter.nil?
|
||||
getter = ivar
|
||||
setter = "set#{getter[0,1].upcase}#{getter[1..-1]}"
|
||||
end
|
||||
# Check for @accessors with no attributes
|
||||
if getter.nil? and setter.nil?
|
||||
getter = ivar
|
||||
setter = "set#{getter[0,1].upcase}#{getter[1..-1]}"
|
||||
end
|
||||
|
||||
accessorsSource += makeAccessors(getter, setter, ivar, ivarType)
|
||||
accessorsSource += makeAccessors(getter, setter, ivar, ivarType)
|
||||
end
|
||||
|
||||
sourceFile.write(eval('"' + ACCESSORS_IMPLEMENTATION_TEMPLATE + '"'))
|
||||
end
|
||||
|
||||
sourceFile.close()
|
||||
end
|
||||
|
||||
def makeAccessors(getter, setter, ivar, ivarType)
|
||||
accessors = ""
|
||||
accessors = ""
|
||||
|
||||
if not getter.nil?
|
||||
accessors += eval('"' + ACCESSOR_GET_TEMPLATE + '"')
|
||||
end
|
||||
if not getter.nil?
|
||||
accessors += eval('"' + ACCESSOR_GET_TEMPLATE + '"')
|
||||
end
|
||||
|
||||
if not setter.nil?
|
||||
accessors += eval('"' + ACCESSOR_SET_TEMPLATE + '"')
|
||||
end
|
||||
if not setter.nil?
|
||||
accessors += eval('"' + ACCESSOR_SET_TEMPLATE + '"')
|
||||
end
|
||||
|
||||
return accessors
|
||||
return accessors
|
||||
end
|
||||
|
||||
print "\033[36mGenerating header files...\033[0m\n"
|
||||
fileList = Dir['AppKit.doc/**/*.j'] + Dir['Foundation.doc/**/*.j']
|
||||
|
||||
for fileName in fileList
|
||||
makeHeaderFileFrom(fileName)
|
||||
makeHeaderFileFrom(fileName)
|
||||
end
|
||||
|
||||
Executable
+42
@@ -0,0 +1,42 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# $1 Generated documentation directory
|
||||
|
||||
# The following transforms are performed:
|
||||
# - Strip useless "[implementation]" littering the docs
|
||||
# - Change "Static Public Member Functions" to "Class Methods"
|
||||
# - Change "Public Member Functions" to "Instance Methods"
|
||||
# - Change "Member Function Documentation" to "Method Documentation"
|
||||
# - Remove empty line left at the end of multi-parameter method prototypes
|
||||
|
||||
import glob
|
||||
import os.path
|
||||
import re
|
||||
import sys
|
||||
|
||||
transforms = [
|
||||
re.compile(r"<code> \[implementation\]</code>"), " ",
|
||||
re.compile(r"Static Public Member Functions"), "Class Methods",
|
||||
re.compile(r"Public Member Functions"), "Instance Methods",
|
||||
re.compile(r"Protected Attributes"), "Instance Variables",
|
||||
re.compile(r"Member Function Documentation"), "Method Documentation",
|
||||
re.compile(r"Member Data Documentation"), "Instance Variable Documentation",
|
||||
re.compile(r"(AppKit|Foundation)\.doc"), r"\1",
|
||||
re.compile(r"\s*<tr>\n(\s*<td></td>\n){2}\s*(<td></td>){2}<td> </td>\n\s*</tr>"), ""
|
||||
]
|
||||
|
||||
html = glob.glob(os.path.join(sys.argv[1], "*.html"))
|
||||
|
||||
for count, filename in enumerate(html):
|
||||
f = open(filename, "r+")
|
||||
text = f.read()
|
||||
i = 0
|
||||
|
||||
while i < len(transforms):
|
||||
text = transforms[i].sub(transforms[i + 1], text)
|
||||
i += 2
|
||||
|
||||
f.seek(0)
|
||||
f.truncate()
|
||||
f.write(text)
|
||||
f.close()
|
||||
Reference in New Issue
Block a user