[Bind] Concatenate multiline documentation

This commit is contained in:
thefiddler 2014-03-30 10:29:11 +02:00
parent 67b0ead68b
commit 033e0b7155
5 changed files with 62 additions and 50 deletions

View file

@ -274,7 +274,7 @@ namespace Bind
get get
{ {
if (processor_ == null) if (processor_ == null)
processor_ = new DocProcessor(Path.Combine(Settings.DocPath, Settings.DocFile)); processor_ = new DocProcessor();
return processor_; return processor_;
} }
} }
@ -310,48 +310,68 @@ namespace Bind
new KeyValuePair<string, string>(p.Name, String.Empty)).ToList() new KeyValuePair<string, string>(p.Name, String.Empty)).ToList()
}; };
string warning = "[deprecated: v{0}]"; string warning = String.Empty;
string category = "[requires: {0}]"; string category = String.Empty;
if (f.Deprecated) if (f.Deprecated)
{ {
warning = String.Format(warning, f.DeprecatedVersion); warning = String.Format("[deprecated: v{0}]", f.DeprecatedVersion);
docs.Summary = docs.Summary.Insert(0, warning);
} }
if (f.Extension != "Core" && !String.IsNullOrEmpty(f.Category)) if (f.Extension != "Core" && !String.IsNullOrEmpty(f.Category))
{ {
category = String.Format(category, f.Category); category = String.Format("[requires: {0}]", f.Category);
docs.Summary = docs.Summary.Insert(0, category);
} }
else if (!String.IsNullOrEmpty(f.Version)) else if (!String.IsNullOrEmpty(f.Version))
{ {
if (f.Category.StartsWith("VERSION")) if (f.Category.StartsWith("VERSION"))
category = String.Format(category, "v" + f.Version); category = String.Format("[requires: {0}]", "v" + f.Version);
else else
category = String.Format(category, "v" + f.Version + " and " + f.Category); category = String.Format("[requires: {0}]", "v" + f.Version + " or " + f.Category);
docs.Summary = docs.Summary.Insert(0, category);
} }
sw.WriteLine("/// <summary>{0}{1} {2}</summary>",
category, warning, docs.Summary);
for (int i = 0; i < f.Parameters.Count; i++) for (int i = 0; i < f.Parameters.Count; i++)
{ {
var param = f.Parameters[i]; var param = f.Parameters[i];
string length = String.Empty;
if (!String.IsNullOrEmpty(param.ComputeSize)) if (!String.IsNullOrEmpty(param.ComputeSize))
{ {
docs.Parameters[i].Value.Insert(0, length = String.Format("[length: {0}]", param.ComputeSize);
String.Format("[length: {0}]", param.ComputeSize));
} }
}
sw.WriteLine("/// <summary>{0}</summary>", docs.Summary); if (docs.Parameters.Count > i)
foreach (var p in docs.Parameters) {
{ var doc = docs.Parameters[i];
sw.WriteLine("/// <param name=\"{0}\">{1}</param>", p.Key, p.Value);
if (doc.Key != param.Name)
{
Console.Error.WriteLine(
"[Warning] Parameter '{0}' in function '{1}' has incorrect doc name '{2}'",
param.Name, f.Name, doc.Key);
}
// Note: we use param.Name, because the documentation sometimes
// uses different names than the specification.
sw.WriteLine("/// <param name=\"{0}\">{1} {2}</param>",
param.Name, length, doc.Value);
}
else
{
Console.Error.WriteLine(
"[Warning] Parameter '{0}' in function '{1}' not found in '{2}'",
param.Name, f.Name, docfile);
sw.WriteLine("/// <param name=\"{0}\">{1}</param>",
param.Name, length);
}
} }
} }
catch (Exception e) catch (Exception e)
{ {
Console.WriteLine("[Warning] Error processing file {0}: {1}", docfile, e.ToString()); Console.WriteLine("[Warning] Error processing file {0}: {1}", docfile, e.ToString());
} }
} }
#endregion #endregion

View file

@ -671,7 +671,7 @@ typedef const char* GLstring;
get get
{ {
if (processor_ == null) if (processor_ == null)
processor_ = new DocProcessor(Path.Combine(Settings.DocPath, Settings.DocFile)); processor_ = new DocProcessor();
return processor_; return processor_;
} }
} }

View file

