Skip to content
This repository has been archived by the owner on Jan 6, 2021. It is now read-only.

Commit

Permalink
Targets issues #27, #28, #31
Browse files Browse the repository at this point in the history
  • Loading branch information
piac committed May 17, 2012
1 parent 159c2f8 commit f23dffe
Show file tree
Hide file tree
Showing 4 changed files with 238 additions and 14 deletions.
234 changes: 234 additions & 0 deletions Component/DocStringUtils.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Grasshopper.Kernel;

namespace GhPython.Component
{
/*
# based on DocStrings as defined in
# http://google-styleguide.googlecode.com/svn/trunk/pyguide.html#Comments
""""""
Title: Arithmetic Series
Description: Computes the Sum of an Arithmetic Progression, or the
sum of all numbers from F to L, included.
Args:
F: the first number included in the series.
L: the last number included in the series.
Returns:
S: If F > L, then sum of all numbers [F,L].
If F = L, then 0.
If F < L, then sum of all numbers (L,F).
K: Not used.
Help:
See also the Gauss elementary school story:
http://mathworld.wolfram.com/ArithmeticSeries.html
""""""
*/
class DocStringUtils
{
public static void ApplyDocString(string code, ScriptingAncestorComponent component)
{
var reader = new StringReader(code);

string line;
for (; ; ) //proceeds to begin of docstrings, or leave method
{
line = reader.ReadLine();
if (line == null) return;
if (IsEmptyOrFullyCommentedOutLine(line)) continue;
if (IsDocStringStart(line)) break;
return;
}

//strips the docstring start chars
line = line.Substring(line.IndexOf(_docStringSeparator) + _docStringSeparator.Length);
int firstLevelIndent = GetIndent(line);
int secondLevelIndent = -1;

string variable = "%HEADING";
StringBuilder result = new StringBuilder();
KeywordType type = KeywordType.Description;

List<KeyValuePair<KeywordType, string>> l = new List<KeyValuePair<KeywordType, string>>();

do //consumes docstring lines and then leaves
{
int endSeparator = line.IndexOf(_docStringSeparator);
if (endSeparator != -1) line = line.Substring(0, endSeparator);

if (IsEmptyLine(line)) {
if (endSeparator != -1) break;
continue;
};
int newIndent = GetIndent(line);
if (newIndent > firstLevelIndent)
{
if (secondLevelIndent == -1 ||
newIndent <= secondLevelIndent) //second level
{
//we could check for faulty indentation here
secondLevelIndent = newIndent;

string keyword;
if (IsNewKeywordDeclared(line, out keyword))
{
var nextType = type;
bool match = true;
switch (keyword.ToUpperInvariant())
{
case "ARG":
case "ARGS":
case "ARGUMENT":
case "ARGUMENTS":
nextType = KeywordType.Argument;
break;
case "RETURN":
case "RETURNS":
nextType = KeywordType.Return;
break;
case "HELP":
nextType = KeywordType.Help;
break;
default:
match = false;
break;
}

if (match)
{
Send(variable, ref result, type, component);
AddLine(result, line.Substring(line.IndexOf(":") + 1).TrimStart(_toTrim));
variable = null;
type = nextType;
}
else
AddLine(result, line);
}
else
AddLine(result, line);
}
else //third level
{
string keyword;
if (IsNewKeywordDeclared(line, out keyword))
{
Send(variable, ref result, type, component);
AddLine(result, line.Substring(line.IndexOf(":") + 1).TrimStart(_toTrim));
variable = keyword;
}
else
AddLine(result, line.Trim(_toTrim));
}
}
else
AppendText(result, line);
if (endSeparator != -1) break;
}
while ((line = reader.ReadLine()) != null);

Send(variable, ref result, type, component);
}

private static void Send(string variable, ref StringBuilder result, KeywordType type, ScriptingAncestorComponent component)
{
if (variable != null)
{
switch(type)
{
case KeywordType.Description:
component.Description = result.ToString();
break;
case KeywordType.Argument:
FindAndDescribe(component.Params.Input, variable, result.ToString());
break;
case KeywordType.Return:
FindAndDescribe(component.Params.Output, variable, result.ToString());
break;
case KeywordType.Help:
FindAndDescribe(component.Params.Input, variable, result.ToString());
break;
}
result = new StringBuilder();
}
}

private static bool FindAndDescribe(List<IGH_Param> list, string variable, string p)
{
int i = list.FindIndex((match) => match.NickName == variable);
if (i != -1)
{
var item = list[i];
if (item != null)
{
item.Description = p;
}
}
return false;
}

enum KeywordType
{
Description,
Argument,
Return,
Help,
}

private static void AppendText(StringBuilder result, string text)
{
if (result.Length != 0) result.Append(" ");
result.Append(text);
}

private static void AddLine(StringBuilder result, string text)
{
if (result.Length != 0) result.AppendLine();
result.Append(text);
}

private static bool IsNewKeywordDeclared(string line, out string keyword)
{
keyword = null;
string piece = line.TrimStart(_toTrim);
int end = piece.IndexOf(":");
if (end == -1) return false;
piece = piece.Substring(0, end).TrimEnd(_toTrim);
if (piece.IndexOfAny(_toTrim) != -1) return false;
keyword = piece;
return true;
}

private static int GetIndent(string line)
{
int i;
for (i = 0; i < line.Length; i++)
if (!(line[i].Equals(' ') || line[i].Equals('\t')))
break;
return i;
}

static readonly char[] _toTrim = new char[] { ' ', '\t' };
const string _docStringSeparator = "\"\"\"";

private static bool IsDocStringStart(string line)
{
return line.TrimStart(_toTrim).StartsWith(_docStringSeparator);
}

private static bool IsEmptyLine(string line)
{
return line.TrimStart(_toTrim).Length == 0;
}

private static bool IsEmptyOrFullyCommentedOutLine(string line)
{
var after = line.TrimStart(_toTrim);
if (after.Length == 0)
return true;
return after.IndexOf("#") == 0;
}
}
}
3 changes: 0 additions & 3 deletions Component/PyUpgrader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,9 +57,6 @@ public IGH_DocumentObject Upgrade(IGH_DocumentObject target, GH_Document documen
}
}

