diff --git a/kibom/Keio.Utils.dll b/kibom/Keio.Utils.dll index 7115406..4935f7e 100644 Binary files a/kibom/Keio.Utils.dll and b/kibom/Keio.Utils.dll differ diff --git a/kibom/Output.cs b/kibom/Output.cs index fe30bf5..018720e 100644 --- a/kibom/Output.cs +++ b/kibom/Output.cs @@ -12,6 +12,7 @@ using System.Drawing; using OfficeOpenXml; using OfficeOpenXml.Style; +using Keio.Utils; namespace kibom { @@ -260,6 +261,153 @@ public static void OutputTSV(List groups, HeaderBlock header, s } } + private static void PrettyMeasureWidths(List groups, + out int count_width, + out int reference_width, + out int value_width, + out int footprint_width, + out int precision_width) + { + count_width = "No.".Length; + reference_width = "Reference".Length; + value_width = "Value".Length; + footprint_width = "Footprint".Length; + precision_width = "Precision".Length; + + foreach (DesignatorGroup g in groups) + { + // check for groups that are entire "no part" + bool all_no_part = true; + foreach (Component c in g.comp_list) + { + if (!c.no_part) + all_no_part = false; + } + if (all_no_part) + continue; + + foreach (Component c in g.comp_list) + { + count_width = Math.Max(count_width, (c.count + 1).ToString().Length); + reference_width = Math.Max(reference_width, c.reference.Length); + value_width = Math.Max(value_width, c.value.Length); + if (!string.IsNullOrEmpty(c.precision)) + precision_width = Math.Max(precision_width, c.precision.Length); + + string footprint = c.footprint_normalized; + if (footprint == "") + footprint = c.footprint; + footprint_width = Math.Max(footprint_width, footprint.Length); + } + } + + count_width = Math.Min(count_width, 10); + reference_width = Math.Min(reference_width, 20); + value_width = Math.Min(value_width, 30); + footprint_width = Math.Min(footprint_width, 30); + precision_width = Math.Min(precision_width, 20); + } + + public static void OutputPretty(List groups, HeaderBlock header, string file) + { + Console.WriteLine("Generating " + file + "..."); + using (StreamWriter sw = new StreamWriter(file)) + { + int count_width; + int reference_width; + int value_width; + int footprint_width; + int precision_width; + PrettyMeasureWidths(groups, out count_width, out reference_width, out value_width, out footprint_width, out precision_width); + + sw.WriteLine("Title: " + header.title); + sw.WriteLine("Date: " + header.date); + sw.WriteLine("Source: " + header.source); + sw.WriteLine("Revsision: " + header.revision); + if (header.company != "") + sw.WriteLine("Company: " + header.company); + sw.WriteLine(""); + + //sw.WriteLine("No. Designation Value Footprint Precision"); + sw.Write(TextUtils.FixedLengthString("No.", ' ', count_width) + " "); + sw.Write(TextUtils.FixedLengthString("Reference", ' ', reference_width) + " "); + sw.Write(TextUtils.FixedLengthString("Value", ' ', value_width) + " "); + sw.Write(TextUtils.FixedLengthString("Footprint", ' ', footprint_width) + " "); + sw.WriteLine("Precision"); + sw.WriteLine(""); + + foreach (DesignatorGroup g in groups) + { + // check for groups that are entire "no part" + bool all_no_part = true; + foreach (Component c in g.comp_list) + { + if (!c.no_part) + all_no_part = false; + } + if (all_no_part) + continue; + + // header + DefaultComp def = Component.FindDefaultComp(g.designator); + if (def != null) + { + sw.Write("[ " + def.long_name); + sw.Write(", " + g.comp_list.Count.ToString() + (g.comp_list.Count > 1 ? " values" : " value")); + if (def.has_default) + sw.Write(", " + def.default_type + " unless otherwise stated"); + sw.WriteLine(" ]"); + } + else + sw.WriteLine("[ " + g.designator + ", " + g.comp_list.Count.ToString() + + (g.comp_list.Count > 1 ? " values" : " value") + " ]"); + + sw.WriteLine(new string('-', count_width + 2 + reference_width + 2 + value_width + 2 + footprint_width + 2 + precision_width)); + + // component list + foreach (Component c in g.comp_list) + { + if (c.no_part) + continue; + + string footprint = c.footprint_normalized; + if (footprint == "") + footprint = c.footprint; + sw.Write(TextUtils.FixedLengthString((c.count + 1).ToString(), ' ', count_width) + " "); + + string reference = TextUtils.Reformat(c.reference, reference_width); + int split_point = reference.IndexOf('\n'); + if (split_point == -1) + sw.Write(TextUtils.FixedLengthString(reference, ' ', reference_width) + " "); + else + sw.Write(TextUtils.FixedLengthString(reference.Substring(0, split_point - 1), ' ', reference_width) + " "); + + sw.Write(TextUtils.FixedLengthString(c.value, ' ', value_width) + " "); + //sw.Write(TextUtils.FixedLengthString(c.part_no, ' ', 10)); + sw.Write(TextUtils.FixedLengthString(footprint, ' ', footprint_width) + " "); + if (!string.IsNullOrEmpty(c.precision)) + sw.Write(TextUtils.FixedLengthString(c.precision, ' ', precision_width)); + sw.WriteLine(); + + if (split_point != -1) // need to do the rest of the references + { + string indent = new string(' ', count_width + 2); + do + { + reference = reference.Substring(split_point + 1); + split_point = reference.IndexOf('\n'); + if (split_point == -1) + sw.WriteLine(indent + reference.Trim()); + else + sw.WriteLine(indent + reference.Substring(0, split_point - 1).Trim()); + } while (split_point != -1); + } + } + sw.WriteLine(); + } + } + } + public static void OutputPDF(List groups, HeaderBlock header, string file, bool rtf = false) { Console.WriteLine("Generating " + file + "..."); diff --git a/kibom/Program.cs b/kibom/Program.cs index 638e1d6..ed4b1c1 100644 --- a/kibom/Program.cs +++ b/kibom/Program.cs @@ -59,6 +59,8 @@ static bool ParseArgs(string[] args, out string filename, out string path, out s assign: (dynamic d) => { poutputs += "d"; }) }, { new CmdArgument("tsv", ArgType.Flag, help: "Generate tab separated value output", assign: (dynamic d) => { poutputs += "t"; }) }, + { new CmdArgument("pretty", ArgType.Flag, help: "Generate pretty text output", + assign: (dynamic d) => { poutputs += "q"; }) }, { new CmdArgument("pdf", ArgType.Flag, help: "Generate PDF output", assign: (dynamic d) => { poutputs += "p"; }) }, { new CmdArgument("rtf", ArgType.Flag, help: "Generate RTF output", @@ -125,7 +127,9 @@ static bool ParseKicadXML(XmlDocument doc, string path, string filename, string { string base_filename = Path.GetFileNameWithoutExtension(path + filename); if (outputs.Contains('t')) - Output.OutputTSV(merged_groups, header, path + base_filename + ".txt"); + Output.OutputTSV(merged_groups, header, path + base_filename + ".tsv.txt"); + if (outputs.Contains('q')) + Output.OutputPretty(merged_groups, header, path + base_filename + ".txt"); if (outputs.Contains('x')) Output.OutputXLSX(merged_groups, header, path + base_filename + ".xlsx", template); if (outputs.Contains('p')) @@ -137,6 +141,8 @@ static bool ParseKicadXML(XmlDocument doc, string path, string filename, string { if (outputs.Contains('t')) Output.OutputTSV(merged_groups, header, output_filename); + if (outputs.Contains('q')) + Output.OutputPretty(merged_groups, header, output_filename); if (outputs.Contains('x')) Output.OutputXLSX(merged_groups, header, output_filename, template); if (outputs.Contains('p')) diff --git a/kibom/Properties/AssemblyInfo.cs b/kibom/Properties/AssemblyInfo.cs index 1b2b87a..70a7cbb 100644 --- a/kibom/Properties/AssemblyInfo.cs +++ b/kibom/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.5.*")] +[assembly: AssemblyVersion("0.6.*")] [assembly: AssemblyFileVersion("1.0.0.0")]