@ -8,7 +8,6 @@ using System.Text.RegularExpressions;
using System.Xml; using System.Xml;
using System.Xml.Linq; using System.Xml.Linq;
using System.Xml.XPath; using System.Xml.XPath;
using System.Xml.Xsl;
using Bind.Structures; using Bind.Structures;
@ -19,29 +18,12 @@ namespace Bind
static readonly Regex remove_mathml = new Regex( static readonly Regex remove_mathml = new Regex(
@"<(mml:math|inlineequation)[^>]*?>(?:.|\n)*?</\s*\1\s*>", @"<(mml:math|inlineequation)[^>]*?>(?:.|\n)*?</\s*\1\s*>",
RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnorePatternWhitespace); RegexOptions.Compiled | RegexOptions.Multiline | RegexOptions.IgnorePatternWhitespace);
static readonly Regex remove_doctype = new Regex(
static readonly XslCompiledTransform xslt = new XslCompiledTransform(); @"<!DOCTYPE[^>\[]*(\[.*\])?>", RegexOptions.Compiled | RegexOptions.Multiline);
static readonly XmlReaderSettings settings = new XmlReaderSettings();
Documentation Cached; Documentation Cached;
string LastFile; string LastFile;
public DocProcessor(string transform_file)
{
if (!File.Exists(transform_file))
{
// If no specific transform file exists
// get the generic transform file from
// the parent directory
var dir = Directory.GetParent(Path.GetDirectoryName(transform_file)).FullName;
var file = Path.GetFileName(transform_file);
transform_file = Path.Combine(dir, file);
}
xslt.Load(transform_file);
settings.ProhibitDtd = false;
settings.XmlResolver = null;
}
// Strips MathML tags from the source and replaces the equations with the content // Strips MathML tags from the source and replaces the equations with the content
// found in the <!-- eqn: :--> comments in the docs. // found in the <!-- eqn: :--> comments in the docs.
// Todo: Some simple MathML tags do not include comments, find a solution. // Todo: Some simple MathML tags do not include comments, find a solution.
@ -57,10 +39,8 @@ namespace Bind
text = File.ReadAllText(file); text = File.ReadAllText(file);
text = text text = text
.Replace("xml:", String.Empty) // Remove namespaces .Replace("&epsi;", "epsilon"); // Fix unrecognized &epsi; entities
.Replace("&epsi;", "epsilon") // Fix unrecognized &epsi; entities text = remove_doctype.Replace(text, String.Empty);
.Replace("<constant>", "<c>") // Improve output
.Replace("</constant>", "</c>");
Match m = remove_mathml.Match(text); Match m = remove_mathml.Match(text);
while (m.Length > 0) while (m.Length > 0)
@ -98,11 +78,12 @@ namespace Bind
{ {
// The pure XmlReader is ~20x faster than the XmlTextReader. // The pure XmlReader is ~20x faster than the XmlTextReader.
//doc = XmlReader.Create(new StringReader(text), settings); //doc = XmlReader.Create(new StringReader(text), settings);
//XmlReader reader =
doc = XDocument.Parse(text); doc = XDocument.Parse(text);
Cached = ToInlineDocs(doc); Cached = ToInlineDocs(doc);
return Cached; return Cached;
} }
catch (XmlException e) catch (Exception e)
{ {
Console.WriteLine(e.ToString()); Console.WriteLine(e.ToString());
Console.WriteLine(doc.ToString()); Console.WriteLine(doc.ToString());
@ -115,19 +96,31 @@ namespace Bind
var inline = new Documentation var inline = new Documentation
{ {
Summary = Summary =
((IEnumerable)doc.XPathEvaluate("//*[name()='refentry']/*[name()='refnamediv']/*[name()='refpurpose']")) Cleanup(
.Cast<XElement>().First().Value.Trim(), ((IEnumerable)doc.XPathEvaluate("//*[name()='refentry']/*[name()='refnamediv']/*[name()='refpurpose']"))
.Cast<XElement>().First().Value),
Parameters = Parameters =
((IEnumerable)doc.XPathEvaluate("*[name()='refentry']/*[name()='refsect1'][@id='parameters']/*[name()='variablelist']/*[name()='varlistentry']")) ((IEnumerable)doc.XPathEvaluate("*[name()='refentry']/*[name()='refsect1'][@id='parameters']/*[name()='variablelist']/*[name()='varlistentry']"))
.Cast<XNode>() .Cast<XNode>()
.Select(p => new KeyValuePair<string, string>( .Select(p =>
new KeyValuePair<string, string>(
p.XPathSelectElement("*[name()='term']/*[name()='parameter']").Value.Trim(), p.XPathSelectElement("*[name()='term']/*[name()='parameter']").Value.Trim(),
p.XPathSelectElement("*[name()='listitem']").Value.Trim())) Cleanup(p.XPathSelectElement("*[name()='listitem']").Value)))
.ToList() .ToList()
}; };
inline.Summary = Char.ToUpper(inline.Summary[0]) + inline.Summary.Substring(1); inline.Summary = Char.ToUpper(inline.Summary[0]) + inline.Summary.Substring(1);
return inline; return inline;
} }
static readonly char[] newline = new char[] { '\n' };
static string Cleanup(string text)
{
return
String.Join(" ", text
.Replace("\r", "\n")
.Split(newline, StringSplitOptions.RemoveEmptyEntries)
.Select(s => s.Trim()).ToArray());
}
} }
} }

View file

@ -55,7 +55,6 @@
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet> <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<DebugType>full</DebugType> <DebugType>full</DebugType>
<Commandlineparameters>-mode:es30</Commandlineparameters>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<BaseAddress>285212672</BaseAddress> <BaseAddress>285212672</BaseAddress>

View file

@ -322,7 +322,7 @@ namespace Bind
get get
{ {
if (processor_ == null) if (processor_ == null)
processor_ = new DocProcessor(Path.Combine(Settings.DocPath, Settings.DocFile)); processor_ = new DocProcessor();
return processor_; return processor_;
} }
} }