component_new.CodeInputParam.ObjectChanged -= component_OBSOLETE.DestroyCompiledCode;
component_new.CodeInputParam.ObjectChanged += component_new.DestroyCompiledCode;

return component_new;
}
return null;
Expand Down
14 changes: 3 additions & 11 deletions Component/ScriptingAncestorComponent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,16 +119,9 @@ public Param_String ConstructCodeInputParameter()
NickName = "code",
Description = "Python script to execute",
};
// Throw away the compiled script when code changes. We will just recompile on the next solve
code.ObjectChanged += DestroyCompiledCode;
return code;
}

internal void DestroyCompiledCode(IGH_DocumentObject sender, GH_ObjectChangedEventArgs e)
{
_compiled_py = null;
}

protected abstract void AddDefaultOutput(GH_Component.GH_OutputParamManager pManager);

protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager)
Expand Down Expand Up @@ -191,10 +184,8 @@ protected override void SafeSolveInstance(IGH_DataAccess DA)
_py.SetIntellisenseVariable(varname, o);
}

// the "code" string could either be embedded in the component
// itself or a dynamic string that is input from some other component
bool codeIsEmbedded = HideCodeInput || Params.Input[0].SourceCount == 0;
if (!codeIsEmbedded || _compiled_py == null)
// the "code" string could be embedded in the component itself
if (!HideCodeInput || _compiled_py == null)
{
string script = CodeInput;

Expand All @@ -204,6 +195,7 @@ protected override void SafeSolveInstance(IGH_DataAccess DA)
if (_compiled_py == null ||
string.Compare(script, _previousRunCode, StringComparison.InvariantCulture) != 0)
{
DocStringUtils.ApplyDocString(script, this);
_compiled_py = _py.Compile(script);
_previousRunCode = script;
}
Expand Down
1 change: 1 addition & 0 deletions GhPython.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Component\ComponentIOMarshal.cs" />
<Compile Include="Component\DocStringUtils.cs" />
<Compile Include="Component\GHComponentsLoader.cs" />
<Compile Include="Component\PythonEnvironment.cs">
<SubType>Code</SubType>
Expand Down

0 comments on commit f23dffe

Please sign in to comment.