pi-revit 0.2.1 → 0.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/Revit/Tools/SearchApiDocs.cs +75 -15
package/package.json
CHANGED
|
@@ -21,16 +21,19 @@ namespace RevitBridge.Tools
|
|
|
21
21
|
{
|
|
22
22
|
private const int DefaultMaxResults = 10;
|
|
23
23
|
private const int MaxResultsCap = 50;
|
|
24
|
+
|
|
25
|
+
// The Max*Chars caps apply to the model-visible markdown only; the index and
|
|
26
|
+
// the details payload keep the full documentation text.
|
|
24
27
|
private const int MaxMarkdownChars = 6_000;
|
|
25
|
-
private const int MaxSummaryChars = 600;
|
|
26
28
|
private const int MaxRemarksChars = 600;
|
|
27
29
|
private const int MaxReturnsChars = 300;
|
|
28
30
|
private const int MaxParamDocChars = 240;
|
|
29
31
|
private const int MaxParamsPerMember = 10;
|
|
32
|
+
private const int MaxExceptionsPerMember = 8;
|
|
30
33
|
|
|
31
34
|
public string Name => "search_api_docs";
|
|
32
35
|
public string Label => "Search API Docs";
|
|
33
|
-
public string Description => "Search the offline Revit API documentation (the RevitAPI.xml and RevitAPIUI.xml files shipped with Revit) for types, methods, constructors, properties, fields, and events; every public API enum is fully searchable by value name (values the XML leaves undocumented are synthesized from the API assemblies). query is a single name or substring — e.g. 'FilteredElementCollector', 'Wall.Create', 'WALL_BASE_OFFSET' — ranked: exact name first, then prefix, then substring; dotted Type.Member queries match composites. Returns signatures with summary, remarks, parameter docs, return docs, and the Revit version a member was introduced in ('since'). Works with no document open. Use it to verify exact classes, members, and signatures before writing execute_csharp code. The first query builds the index (a few seconds); later queries are instant.";
|
|
36
|
+
public string Description => "Search the offline Revit API documentation (the RevitAPI.xml and RevitAPIUI.xml files shipped with Revit) for types, methods, constructors, properties, fields, and events; every public API enum is fully searchable by value name (values the XML leaves undocumented are synthesized from the API assemblies). query is a single name or substring — e.g. 'FilteredElementCollector', 'Wall.Create', 'WALL_BASE_OFFSET' — ranked: exact name first, then prefix, then substring; dotted Type.Member queries match composites, and same-named overloads rank simplest-first. To target one overload, continue the query past a parenthesis with parameter types, e.g. 'Wall.Create(Document, Curve'. Returns signatures with summary, remarks, parameter docs, return docs, exception docs, and the Revit version a member was introduced in ('since'); the top match shows its full docs inline. Works with no document open. Use it to verify exact classes, members, and signatures before writing execute_csharp code. The first query builds the index (a few seconds); later queries are instant.";
|
|
34
37
|
|
|
35
38
|
public bool RequiresDocument => false;
|
|
36
39
|
|
|
@@ -97,6 +100,9 @@ namespace RevitBridge.Tools
|
|
|
97
100
|
.Select(pair => new Dictionary<string, object?> { ["name"] = pair.Key, ["description"] = pair.Value })
|
|
98
101
|
.ToList(),
|
|
99
102
|
["returns"] = member.Returns,
|
|
103
|
+
["exceptions"] = member.Exceptions?
|
|
104
|
+
.Select(pair => new Dictionary<string, object?> { ["type"] = pair.Key, ["description"] = pair.Value })
|
|
105
|
+
.ToList(),
|
|
100
106
|
});
|
|
101
107
|
}
|
|
102
108
|
|
|
@@ -134,6 +140,7 @@ namespace RevitBridge.Tools
|
|
|
134
140
|
var top = scored
|
|
135
141
|
.OrderByDescending(entry => entry.Score)
|
|
136
142
|
.ThenBy(entry => entry.Member.Composite.Length)
|
|
143
|
+
.ThenBy(entry => entry.Member.ParameterCount)
|
|
137
144
|
.ThenBy(entry => entry.Member.FullName, StringComparer.Ordinal)
|
|
138
145
|
.Take(maxResults)
|
|
139
146
|
.Select(entry => entry.Member)
|
|
@@ -143,8 +150,15 @@ namespace RevitBridge.Tools
|
|
|
143
150
|
|
|
144
151
|
private static int Score(ApiMember member, string q, string[] words)
|
|
145
152
|
{
|
|
153
|
+
// A query with a parenthesis targets a specific overload by signature,
|
|
154
|
+
// e.g. 'wall.create(document, curve' — matched against the shortened
|
|
155
|
+
// signature text before any name-based ranking.
|
|
156
|
+
bool signatureQuery = q.Contains('(');
|
|
157
|
+
|
|
146
158
|
int score;
|
|
147
159
|
if (member.CompositeLower == q) score = 1000;
|
|
160
|
+
else if (signatureQuery && member.SignatureLower == q) score = 980;
|
|
161
|
+
else if (signatureQuery && member.SignatureLower.StartsWith(q, StringComparison.Ordinal)) score = 950;
|
|
148
162
|
else if (member.ShortNameLower == q) score = 900;
|
|
149
163
|
else if (member.CompositeLower.StartsWith(q, StringComparison.Ordinal)) score = 700;
|
|
150
164
|
else if (member.ShortNameLower.StartsWith(q, StringComparison.Ordinal)) score = 650;
|
|
@@ -181,7 +195,7 @@ namespace RevitBridge.Tools
|
|
|
181
195
|
}
|
|
182
196
|
markdown.Append(line);
|
|
183
197
|
if (i == 0)
|
|
184
|
-
AppendTopMatchDocs(markdown, member);
|
|
198
|
+
AppendTopMatchDocs(markdown, member, top.Count(other => other.CompositeLower == member.CompositeLower));
|
|
185
199
|
}
|
|
186
200
|
}
|
|
187
201
|
foreach (string warning in index.Warnings)
|
|
@@ -190,18 +204,23 @@ namespace RevitBridge.Tools
|
|
|
190
204
|
}
|
|
191
205
|
|
|
192
206
|
/// <summary>The model sees only this markdown — details.payload never reaches it —
|
|
193
|
-
/// so the top match carries its remarks, parameter, and
|
|
194
|
-
///
|
|
195
|
-
///
|
|
196
|
-
|
|
207
|
+
/// so the top match carries its remarks, parameter, return, and exception docs
|
|
208
|
+
/// inline (capped for display; the payload keeps full text). Lines that would blow
|
|
209
|
+
/// the markdown budget are dropped individually. When the top match is one of
|
|
210
|
+
/// several same-named overloads, a note says how to target another one.</summary>
|
|
211
|
+
private static void AppendTopMatchDocs(StringBuilder markdown, ApiMember member, int overloadCount)
|
|
197
212
|
{
|
|
198
|
-
var lines = new List<string>(
|
|
213
|
+
var lines = new List<string>(5);
|
|
199
214
|
if (member.Remarks is { } remarks)
|
|
200
|
-
lines.Add($"\n remarks: {remarks}");
|
|
215
|
+
lines.Add($"\n remarks: {Cap(remarks, MaxRemarksChars)}");
|
|
201
216
|
if (member.Parameters is { Count: > 0 } parameters)
|
|
202
|
-
lines.Add($"\n params: {string.Join("; ", parameters.Select(pair => $"{pair.Key} — {pair.Value}"))}");
|
|
217
|
+
lines.Add($"\n params: {string.Join("; ", parameters.Select(pair => $"{pair.Key} — {Cap(pair.Value, MaxParamDocChars)}"))}");
|
|
203
218
|
if (member.Returns is { } returns)
|
|
204
|
-
lines.Add($"\n returns: {returns}");
|
|
219
|
+
lines.Add($"\n returns: {Cap(returns, MaxReturnsChars)}");
|
|
220
|
+
if (member.Exceptions is { Count: > 0 } exceptions)
|
|
221
|
+
lines.Add($"\n throws: {string.Join("; ", exceptions.Select(pair => $"{pair.Key} — {Cap(pair.Value, MaxParamDocChars)}"))}");
|
|
222
|
+
if (overloadCount > 1)
|
|
223
|
+
lines.Add($"\n note: {member.Composite} has {overloadCount} overload(s) listed; full docs shown for the simplest top-ranked one. To target another, continue the query past a parenthesis with parameter types, e.g. '{member.Composite}(Document, '.");
|
|
205
224
|
foreach (string line in lines)
|
|
206
225
|
{
|
|
207
226
|
if (markdown.Length + line.Length > MaxMarkdownChars)
|
|
@@ -262,11 +281,18 @@ namespace RevitBridge.Tools
|
|
|
262
281
|
public required string FullNameLower { get; init; }
|
|
263
282
|
public required string CompositeLower { get; init; }
|
|
264
283
|
public required string ShortNameLower { get; init; }
|
|
284
|
+
public required string SignatureLower { get; init; }
|
|
285
|
+
|
|
286
|
+
/// <summary>Top-level parameter count from the doc id; overload tie-breaks
|
|
287
|
+
/// rank the simplest overload first.</summary>
|
|
288
|
+
public required int ParameterCount { get; init; }
|
|
289
|
+
|
|
265
290
|
public string? Summary { get; init; }
|
|
266
291
|
public string? Remarks { get; init; }
|
|
267
292
|
public string? Returns { get; init; }
|
|
268
293
|
public string? Since { get; init; }
|
|
269
294
|
public IReadOnlyList<KeyValuePair<string, string>>? Parameters { get; init; }
|
|
295
|
+
public IReadOnlyList<KeyValuePair<string, string>>? Exceptions { get; init; }
|
|
270
296
|
}
|
|
271
297
|
|
|
272
298
|
private sealed class DocIndex
|
|
@@ -364,6 +390,8 @@ namespace RevitBridge.Tools
|
|
|
364
390
|
FullNameLower = fullName.ToLowerInvariant(),
|
|
365
391
|
CompositeLower = composite.ToLowerInvariant(),
|
|
366
392
|
ShortNameLower = name.ToLowerInvariant(),
|
|
393
|
+
SignatureLower = composite.ToLowerInvariant(),
|
|
394
|
+
ParameterCount = 0,
|
|
367
395
|
Summary = enumType == typeof(BuiltInCategory)
|
|
368
396
|
? "BuiltInCategory enum value — usable as the 'category' argument of get_elements/get_element_types and with FilteredElementCollector.OfCategory in execute_csharp."
|
|
369
397
|
: $"{typeName} enum value (not documented in the XML; synthesized from {assemblyName} metadata).",
|
|
@@ -481,12 +509,24 @@ namespace RevitBridge.Tools
|
|
|
481
509
|
if (parameters is { Count: >= MaxParamsPerMember })
|
|
482
510
|
break;
|
|
483
511
|
string? name = param.Attribute("name")?.Value;
|
|
484
|
-
string? text =
|
|
512
|
+
string? text = CleanDocText(param);
|
|
485
513
|
if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(text))
|
|
486
514
|
continue;
|
|
487
515
|
(parameters ??= new List<KeyValuePair<string, string>>()).Add(new KeyValuePair<string, string>(name, text));
|
|
488
516
|
}
|
|
489
517
|
|
|
518
|
+
List<KeyValuePair<string, string>>? exceptions = null;
|
|
519
|
+
foreach (var exception in element.Elements("exception"))
|
|
520
|
+
{
|
|
521
|
+
if (exceptions is { Count: >= MaxExceptionsPerMember })
|
|
522
|
+
break;
|
|
523
|
+
string? cref = exception.Attribute("cref")?.Value;
|
|
524
|
+
string? text = CleanDocText(exception);
|
|
525
|
+
if (string.IsNullOrEmpty(cref) || string.IsNullOrEmpty(text))
|
|
526
|
+
continue;
|
|
527
|
+
(exceptions ??= new List<KeyValuePair<string, string>>()).Add(new KeyValuePair<string, string>(ShortCref(cref), text));
|
|
528
|
+
}
|
|
529
|
+
|
|
490
530
|
return new ApiMember
|
|
491
531
|
{
|
|
492
532
|
Kind = kind,
|
|
@@ -498,14 +538,34 @@ namespace RevitBridge.Tools
|
|
|
498
538
|
FullNameLower = path.ToLowerInvariant(),
|
|
499
539
|
CompositeLower = composite.ToLowerInvariant(),
|
|
500
540
|
ShortNameLower = shortName.ToLowerInvariant(),
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
541
|
+
SignatureLower = signature.ToLowerInvariant(),
|
|
542
|
+
ParameterCount = CountTopLevelParameters(paramText),
|
|
543
|
+
Summary = CleanDocText(element.Element("summary")),
|
|
544
|
+
Remarks = CleanDocText(element.Element("remarks")),
|
|
545
|
+
Returns = CleanDocText(element.Element("returns")),
|
|
504
546
|
Since = CleanDocText(element.Element("since")),
|
|
505
547
|
Parameters = parameters,
|
|
548
|
+
Exceptions = exceptions,
|
|
506
549
|
};
|
|
507
550
|
}
|
|
508
551
|
|
|
552
|
+
/// <summary>Parameter count of a doc-id parameter list; commas inside generic
|
|
553
|
+
/// braces (Dictionary{K,V}) do not separate parameters.</summary>
|
|
554
|
+
private static int CountTopLevelParameters(string? paramText)
|
|
555
|
+
{
|
|
556
|
+
if (string.IsNullOrEmpty(paramText))
|
|
557
|
+
return 0;
|
|
558
|
+
int count = 1;
|
|
559
|
+
int depth = 0;
|
|
560
|
+
foreach (char c in paramText)
|
|
561
|
+
{
|
|
562
|
+
if (c == '{') depth++;
|
|
563
|
+
else if (c == '}') depth--;
|
|
564
|
+
else if (c == ',' && depth == 0) count++;
|
|
565
|
+
}
|
|
566
|
+
return count;
|
|
567
|
+
}
|
|
568
|
+
|
|
509
569
|
// ------------------------------------------------------------- text utils
|
|
510
570
|
|
|
511
571
|
/// <summary>Flattens doc XML to plain text: see/seealso cref -> short type name,
|