public static string GetHtmlDiff(string a, string b) { var dmp = new DiffMatchPatch.diff_match_patch(); var diffmain = dmp.diff_main(a, b); dmp.diff_cleanupSemantic(diffmain); return "<div id='hook_diff'><pre>" + dmp.diff_prettyHtml(diffmain) + "</pre></div>"; }
public object Post(Document local) { var server = Db.Select<Document>(q => q.Id == local.Id)[0]; server.Title = local.Title; // Client has a newer version if (server.Revision < local.Revision) { var text1 = server.Content ?? ""; var text2 = local.Content ?? ""; var dmp = new DiffMatchPatch.diff_match_patch(); // Compute patch required between the old and new text var patches = dmp.patch_make(text1, text2); // Apply patch to old text var result = Convert.ToString(dmp.patch_apply(patches, text1)[0]); server.Content = result; server.Revision = local.Revision; server.Updated = DateTime.Now; } Db.Save(server); // Send latest document to client return server; }
private void GenerateMSDNCategory(string category, string categoryMdPath, IOrderedEnumerable <Model.CmdletInfo> cmdlets) { var originalCategoryMd = string.Empty; var newCategoryMd = string.Empty; if (System.IO.File.Exists(categoryMdPath)) { originalCategoryMd = System.IO.File.ReadAllText(categoryMdPath); } var docBuilder = new StringBuilder(); docBuilder.AppendFormat("# {0} {1}", category, Environment.NewLine); docBuilder.AppendFormat("Cmdlet|Description|Platform{0}", Environment.NewLine); docBuilder.AppendFormat(":-----|:----------|:-------{0}", Environment.NewLine); foreach (var cmdletInfo in cmdlets) { var description = cmdletInfo.Description != null?cmdletInfo.Description.Replace("\r\n", " ") : ""; docBuilder.AppendFormat("**[{0}]({1}{2}.md)** |{3}|{4}{5}", cmdletInfo.FullCommand.Replace("-", "‑"), cmdletInfo.Verb, cmdletInfo.Noun, description, cmdletInfo.Platform, Environment.NewLine); } newCategoryMd = docBuilder.ToString(); DiffMatchPatch.diff_match_patch dmp = new DiffMatchPatch.diff_match_patch(); var diffResults = dmp.diff_main(newCategoryMd, originalCategoryMd); foreach (var result in diffResults) { if (result.operation != DiffMatchPatch.Operation.EQUAL) { System.IO.File.WriteAllText(categoryMdPath, docBuilder.ToString()); } } }
public string Merge(string original, string their, string my) { var dmp = new DiffMatchPatch.diff_match_patch(); var patches = dmp.patch_make(original, their); var result = dmp.patch_apply(patches, my); return((string)result[0]); }
public static string GetHtmlDiff(string a, string b) { var dmp = new DiffMatchPatch.diff_match_patch(); var diffmain = dmp.diff_main(a, b); dmp.diff_cleanupSemantic(diffmain); return("<div id='hook_diff'><pre>" + dmp.diff_prettyHtml(diffmain) + "</pre></div>"); }
void apply_patch(string patch) { var dmp = new DiffMatchPatch.diff_match_patch(); var patches = dmp.patch_fromText(patch); var results = dmp.patch_apply(patches, Note.original); System.Diagnostics.Debug.WriteLine("Patch applied: " + results[0]); }
public void LogDifferences(string diffName, List <Comparence> comparence) { var differ = new DiffMatchPatch.diff_match_patch(); differ.Diff_Timeout = 10; var sb = new StringBuilder(diffName); sb.AppendLine(); foreach (var diff in comparence) { if (diff.Result != CompareResult.HasContentDifferences) { continue; } try { var file1Content = FolderComparer.ReadFile(diff.File1FullPath); if (file1Content == null) { sb.AppendLine(string.Format("DIFF Could not get detailed diff for {0}. Content is null.}", diff.File1FullPath)); continue; } var file2Content = FolderComparer.ReadFile(diff.File2FullPath); if (file2Content == null) { sb.AppendLine(string.Format("DIFF Could not get detailed diff for {0}. Content is null.}", diff.File2FullPath)); continue; } var differences = differ.diff_main(file1Content, file2Content); var diffText = differ.DiffText(differences, true); sb.AppendLine(); sb.AppendLine("DIFF for " + diff.ToString()); sb.AppendLine(); sb.AppendLine("|" + diffText + "|"); //sb.AppendLine("-------------------File 1 content:"); //sb.AppendLine(file1Content); //sb.AppendLine("-------------------File 2 content:"); //sb.AppendLine(file2Content); } catch (System.Exception ex) { sb.AppendLine(string.Format("DIFF Could not get detailed diff for {0}. Exception: {1}", diff.ToString(), ex.Message)); } } Logger.Warn(string.Empty); Logger.Warn(sb.ToString()); }
public static TaskList Merge(TaskList original, TaskList new1, TaskList new2) { var diff = new DiffMatchPatch.diff_match_patch(); var diffs = diff.diff_main(original.ToString(), new1.ToString()); var patches = diff.patch_make(original.ToString(), diffs); var text = diff.patch_apply(patches, new2.ToString()); var result = new TaskList(); result.LoadTasksFromString(text[0] as string); return(result); }
private void GenerateMSDNLandingPage(string landingPagePath) { var originalLandingPageMd = string.Empty; var newLandingPageMd = string.Empty; if (System.IO.File.Exists(landingPagePath)) { originalLandingPageMd = System.IO.File.ReadAllText(landingPagePath); } var docBuilder = new StringBuilder(); // read base file from disk var assemblyPath = new FileInfo(Assembly.GetExecutingAssembly().Location).DirectoryName; string baseLandingPage = System.IO.File.ReadAllText(Path.Combine(assemblyPath, "landingpage.md")); // Get all unique categories var categories = _cmdlets.Where(c => !string.IsNullOrEmpty(c.Category)).Select(c => c.Category).Distinct(); foreach (var category in categories.OrderBy(c => c)) { docBuilder.Append("\n\n"); docBuilder.AppendFormat("### {0} {1}", category, Environment.NewLine); docBuilder.AppendFormat("Cmdlet|Description|Platform{0}", Environment.NewLine); docBuilder.AppendFormat(":-----|:----------|:-------{0}", Environment.NewLine); var categoryCmdlets = _cmdlets.Where(c => c.Category == category).OrderBy(c => c.Noun); foreach (var cmdletInfo in categoryCmdlets) { var description = cmdletInfo.Description != null?cmdletInfo.Description.Replace("\r\n", " ") : ""; docBuilder.AppendFormat("**[{0}]({1}{2}.md)** |{3}|{4}{5}", cmdletInfo.FullCommand.Replace("-", "‑"), cmdletInfo.Verb, cmdletInfo.Noun, description, cmdletInfo.Platform, Environment.NewLine); } } string dynamicLandingPage = docBuilder.ToString(); newLandingPageMd = baseLandingPage.Replace("---cmdletdata---", dynamicLandingPage); DiffMatchPatch.diff_match_patch dmp = new DiffMatchPatch.diff_match_patch(); var diffResults = dmp.diff_main(newLandingPageMd, originalLandingPageMd); foreach (var result in diffResults) { if (result.operation != DiffMatchPatch.Operation.EQUAL) { System.IO.File.WriteAllText(landingPagePath, newLandingPageMd); } } }
public void Update(object sender, EventArgs e) { System.Diagnostics.Debug.WriteLine(textbox.Text); //sd.send_string(textbox.Text); var dmp = new DiffMatchPatch.diff_match_patch(); var d = dmp.diff_main(original, textbox.Text); //dmp.diff_cleanupSemantic(d); //String diffs = dmp.diff_prettyHtml(d); var patches = dmp.patch_make(d); var patch_string = dmp.patch_toText(patches); sd.send_string(patch_string); original = textbox.Text; }
private void GenerateTOC() { var originalMd = string.Empty; var newMd = string.Empty; // Create the readme.md var readmePath = $"{_solutionDir}\\Documentation\\readme.{extension}"; if (System.IO.File.Exists(readmePath)) { originalMd = System.IO.File.ReadAllText(readmePath); } var docBuilder = new StringBuilder(); docBuilder.AppendFormat("# Cmdlet Documentation #{0}", Environment.NewLine); docBuilder.AppendFormat("Below you can find a list of all the available cmdlets. Many commands provide built-in help and examples. Retrieve the detailed help with {0}", Environment.NewLine); docBuilder.AppendFormat("{0}```powershell{0}Get-Help Connect-PnPOnline -Detailed{0}```{0}{0}", Environment.NewLine); // Get all unique categories var categories = _cmdlets.Where(c => !string.IsNullOrEmpty(c.Category)).Select(c => c.Category).Distinct(); foreach (var category in categories.OrderBy(c => c)) { docBuilder.AppendFormat("## {0}{1}", category, Environment.NewLine); docBuilder.AppendFormat("Cmdlet|Description|Platforms{0}", Environment.NewLine); docBuilder.AppendFormat(":-----|:----------|:--------{0}", Environment.NewLine); foreach (var cmdletInfo in _cmdlets.Where(c => c.Category == category).OrderBy(c => c.Noun)) { var description = cmdletInfo.Description != null?cmdletInfo.Description.Replace("\r\n", " ") : ""; docBuilder.AppendFormat("**[{0}]({1}{2}.md)** |{3}|{4}{5}", cmdletInfo.FullCommand.Replace("-", "‑"), cmdletInfo.Verb, cmdletInfo.Noun, description, cmdletInfo.Platform, Environment.NewLine); } } newMd = docBuilder.ToString(); DiffMatchPatch.diff_match_patch dmp = new DiffMatchPatch.diff_match_patch(); var diffResults = dmp.diff_main(newMd, originalMd); foreach (var result in diffResults) { if (result.operation != DiffMatchPatch.Operation.EQUAL) { System.IO.File.WriteAllText(readmePath, docBuilder.ToString()); } } }
/// <summary> /// Replaces text without losing markers, expanding folded code, etc. /// </summary> public void ZReplaceTextGently(string s) { if (Z.IsReadonly) { return; } int len = s.Lenn(); if (len == 0) { goto gRaw; } string old = Text; if (len > 1_000_000 || old.Length > 1_000_000 || old.Length == 0) { goto gRaw; } var dmp = new DiffMatchPatch.diff_match_patch(); var a = dmp.diff_main(old, s, true); //the slowest part. Timeout 1 s; then a valid but smaller. if (a.Count > 1000) { goto gRaw; } dmp.diff_cleanupEfficiency(a); Call(SCI_BEGINUNDOACTION); for (int i = a.Count - 1, j = old.Length; i >= 0; i--) { var d = a[i]; if (d.operation == DiffMatchPatch.Operation.INSERT) { Z.InsertText(true, j, d.text); } else { j -= d.text.Length; if (d.operation == DiffMatchPatch.Operation.DELETE) { Z.DeleteRange(true, j, j + d.text.Length); } } } Call(SCI_ENDUNDOACTION); return; gRaw: this.Text = s; }
public void PrintDiff(ILogging logger) { var diff = new DiffMatchPatch.diff_match_patch(); foreach (var kvp in Updated) { var c1 = ContentSelector(Orig[kvp.Key]); var c2 = ContentSelector(kvp.Value); if (string.IsNullOrEmpty(c1) || string.IsNullOrEmpty(c2) || string.Equals(c1, c2)) { //no diffs } else { var diffs = diff.diff_main(c1, c2); diff.diff_cleanupSemantic(diffs); logger.WriteLine(string.Format("K: {0}, {1}", kvp.Key, diff.diff_prettyHtml(diffs))); /* * foreach (var d in diffs) * { * logger.WriteLine("{0}: {1}", d.operation, d.text); * }*/ logger.WriteLine("<hr/>"); } } foreach (var kvp in New) { var n = ContentSelector(New[kvp.Key]); logger.WriteLine(string.Format("N: {0}, {1}", kvp.Key, n)); logger.WriteLine("<hr/>"); } foreach (var kvp in Deleted) { var n = ContentSelector(Deleted[kvp.Key]); logger.WriteLine(string.Format("D: {0}, {1}", kvp.Key, n)); logger.WriteLine("<hr/>"); } }
///// <summary> ///// Diffs two files and displays the diffed content in a single SyntaxEditor, with no striking out of lines. ///// </summary> ///// <param name="editor"></param> ///// <param name="fileBodyLeft"></param> ///// <param name="fileBodyRight"></param> ///// <returns></returns> //public static bool Perform2WayDiffInSingleEditor( // ActiproSoftware.SyntaxEditor.SyntaxEditor editor, // ref string fileBodyLeft, // ref string fileBodyRight) //{ // return Perform2WayDiffInSingleEditor(editor, ref fileBodyLeft, ref fileBodyRight, true); //} public static bool Perform2WayDiffInSingleEditor(SyntaxEditor editor, string text1, string text2) { text1 = text1.Replace("\r\n", "\n"); text2 = text2.Replace("\r\n", "\n"); var dmp = new DiffMatchPatch.diff_match_patch(); dmp.Diff_Timeout = 5.0F; dmp.Diff_EditCost = 4; dmp.Match_Threshold = 0.5F; var diffs = dmp.diff_main(text1, text2, true); dmp.diff_cleanupSemantic(diffs); if (diffs.Count == 1 && diffs[0].operation == DiffMatchPatch.Operation.EQUAL) { editor.Document.Text = diffs[0].text; return true; } DiffInSingleEditor(diffs, editor); return false; }
public void PrintDiff(TextWriter os = null) { if (os == null) { os = Console.Out; } var diff = new DiffMatchPatch.diff_match_patch(); foreach (var kvp in Updated) { var diffs = diff.diff_main(Orig[kvp.Key], kvp.Value); diff.diff_cleanupSemantic(diffs); os.WriteLine("K: {0}, diffs {1}", kvp.Key, diffs.Count); foreach (var d in diffs) { os.WriteLine("{0}: {1}", d.operation, d.text); } //diff.diff_prettyHtml(diffs); } }
///// <summary> ///// Diffs two files and displays the diffed content in a single SyntaxEditor, with no striking out of lines. ///// </summary> ///// <param name="editor"></param> ///// <param name="fileBodyLeft"></param> ///// <param name="fileBodyRight"></param> ///// <returns></returns> //public static bool Perform2WayDiffInSingleEditor( // ActiproSoftware.SyntaxEditor.SyntaxEditor editor, // ref string fileBodyLeft, // ref string fileBodyRight) //{ // return Perform2WayDiffInSingleEditor(editor, ref fileBodyLeft, ref fileBodyRight, true); //} public static bool Perform2WayDiffInSingleEditor(SyntaxEditor editor, string text1, string text2) { text1 = text1.Replace("\r\n", "\n"); text2 = text2.Replace("\r\n", "\n"); var dmp = new DiffMatchPatch.diff_match_patch(); dmp.Diff_Timeout = 5.0F; dmp.Diff_EditCost = 4; dmp.Match_Threshold = 0.5F; var diffs = dmp.diff_main(text1, text2, true); dmp.diff_cleanupSemantic(diffs); if (diffs.Count == 1 && diffs[0].operation == DiffMatchPatch.Operation.EQUAL) { editor.Document.Text = diffs[0].text; return(true); } DiffInSingleEditor(diffs, editor); return(false); }
public static string ShowDiffsAsHtml(string oldText, string newText, int?sizeThreshold = null, bool cleanupSemantic = false) { var dmp = new DiffMatchPatch.diff_match_patch(); var diffs = dmp.diff_main(oldText ?? "", newText ?? ""); if (sizeThreshold != null && ((oldText != null && oldText.Length <= sizeThreshold) || (newText != null && newText.Length <= sizeThreshold) ) ) { return ((string.IsNullOrEmpty(oldText) ? "" : "<del style=\"background:#ffe6e6;display:inline-block;padding:4px 8px 4px 8px;\">" + CorrectHtml(oldText) + "</del>" + " ") + (string.IsNullOrEmpty(newText) ? "" : "<ins style=\"background:#e6ffe6;display:inline-block;padding:4px 8px 4px 8px;\">" + CorrectHtml(newText) + "</ins>")); } if (cleanupSemantic) { dmp.diff_cleanupSemantic(diffs); } return(dmp.diff_prettyHtml(diffs)); }
private void GenerateCmdletDocs() { foreach (var cmdletInfo in _cmdlets) { var originalMd = string.Empty; var newMd = string.Empty; if (!string.IsNullOrEmpty(cmdletInfo.Verb) && !string.IsNullOrEmpty(cmdletInfo.Noun)) { string mdFilePath = $"{_solutionDir}\\Documentation\\{cmdletInfo.Verb}{cmdletInfo.Noun}.{extension}"; if (System.IO.File.Exists(mdFilePath)) { originalMd = System.IO.File.ReadAllText(mdFilePath); } var docBuilder = new StringBuilder(); // Header docBuilder.Append($"# {cmdletInfo.FullCommand}{Environment.NewLine}{Environment.NewLine}"); // Body if (cmdletInfo.Platform != "All") { docBuilder.Append($"## SYNOPSIS{Environment.NewLine}{cmdletInfo.Description}{Environment.NewLine}{Environment.NewLine}>Only available for {cmdletInfo.Platform}{Environment.NewLine}{Environment.NewLine}"); } else { docBuilder.Append($"## SYNOPSIS{Environment.NewLine}{cmdletInfo.Description}{Environment.NewLine}{Environment.NewLine}"); } if (cmdletInfo.Syntaxes.Any()) { docBuilder.Append($"## SYNTAX {Environment.NewLine}{Environment.NewLine}"); foreach (var cmdletSyntax in cmdletInfo.Syntaxes.OrderBy(s => s.Parameters.Count(p => p.Required))) { if (cmdletSyntax.ParameterSetName != "__AllParameterSets") { docBuilder.Append($"### {cmdletSyntax.ParameterSetName}{Environment.NewLine}"); } var syntaxText = new StringBuilder(); syntaxText.AppendFormat("```powershell\r\n{0} ", cmdletInfo.FullCommand); var cmdletLength = cmdletInfo.FullCommand.Length; var first = true; foreach (var par in cmdletSyntax.Parameters.Distinct(new ParameterComparer()).OrderBy(p => !p.Required).ThenBy(p => p.Position)) { if (first) { first = false; } else { syntaxText.Append(new string(' ', cmdletLength + 1)); } if (!par.Required) { syntaxText.Append("["); } if (par.Type.StartsWith("Int")) { par.Type = "Int"; } if (par.Type == "SwitchParameter") { syntaxText.AppendFormat("-{0} [<{1}>]", par.Name, par.Type); } else { syntaxText.AppendFormat("-{0} <{1}>", par.Name, par.Type); } if (!par.Required) { syntaxText.Append("]"); } syntaxText.Append("\r\n"); } // Add All ParameterSet ones docBuilder.Append(syntaxText); docBuilder.Append($"```{Environment.NewLine}{Environment.NewLine}"); } } if (!string.IsNullOrEmpty(cmdletInfo.DetailedDescription)) { docBuilder.Append($"## DESCRIPTION{Environment.NewLine}"); docBuilder.Append($"{cmdletInfo.DetailedDescription}{Environment.NewLine}{Environment.NewLine}"); } if (cmdletInfo.Examples.Any()) { docBuilder.Append($"## EXAMPLES{Environment.NewLine}{Environment.NewLine}"); var examplesCount = 1; foreach (var example in cmdletInfo.Examples.OrderBy(e => e.SortOrder)) { docBuilder.Append($"### ------------------EXAMPLE {examplesCount}------------------{Environment.NewLine}"); if (!string.IsNullOrEmpty(example.Introduction)) { docBuilder.Append($"{example.Introduction}{Environment.NewLine}"); } docBuilder.Append($"```powershell{Environment.NewLine}{example.Code}{Environment.NewLine}```{Environment.NewLine}{Environment.NewLine}"); docBuilder.Append($"{example.Remarks}{Environment.NewLine}{Environment.NewLine}"); examplesCount++; } } if (cmdletInfo.Parameters.Any()) { docBuilder.Append($"## PARAMETERS{Environment.NewLine}{Environment.NewLine}"); foreach (var parameter in cmdletInfo.Parameters.OrderBy(x => x.Name).Distinct(new ParameterComparer())) { if (parameter.Type.StartsWith("Int")) { parameter.Type = "Int"; } docBuilder.Append($"### -{parameter.Name}{Environment.NewLine}"); docBuilder.Append($"{parameter.Description}{Environment.NewLine}{Environment.NewLine}"); docBuilder.Append($"```yaml{Environment.NewLine}"); docBuilder.Append($"Type: {parameter.Type}{Environment.NewLine}"); if (parameter.ParameterSetName == "__AllParameterSets") { parameter.ParameterSetName = "(All)"; } docBuilder.Append($"Parameter Sets: { parameter.ParameterSetName}{Environment.NewLine}"); if (parameter.Aliases.Any()) { docBuilder.Append($"Aliases: {string.Join(",", parameter.Aliases)}{Environment.NewLine}"); } docBuilder.Append(Environment.NewLine); docBuilder.Append($"Required: {parameter.Required}{Environment.NewLine}"); docBuilder.Append($"Position: {(parameter.Position == int.MinValue ? "Named" : parameter.Position.ToString())}{Environment.NewLine}"); docBuilder.Append($"Accept pipeline input: {parameter.ValueFromPipeline}{Environment.NewLine}"); docBuilder.Append($"```{Environment.NewLine}{Environment.NewLine}"); } } if (cmdletInfo.OutputType != null) { docBuilder.Append($"## OUTPUTS{Environment.NewLine}{Environment.NewLine}"); var outputType = ""; if (cmdletInfo.OutputType != null) { if (cmdletInfo.OutputType.IsGenericType) { if (cmdletInfo.OutputType.GetGenericTypeDefinition() == typeof(List <>) || cmdletInfo.OutputType.GetGenericTypeDefinition() == typeof(IEnumerable <>)) { if (cmdletInfo.OutputType.GenericTypeArguments.Any()) { outputType = $"List<{cmdletInfo.OutputType.GenericTypeArguments[0].FullName}>"; } else { outputType = cmdletInfo.OutputType.FullName; } } else { outputType = cmdletInfo.OutputType.FullName; } } else { outputType = cmdletInfo.OutputType.FullName; } } if (!string.IsNullOrEmpty(cmdletInfo.OutputTypeLink)) { docBuilder.Append($"### [{outputType}]({cmdletInfo.OutputTypeLink})"); } else { docBuilder.Append($"### {outputType}"); } if (!string.IsNullOrEmpty(cmdletInfo.OutputTypeDescription)) { docBuilder.Append($"\n\n{cmdletInfo.OutputTypeDescription}"); } docBuilder.Append("\n\n"); } if (cmdletInfo.RelatedLinks.Any()) { docBuilder.Append($"# RELATED LINKS{Environment.NewLine}{Environment.NewLine}"); foreach (var link in cmdletInfo.RelatedLinks) { docBuilder.Append($"[{link.Text}]({link.Url})"); } } newMd = docBuilder.ToString(); var dmp = new DiffMatchPatch.diff_match_patch(); var diffResults = dmp.diff_main(newMd, originalMd); foreach (var result in diffResults) { if (result.operation != DiffMatchPatch.Operation.EQUAL) { System.IO.File.WriteAllText(mdFilePath, docBuilder.ToString()); break; } } } } }
public string Export(List <GitCommit> commits, bool debug) { if (!commits.Any()) { return(""); } StringWriter w = new StringWriter(); if (commits.Any()) { w.WriteLine(EmitDate(commits.First().CommitTimeStamp)); } else { w.WriteLine("### No commits!"); w.WriteLine("Please make sure that *autogit* is properly saving changes in your solution directory in the hidden folder `.HistoryData/LocalHistory`"); } var diffEngine = new DiffMatchPatch.diff_match_patch(); GitCommit previousCommit = null; bool isFirstCommit = true; foreach (var commit in commits) { var span = TimeSinceLastCommit(commit, previousCommit); if (span != TimeSpan.MaxValue && !IsCommitOnSameDay(commit, previousCommit)) { w.WriteLine(EmitDate(commit.CommitTimeStamp)); } if (isFirstCommit || (span != TimeSpan.MaxValue && span.TotalHours > 2) || !IsCommitOnSameDay(commit, previousCommit)) { w.WriteLine(""); w.WriteLine(string.Format("<div class='section'>{0}<div></div><div class='summary'></div></div>", EmitTime(commit.CommitTimeStamp))); isFirstCommit = false; } // Sunday, October 6 2013 // 10:44 AM //if (span != TimeSpan.MaxValue && span.TotalHours > 2) //{ // w.WriteLine("<div class='divider'></div>"); // w.WriteLine(EmitTime(commit.CommitTimeStamp)); //} if (commit.Visits.Any()) { //w.WriteLine("#### Visited "); w.WriteLine(" "); foreach (var visit in commit.Visits) { w.WriteLine("* [{0}]({1})", string.IsNullOrEmpty(visit.Title) ? visit.Url : visit.Title, visit.Url); } w.WriteLine(" "); if (commit.Visits.Count == 1) { w.WriteLine("<div></div>"); } } foreach (var fileDiff in commit.Difflets) { //w.WriteLine("> {0} to {1}", file.Status, file.File); w.WriteLine("#### {0}", fileDiff.FileName); w.WriteLine(); foreach (var hunk in fileDiff.Hunks) { foreach (var line in hunk.DiffLines) { // http://stackoverflow.com/questions/8301207/microsoft-ides-source-file-encodings-boms-and-the-unicode-character-ufeff // default filter: skip context of adding using. if (line.Trim().StartsWith("using ")) { continue; } w.WriteLine(" {0}", line.TrimEnd()); } } // test space if (debug) { w.WriteLine("##### Myers Version"); var diffs = fileDiff.MyerDiffs; foreach (var diff in diffs) { w.WriteLine("Type {0} Left {1}:{2} Right {3}:{4}", diff.DifferenceType, diff.Left.Start, diff.Left.End, diff.Right.Start, diff.Right.End); if (diff.DifferenceType == Models.Diff.DifferenceType.Change && diff.Left.Length == diff.Right.Length) { w.WriteLine(); for (var i = 0; i < diff.Left.Length; i++) { var left = diff.Left.TextLines[i]; var right = diff.Right.TextLines[i]; var innerDiffs = diffEngine.diff_main(left, right, false); diffEngine.Diff_Timeout = 0; diffEngine.diff_cleanupSemantic(innerDiffs); w.WriteLine(string.Join(",", innerDiffs.Where(d => d.operation != DiffMatchPatch.Operation.EQUAL).Select(d => d.text))); } } } } } previousCommit = commit; } return(w.ToString()); }
/// <summary> /// Writes a difference summary to the file system. /// </summary> /// <param name="differences">The differences.</param> /// <param name="referenceDatabase">Reference database definition</param> /// <param name="targetDatabase">Target database to update</param> public static void WriteDifferenceSummary(DBTypes.Database referenceDatabase, DBTypes.Database targetDatabase, DifferenceSet differences) { StreamWriter diffWriter = new StreamWriter(Path.Combine(RunOptions.Current.ScriptOutputDirectory, RunOptions.Current.DiffFile), false); var patchGenerator = new DiffMatchPatch.diff_match_patch(); foreach (var difference in differences) { if (difference.DifferenceType != DifferenceType.Modified) { continue; } diffWriter.WriteLine(difference.ToString()); diffWriter.WriteLine(); var referenceDefinition = referenceDatabase[difference.Item].GenerateCreateScript(); var targetDefinition = targetDatabase[difference.Item].GenerateCreateScript(); var diff = patchGenerator.diff_main(targetDefinition.Text, referenceDefinition.Text); //var patch = patchGenerator.diff_prettyHtml(diff); //patch = System.Web.HttpUtility.UrlDecode(patch); //diffWriter.WriteLine(patch); //Diffs aren't full lines... we need to fix that for readability var coalesced = new List <DiffMatchPatch.Diff>(); DiffMatchPatch.Diff lastEqual = null; DiffMatchPatch.Diff lastInsert = null; DiffMatchPatch.Diff lastDelete = null; foreach (var entry in diff) { if (entry.operation == DiffMatchPatch.Operation.INSERT) { lastInsert = lastInsert ?? new DiffMatchPatch.Diff(entry.operation, ""); lastInsert.text += entry.text; } else if (entry.operation == DiffMatchPatch.Operation.DELETE) { lastDelete = lastDelete ?? new DiffMatchPatch.Diff(entry.operation, ""); lastDelete.text += entry.text; } else if (entry.operation == DiffMatchPatch.Operation.EQUAL) { string content = entry.text; int linebreak = content.IndexOf("\n"); string donate = linebreak < 0 ? content : content.Substring(0, linebreak + 1); //see if there's a change that needs this to finish its line bool used = false; if (lastInsert != null) { lastInsert.text += donate; used = true; } if (lastDelete != null) { lastDelete.text += donate; used = true; } if (used) { content = content.Remove(0, donate.Length); } //stash anything that's left if (content.Length > 0) { //time to flush everything we've coalesced //see if there are any mods that need to grab a line start if (lastEqual != null && !lastEqual.text.EndsWith("\n") && (lastInsert != null || lastDelete != null)) { linebreak = lastEqual.text.LastIndexOf("\n"); donate = lastEqual.text.Substring(linebreak + 1); lastEqual.text = lastEqual.text.Remove(linebreak + 1); if (lastInsert != null) { lastInsert.text = donate + lastInsert.text; } if (lastDelete != null) { lastDelete.text = donate + lastDelete.text; } } //do the flush if (lastEqual != null) { coalesced.Add(lastEqual); lastEqual = null; } if (lastInsert != null) { coalesced.Add(lastInsert); lastInsert = null; } if (lastDelete != null) { coalesced.Add(lastDelete); lastDelete = null; } lastEqual = new DiffMatchPatch.Diff(DiffMatchPatch.Operation.EQUAL, content); } } else { throw new Exception("Unknown operation: " + entry.operation); } } if (lastEqual != null) { coalesced.Add(lastEqual); } if (lastInsert != null) { coalesced.Add(lastInsert); } if (lastDelete != null) { coalesced.Add(lastDelete); } //Finally spit out a nice diff for (int i = 0; i < coalesced.Count; i++) { var entry = coalesced[i]; if (entry.operation == DiffMatchPatch.Operation.EQUAL) { //(ab)use a stream to partition the content into lines using (var text = new StreamReader(new MemoryStream(Encoding.UTF8.GetBytes(entry.text)))) { //write out the first two lines if (i > 0) { for (int j = 0; j < 2 && !text.EndOfStream; j++) { string line = text.ReadLine(); if (string.IsNullOrEmpty(line)) { j--; continue; } diffWriter.WriteLine(line); } } //write out the last two lines if (i < coalesced.Count - 1 && !text.EndOfStream) { var lines = new string[3]; while (!text.EndOfStream) { lines[0] = lines[1]; lines[1] = lines[2]; lines[2] = text.ReadLine(); } if (i > 0 && lines[0] != null) { diffWriter.WriteLine(); diffWriter.WriteLine(">> ... <<"); diffWriter.WriteLine(); } if (lines[1] != null) { diffWriter.WriteLine(lines[1]); } diffWriter.WriteLine(lines[2]); } } } else { string marker = entry.operation == DiffMatchPatch.Operation.INSERT ? "> > > >" : "< < < <"; diffWriter.WriteLine(marker); diffWriter.Write(entry.text); if (!entry.text.EndsWith("\n")) { diffWriter.WriteLine(); } diffWriter.WriteLine(marker); } } diffWriter.WriteLine(); } diffWriter.Close(); }
public static bool ToMatchSnapshot( this object result, bool update = false, [CallerMemberName] string name = "", [CallerFilePath] string file = "", [CallerLineNumber] int line = 0 ) { var newLine = System.Environment.NewLine; var current = Directory.GetCurrentDirectory(); var snapshotFolder = Path.Combine(current, "__snaphots__"); var filename = Path.Combine(snapshotFolder, string.Format("{0}.snap", Path.GetFileName(file))); var dictionary = new Dictionary <string, string>(); var serializer = new JsonSerializer(); var directoryExists = Directory.Exists(snapshotFolder); var fileExists = File.Exists(filename); var key = String.Format("{0} ({1})", MethodToSentence(name), line); if (directoryExists && fileExists) { var text = File.ReadAllText(filename); dictionary = JsonConvert.DeserializeObject <Dictionary <string, string> >(text); if (dictionary.ContainsKey(key)) { var value = dictionary[key]; if (!update && value != result.ToString()) { Console.Write("{0}Snapshot failed:{0}Diff:{0}", newLine); var diff = new DiffMatchPatch.diff_match_patch(); var differences = diff.diff_main(value, result.ToString()); diff.diff_cleanupSemantic(differences); foreach (var difference in differences) { switch (difference.operation) { case DiffMatchPatch.Operation.DELETE: Console.ForegroundColor = ConsoleColor.Red; break; case DiffMatchPatch.Operation.EQUAL: Console.ForegroundColor = ConsoleColor.Gray; break; case DiffMatchPatch.Operation.INSERT: Console.ForegroundColor = ConsoleColor.Green; break; } Console.Write(difference.text); } Console.Write(newLine); return(false); } } } else { Directory.CreateDirectory(snapshotFolder); } if (dictionary.ContainsKey(key)) { dictionary.Remove(key); } dictionary.Add(key, result.ToString()); File.WriteAllText(filename, JsonConvert.SerializeObject(dictionary)); return(true); }
private void GenerateMSDNTOC() { var originalTocMd = string.Empty; var newTocMd = string.Empty; var msdnDocPath = $"{_solutionDir}\\Documentation\\MSDN"; if (!Directory.Exists(msdnDocPath)) { Directory.CreateDirectory(msdnDocPath); } // Generate the landing page var landingPagePath = $"{msdnDocPath}\\PnP-PowerShell-Overview.{extension}"; GenerateMSDNLandingPage(landingPagePath); // TOC.md generation var tocPath = $"{msdnDocPath}\\TOC.{extension}"; if (System.IO.File.Exists(tocPath)) { originalTocMd = System.IO.File.ReadAllText(tocPath); } var docBuilder = new StringBuilder(); docBuilder.AppendFormat("# [SharePoint PnP PowerShell reference](PnP-PowerShell-Overview.md){0}", Environment.NewLine); // Get all unique categories var categories = _cmdlets.Where(c => !string.IsNullOrEmpty(c.Category)).Select(c => c.Category).Distinct(); foreach (var category in categories.OrderBy(c => c)) { var categoryMdPage = $"{category.Replace(" ", "")}-category.{extension}"; var categoryMdPath = $"{msdnDocPath}\\{categoryMdPage}"; // Add section reference to TOC docBuilder.AppendFormat("## [{0}]({1}){2}", category, categoryMdPage, Environment.NewLine); var categoryCmdlets = _cmdlets.Where(c => c.Category == category).OrderBy(c => c.Noun); // Generate category MD GenerateMSDNCategory(category, categoryMdPath, categoryCmdlets); // Link cmdlets to TOC foreach (var cmdletInfo in categoryCmdlets) { var description = cmdletInfo.Description != null?cmdletInfo.Description.Replace("\r\n", " ") : ""; docBuilder.AppendFormat("### [{0}]({1}{2}.md){3}", cmdletInfo.FullCommand, cmdletInfo.Verb, cmdletInfo.Noun, Environment.NewLine); } } newTocMd = docBuilder.ToString(); DiffMatchPatch.diff_match_patch dmp = new DiffMatchPatch.diff_match_patch(); var diffResults = dmp.diff_main(newTocMd, originalTocMd); foreach (var result in diffResults) { if (result.operation != DiffMatchPatch.Operation.EQUAL) { System.IO.File.WriteAllText(tocPath, docBuilder.ToString()); } } }
private static void GenerateMarkDown(List <CmdletInfo> toc, string solutionDir, List <CmdletExampleAttribute> examples, CmdletInfo cmdletInfo) { var originalMd = string.Empty; var newMd = string.Empty; if (!string.IsNullOrEmpty(cmdletInfo.Verb) && !string.IsNullOrEmpty(cmdletInfo.Noun)) { string mdFilePath = $"{solutionDir}\\Documentation\\{cmdletInfo.Verb}{cmdletInfo.Noun}.md"; toc.Add(cmdletInfo); if (System.IO.File.Exists(mdFilePath)) { originalMd = System.IO.File.ReadAllText(mdFilePath); } var docBuilder = new StringBuilder(); // Header docBuilder.AppendFormat("#{0}{1}", cmdletInfo.FullCommand, Environment.NewLine); // Body docBuilder.AppendFormat("{0}{1}", cmdletInfo.Description, Environment.NewLine); docBuilder.AppendFormat("##Syntax{0}", Environment.NewLine); foreach (var cmdletSyntax in cmdletInfo.Syntaxes.OrderBy(s => s.ParameterSetName)) { var syntaxText = new StringBuilder(); syntaxText.AppendFormat("```powershell\r\n{0} ", cmdletInfo.FullCommand); var cmdletLength = cmdletInfo.FullCommand.Length; var first = true; foreach (var par in cmdletSyntax.Parameters.OrderBy(p => p.Position)) { if (first) { first = false; } else { syntaxText.Append(new string(' ', cmdletLength + 1)); } if (!par.Required) { syntaxText.Append("["); } if (par.Type == "SwitchParameter") { syntaxText.AppendFormat("-{0} [<{1}>]", par.Name, par.Type); } else { syntaxText.AppendFormat("-{0} <{1}>", par.Name, par.Type); } if (!par.Required) { syntaxText.Append("]"); } syntaxText.Append("\r\n"); } // Add All ParameterSet ones docBuilder.Append(syntaxText); docBuilder.AppendFormat("```\n\n\n"); } if (!string.IsNullOrEmpty(cmdletInfo.DetailedDescription)) { docBuilder.Append("##Detailed Description\n"); docBuilder.AppendFormat("{0}\n\n", cmdletInfo.DetailedDescription); } if (cmdletInfo.OutputType != null) { docBuilder.Append("##Returns\n"); if (!string.IsNullOrEmpty(cmdletInfo.OutputTypeLink)) { docBuilder.Append($">[{cmdletInfo.OutputType}]({cmdletInfo.OutputTypeLink})"); } else { docBuilder.Append($">{cmdletInfo.OutputType}"); } if (!string.IsNullOrEmpty(cmdletInfo.OutputTypeDescription)) { docBuilder.Append($"\n\n{cmdletInfo.OutputTypeDescription}"); } docBuilder.Append("\n\n"); } docBuilder.Append("##Parameters\n"); docBuilder.Append("Parameter|Type|Required|Description\n"); docBuilder.Append("---------|----|--------|-----------\n"); foreach (var par in cmdletInfo.Parameters.OrderBy(x => x.Name)) { docBuilder.AppendFormat("|{0}|{1}|{2}|{3}|\n", par.Name, par.Type, par.Required ? "True" : "False", par.Description); } if (examples.Any()) { docBuilder.Append("##Examples\n"); } var examplesCount = 1; foreach (var example in examples.OrderBy(e => e.SortOrder)) { docBuilder.AppendFormat("{0}\n", example.Introduction); docBuilder.AppendFormat("###Example {0}\n", examplesCount); docBuilder.AppendFormat("```powershell\n{0}\n```\n", example.Code); docBuilder.AppendFormat("{0}\n", example.Remarks); examplesCount++; } newMd = docBuilder.ToString(); var dmp = new DiffMatchPatch.diff_match_patch(); var diffResults = dmp.diff_main(newMd, originalMd); foreach (var result in diffResults) { if (result.operation != DiffMatchPatch.Operation.EQUAL) { System.IO.File.WriteAllText(mdFilePath, docBuilder.ToString()); break; } } } }
static void Main(string[] args) { var cmdlets = new List <CmdletInfo>(); var inFile = args[0]; var outFile = args[1]; var toc = new List <CmdletInfo>(); // Specify an additional (third) parameter pointing to the Solution folder to generate Markdown. The markdown // will be created in the Documentation folder underneath the solution folder. bool generateMarkdown = false; string solutionDir = null; if (args.Length > 2) { solutionDir = args[2]; generateMarkdown = true; } var doc = new XDocument(new XDeclaration("1.0", "UTF-8", string.Empty)); XNamespace ns = "http://msh"; var helpItems = new XElement(ns + "helpItems", new XAttribute("schema", "maml")); doc.Add(helpItems); XNamespace maml = "http://schemas.microsoft.com/maml/2004/10"; XNamespace command = "http://schemas.microsoft.com/maml/dev/command/2004/10"; XNamespace dev = "http://schemas.microsoft.com/maml/dev/2004/10"; var mamlNsAttr = new XAttribute(XNamespace.Xmlns + "maml", "http://schemas.microsoft.com/maml/2004/10"); var commandNsAttr = new XAttribute(XNamespace.Xmlns + "command", "http://schemas.microsoft.com/maml/dev/command/2004/10"); var devNsAttr = new XAttribute(XNamespace.Xmlns + "dev", "http://schemas.microsoft.com/maml/dev/2004/10"); var assembly = Assembly.LoadFrom(inFile); var types = assembly.GetTypes(); foreach (var t in types) { if (t.BaseType.Name == "SPOCmdlet" || t.BaseType.Name == "PSCmdlet" || t.BaseType.Name == "SPOWebCmdlet" || t.BaseType.Name == "SPOAdminCmdlet") { //XElement examples = new XElement(command + "examples"); var verb = string.Empty; var noun = string.Empty; var description = string.Empty; var detaileddescription = string.Empty; var copyright = string.Empty; var version = string.Empty; var category = string.Empty; var attrs = t.GetCustomAttributes(); var examples = new List <CmdletExampleAttribute>(); var relatedLinks = new List <CmdletRelatedLinkAttribute>(); //System.Attribute.GetCustomAttributes(t); // Get info from attributes foreach (var attr in attrs) { if (attr is CmdletAttribute) { var a = (CmdletAttribute)attr; verb = a.VerbName; noun = a.NounName; } if (attr is CmdletHelpAttribute) { var a = (CmdletHelpAttribute)attr; description = a.Description; copyright = a.Copyright; version = a.Version; detaileddescription = a.DetailedDescription; category = ToEnumString(a.Category); } if (attr is CmdletExampleAttribute) { var a = (CmdletExampleAttribute)attr; examples.Add(a); } if (attr is CmdletRelatedLinkAttribute) { var l = (CmdletRelatedLinkAttribute)attr; relatedLinks.Add(l); } } // Store in CmdletInfo structure var cmdletInfo = new CmdletInfo(verb, noun); cmdletInfo.Description = description; cmdletInfo.DetailedDescription = detaileddescription; cmdletInfo.Version = version; cmdletInfo.Copyright = copyright; cmdletInfo.Category = category; // Build XElement for command var commandElement = new XElement(command + "command", mamlNsAttr, commandNsAttr, devNsAttr); var detailsElement = new XElement(command + "details"); commandElement.Add(detailsElement); detailsElement.Add(new XElement(command + "name", string.Format("{0}-{1}", verb, noun))); detailsElement.Add(new XElement(maml + "description", new XElement(maml + "para", description))); detailsElement.Add(new XElement(maml + "copyright", new XElement(maml + "para", copyright))); detailsElement.Add(new XElement(command + "verb", verb)); detailsElement.Add(new XElement(command + "noun", noun)); detailsElement.Add(new XElement(dev + "version", version)); if (!string.IsNullOrWhiteSpace(detaileddescription)) { commandElement.Add(new XElement(maml + "description", new XElement(maml + "para", detaileddescription))); } var syntaxElement = new XElement(command + "syntax"); commandElement.Add(syntaxElement); // Store syntaxes in CmdletInfo structure (if not AllParameterSets), and also in all syntaxItems list var fields = t.GetFields(); var syntaxItems = new List <SyntaxItem>(); foreach (var field in fields) { var dontShow = false; foreach (Attribute attr in field.GetCustomAttributes(typeof(ObsoleteAttribute), true)) { if (attr is ObsoleteAttribute) { dontShow = true; break; } } foreach (Attribute attr in field.GetCustomAttributes(typeof(ParameterAttribute), true)) { if (attr is ParameterAttribute) { var a = (ParameterAttribute)attr; if (!dontShow) { if (a.ParameterSetName != ParameterAttribute.AllParameterSets) { var cmdletSyntax = cmdletInfo.Syntaxes.FirstOrDefault(c => c.ParameterSetName == a.ParameterSetName); if (cmdletSyntax == null) { cmdletSyntax = new CmdletSyntax(); cmdletSyntax.ParameterSetName = a.ParameterSetName; cmdletInfo.Syntaxes.Add(cmdletSyntax); } cmdletSyntax.Parameters.Add(new CmdletParameterInfo() { Name = field.Name, Description = a.HelpMessage, Position = a.Position, Required = a.Mandatory, Type = field.FieldType.Name }); var syntaxItem = syntaxItems.FirstOrDefault(x => x.Name == a.ParameterSetName); if (syntaxItem == null) { syntaxItem = new SyntaxItem(a.ParameterSetName); syntaxItems.Add(syntaxItem); } syntaxItem.Parameters.Add(new SyntaxItem.Parameter() { Name = field.Name, Description = a.HelpMessage, Position = a.Position, Required = a.Mandatory, Type = field.FieldType.Name }); } } } } } // all parameters // Add AllParameterSets to all CmdletInfo syntax sets and syntaxItems sets (first checking there is at least one, i.e. if all are marked AllParameterSets) foreach (var field in fields) { var dontShow = false; foreach (Attribute attr in field.GetCustomAttributes(typeof(ObsoleteAttribute), true)) { if (attr is ObsoleteAttribute) { dontShow = true; break; } } foreach (Attribute attr in field.GetCustomAttributes(typeof(ParameterAttribute), true)) { if (attr is ParameterAttribute) { var a = (ParameterAttribute)attr; if (!dontShow) { if (a.ParameterSetName == ParameterAttribute.AllParameterSets) { if (syntaxItems.Count == 0) { syntaxItems.Add(new SyntaxItem(ParameterAttribute.AllParameterSets)); } foreach (var si in syntaxItems) { si.Parameters.Add(new SyntaxItem.Parameter() { Name = field.Name, Description = a.HelpMessage, Position = a.Position, Required = a.Mandatory, Type = field.FieldType.Name }); } if (cmdletInfo.Syntaxes.Count == 0) { cmdletInfo.Syntaxes.Add(new CmdletSyntax() { ParameterSetName = ParameterAttribute.AllParameterSets }); } foreach (var cmdletSyntax in cmdletInfo.Syntaxes) { cmdletSyntax.Parameters.Add(new CmdletParameterInfo() { Name = field.Name, Description = a.HelpMessage, Position = a.Position, Required = a.Mandatory, Type = field.FieldType.Name }); } } } } } } // Build XElement for parameters from syntaxItems list (note: syntax element is set above) foreach (var syntaxItem in syntaxItems) { var syntaxItemElement = new XElement(command + "syntaxItem"); syntaxElement.Add(syntaxItemElement); syntaxItemElement.Add(new XElement(maml + "name", string.Format("{0}-{1}", verb, noun))); foreach (var parameter in syntaxItem.Parameters) { var parameterElement = new XElement(command + "parameter", new XAttribute("required", parameter.Required), new XAttribute("position", parameter.Position > 0 ? parameter.Position.ToString() : "named")); parameterElement.Add(new XElement(maml + "name", parameter.Name)); parameterElement.Add(new XElement(maml + "description", new XElement(maml + "para", parameter.Description))); parameterElement.Add(new XElement(command + "parameterValue", new XAttribute("required", parameter.Type != "SwitchParameter"), parameter.Type)); syntaxItemElement.Add(parameterElement); } } // Also store parameters in cmdletInfo.Parameters (all parameters) and XElement parameters var parametersElement = new XElement(command + "parameters"); commandElement.Add(parametersElement); foreach (var field in fields) { var dontShow = false; foreach (Attribute attr in field.GetCustomAttributes(typeof(ObsoleteAttribute), true)) { if (attr is ObsoleteAttribute) { dontShow = true; break; } } foreach (Attribute attr in field.GetCustomAttributes(typeof(ParameterAttribute), true)) { if (attr is ParameterAttribute) { var a = (ParameterAttribute)attr; if (!dontShow) { cmdletInfo.Parameters.Add(new CmdletParameterInfo() { Name = field.Name, Description = a.HelpMessage, Position = a.Position, Required = a.Mandatory, Type = field.FieldType.Name }); var parameter2Element = new XElement(command + "parameter", new XAttribute("required", a.Mandatory), new XAttribute("position", a.Position > 0 ? a.Position.ToString() : "named")); parameter2Element.Add(new XElement(maml + "name", field.Name)); parameter2Element.Add(new XElement(maml + "description", new XElement(maml + "para", a.HelpMessage))); var parameterValueElement = new XElement(command + "parameterValue", field.FieldType.Name, new XAttribute("required", a.Mandatory)); parameter2Element.Add(parameterValueElement); var devElement = new XElement(dev + "type"); devElement.Add(new XElement(maml + "name", field.FieldType.Name)); devElement.Add(new XElement(maml + "uri")); parameter2Element.Add(devElement); parametersElement.Add(parameter2Element); } break; } } } // XElement inputTypes commandElement.Add( new XElement(command + "inputTypes", new XElement(command + "inputType", new XElement(dev + "type", new XElement(maml + "name", "String"), new XElement(maml + "uri"), new XElement(maml + "description", new XElement(maml + "para", "description")))))); helpItems.Add(commandElement); // XElement return values commandElement.Add( new XElement(command + "returnValues", new XElement(command + "returnValue", new XElement(dev + "type", new XElement(maml + "name", "String"), new XElement(maml + "uri"), new XElement(maml + "description", new XElement(maml + "para", "description")))))); // XElement examples var examplesElement = new XElement(command + "examples"); var exampleCount = 1; foreach (var exampleAttr in examples.OrderBy(e => e.SortOrder)) { var example = new XElement(command + "example"); var title = string.Format("------------------EXAMPLE {0}---------------------", exampleCount); example.Add(new XElement(maml + "title", title)); example.Add(new XElement(maml + "introduction", new XElement(maml + "para", exampleAttr.Introduction))); example.Add(new XElement(dev + "code", exampleAttr.Code)); example.Add(new XElement(maml + "remarks", new XElement(maml + "para", exampleAttr.Remarks))); example.Add(new XElement(command + "commandLines", new XElement(command + "commandLine", new XElement(command + "commandText")))); examplesElement.Add(example); exampleCount++; } commandElement.Add(examplesElement); // Related links var relatedLinksElement = new XElement(maml + "relatedLinks"); relatedLinks.Insert(0, new CmdletRelatedLinkAttribute() { Text = "Office 365 Developer Patterns and Practices", Url = "http://aka.ms/officedevpnp" }); foreach (var link in relatedLinks) { var navigationLinksElement = new XElement(maml + "navigationLink"); var linkText = new XElement(maml + "linkText"); linkText.Value = link.Text + ":"; navigationLinksElement.Add(linkText); var uriElement = new XElement(maml + "uri"); uriElement.Value = link.Url; navigationLinksElement.Add(uriElement); relatedLinksElement.Add(navigationLinksElement); } commandElement.Add(relatedLinksElement); // Markdown from CmdletInfo if (generateMarkdown) { var originalMd = string.Empty; var newMd = string.Empty; if (!string.IsNullOrEmpty(cmdletInfo.Verb) && !string.IsNullOrEmpty(cmdletInfo.Noun)) { string mdFilePath = string.Format("{0}\\Documentation\\{1}{2}.md", solutionDir, cmdletInfo.Verb, cmdletInfo.Noun); toc.Add(cmdletInfo); //var existingHashCode = string.Empty; if (System.IO.File.Exists(mdFilePath)) { originalMd = System.IO.File.ReadAllText(mdFilePath); } var docHeaderBuilder = new StringBuilder(); // Separate header from body to calculate the hashcode later docHeaderBuilder.AppendFormat("#{0}{1}", cmdletInfo.FullCommand, Environment.NewLine); docHeaderBuilder.AppendFormat("*Topic automatically generated on: {0}*{1}", DateTime.Now.ToString("yyyy'-'MM'-'dd"), Environment.NewLine); docHeaderBuilder.Append(Environment.NewLine); // Body var docBuilder = new StringBuilder(); docBuilder.AppendFormat("{0}{1}", cmdletInfo.Description, Environment.NewLine); docBuilder.AppendFormat("##Syntax{0}", Environment.NewLine); foreach (var cmdletSyntax in cmdletInfo.Syntaxes.OrderBy(s => s.ParameterSetName)) { var syntaxText = new StringBuilder(); syntaxText.AppendFormat("```powershell\r\n{0}", cmdletInfo.FullCommand); foreach (var par in cmdletSyntax.Parameters.OrderBy(p => p.Position)) { syntaxText.Append(" "); if (!par.Required) { syntaxText.Append("["); } if (par.Type == "SwitchParameter") { syntaxText.AppendFormat("-{0} [<{1}>]", par.Name, par.Type); } else { syntaxText.AppendFormat("-{0} <{1}>", par.Name, par.Type); } if (!par.Required) { syntaxText.Append("]"); } } // Add All ParameterSet ones docBuilder.Append(syntaxText); docBuilder.AppendFormat("\n```\n\n\n"); } if (!string.IsNullOrEmpty(cmdletInfo.DetailedDescription)) { docBuilder.Append("##Detailed Description\n"); docBuilder.AppendFormat("{0}\n\n", cmdletInfo.DetailedDescription); } docBuilder.Append("##Parameters\n"); docBuilder.Append("Parameter|Type|Required|Description\n"); docBuilder.Append("---------|----|--------|-----------\n"); foreach (var par in cmdletInfo.Parameters.OrderBy(x => x.Name)) { docBuilder.AppendFormat("|{0}|{1}|{2}|{3}|\n", par.Name, par.Type, par.Required ? "True" : "False", par.Description); } if (examples.Any()) { docBuilder.Append("##Examples\n"); } var examplesCount = 1; foreach (var example in examples.OrderBy(e => e.SortOrder)) { docBuilder.AppendFormat("{0}\n", example.Introduction); docBuilder.AppendFormat("###Example {0}\n", examplesCount); docBuilder.AppendFormat("```powershell\n{0}\n```\n", example.Code); docBuilder.AppendFormat("{0}\n", example.Remarks); examplesCount++; } newMd = docBuilder.ToString(); DiffMatchPatch.diff_match_patch dmp = new DiffMatchPatch.diff_match_patch(); var diffResults = dmp.diff_main(newMd, originalMd); foreach (var result in diffResults) { if (!result.text.Contains("*Topic automatically generated on")) { if (result.operation != DiffMatchPatch.Operation.EQUAL) { System.IO.File.WriteAllText(mdFilePath, docHeaderBuilder.Append(docBuilder).ToString()); } } } } } } } doc.Save(outFile); if (generateMarkdown) { var originalMd = string.Empty; var newMd = string.Empty; // Create the readme.md var readmePath = string.Format("{0}\\Documentation\\readme.md", solutionDir); if (System.IO.File.Exists(readmePath)) { originalMd = System.IO.File.ReadAllText(readmePath); } var docBuilder = new StringBuilder(); docBuilder.AppendFormat("# Cmdlet Documentation #{0}", Environment.NewLine); docBuilder.AppendFormat("Below you can find a list of all the available cmdlets. Many commands provide built-in help and examples. Retrieve the detailed help with {0}", Environment.NewLine); docBuilder.AppendFormat("{0}```powershell{0}Get-Help Connect-SPOnline -Detailed{0}```{0}{0}", Environment.NewLine); // Get all unique categories var categories = toc.Select(c => c.Category).Distinct(); foreach (var category in categories.OrderBy(c => c)) { docBuilder.AppendFormat("##{0}{1}", category, Environment.NewLine); docBuilder.AppendFormat("Cmdlet|Description{0}", Environment.NewLine); docBuilder.AppendFormat(":-----|:----------{0}", Environment.NewLine); foreach (var cmdletInfo in toc.Where(c => c.Category == category).OrderBy(c => c.Noun)) { var description = cmdletInfo.Description.Replace("\r\n", " "); docBuilder.AppendFormat("**[{0}]({1}{2}.md)** |{3}{4}", cmdletInfo.FullCommand.Replace("-", "‑"), cmdletInfo.Verb, cmdletInfo.Noun, description, Environment.NewLine); } } newMd = docBuilder.ToString(); DiffMatchPatch.diff_match_patch dmp = new DiffMatchPatch.diff_match_patch(); var diffResults = dmp.diff_main(newMd, originalMd); foreach (var result in diffResults) { if (!result.text.Contains("*Topic automatically generated on")) { if (result.operation != DiffMatchPatch.Operation.EQUAL) { System.IO.File.WriteAllText(readmePath, docBuilder.ToString()); } } } } DirectoryInfo di = new DirectoryInfo(string.Format("{0}\\Documentation", solutionDir)); var mdFiles = di.GetFiles("*.md"); // Clean up old MD files foreach (var mdFile in mdFiles) { if (mdFile.Name.ToLowerInvariant() != "readme.md") { var index = toc.FindIndex(t => string.Format("{0}{1}.md", t.Verb, t.Noun) == mdFile.Name); if (index == -1) { mdFile.Delete(); } } } }
private void GenerateCmdletDocs() { foreach (var cmdletInfo in _cmdlets) { var originalMd = string.Empty; var newMd = string.Empty; if (!string.IsNullOrEmpty(cmdletInfo.Verb) && !string.IsNullOrEmpty(cmdletInfo.Noun)) { string mdFilePath = $"{_solutionDir}\\Documentation\\{cmdletInfo.Verb}{cmdletInfo.Noun}.{extension}"; if (System.IO.File.Exists(mdFilePath)) { originalMd = System.IO.File.ReadAllText(mdFilePath); } var docBuilder = new StringBuilder(); // Header docBuilder.AppendFormat("# {0}{1}", cmdletInfo.FullCommand, Environment.NewLine); // Body docBuilder.AppendFormat("{0}{1}", cmdletInfo.Description, Environment.NewLine); if (cmdletInfo.Platform != "All") { docBuilder.Append($">*Only available for {cmdletInfo.Platform}*{Environment.NewLine}"); } if (cmdletInfo.Syntaxes.Any()) { docBuilder.AppendFormat("## Syntax{0}", Environment.NewLine); foreach (var cmdletSyntax in cmdletInfo.Syntaxes.OrderBy(s => s.Parameters.Count(p => p.Required))) { var syntaxText = new StringBuilder(); syntaxText.AppendFormat("```powershell\r\n{0} ", cmdletInfo.FullCommand); var cmdletLength = cmdletInfo.FullCommand.Length; var first = true; foreach (var par in cmdletSyntax.Parameters.Distinct(new ParameterComparer()).OrderBy(p => !p.Required).ThenBy(p => p.Position)) { if (first) { first = false; } else { syntaxText.Append(new string(' ', cmdletLength + 1)); } if (!par.Required) { syntaxText.Append("["); } if (par.Type.StartsWith("Int")) { par.Type = "Int"; } if (par.Type == "SwitchParameter") { syntaxText.AppendFormat("-{0} [<{1}>]", par.Name, par.Type); } else { syntaxText.AppendFormat("-{0} <{1}>", par.Name, par.Type); } if (!par.Required) { syntaxText.Append("]"); } syntaxText.Append("\r\n"); } // Add All ParameterSet ones docBuilder.Append(syntaxText); docBuilder.AppendFormat("```\n\n\n"); } } if (!string.IsNullOrEmpty(cmdletInfo.DetailedDescription)) { docBuilder.Append("## Detailed Description\n"); docBuilder.AppendFormat("{0}\n\n", cmdletInfo.DetailedDescription); } if (cmdletInfo.OutputType != null) { docBuilder.Append("## Returns\n"); var outputType = ""; if (cmdletInfo.OutputType != null) { if (cmdletInfo.OutputType.IsGenericType) { if (cmdletInfo.OutputType.GetGenericTypeDefinition() == typeof(List <>) || cmdletInfo.OutputType.GetGenericTypeDefinition() == typeof(IEnumerable <>)) { if (cmdletInfo.OutputType.GenericTypeArguments.Any()) { outputType = $"List<{cmdletInfo.OutputType.GenericTypeArguments[0].FullName}>"; } else { outputType = cmdletInfo.OutputType.FullName; } } else { outputType = cmdletInfo.OutputType.FullName; } } else { outputType = cmdletInfo.OutputType.FullName; } } if (!string.IsNullOrEmpty(cmdletInfo.OutputTypeLink)) { docBuilder.Append($">[{outputType}]({cmdletInfo.OutputTypeLink})"); } else { docBuilder.Append($">{outputType}"); } if (!string.IsNullOrEmpty(cmdletInfo.OutputTypeDescription)) { docBuilder.Append($"\n\n{cmdletInfo.OutputTypeDescription}"); } docBuilder.Append("\n\n"); } if (cmdletInfo.Parameters.Any()) { docBuilder.Append("## Parameters\n"); docBuilder.Append("Parameter|Type|Required|Description\n"); docBuilder.Append("---------|----|--------|-----------\n"); foreach (var par in cmdletInfo.Parameters.OrderBy(x => x.Name).Distinct(new ParameterComparer()).OrderBy(p => !p.Required)) { if (par.Type.StartsWith("Int")) { par.Type = "Int"; } docBuilder.AppendFormat("|{0}|{1}|{2}|{3}|\n", par.Name, par.Type, par.Required ? "True" : "False", par.Description); } } if (cmdletInfo.Examples.Any()) { docBuilder.Append("## Examples\n"); } var examplesCount = 1; foreach (var example in cmdletInfo.Examples.OrderBy(e => e.SortOrder)) { docBuilder.AppendFormat("{0}\n", example.Introduction); docBuilder.AppendFormat("### Example {0}\n", examplesCount); docBuilder.AppendFormat("```powershell\n{0}\n```\n", example.Code); docBuilder.AppendFormat("{0}\n", example.Remarks); examplesCount++; } newMd = docBuilder.ToString(); var dmp = new DiffMatchPatch.diff_match_patch(); var diffResults = dmp.diff_main(newMd, originalMd); foreach (var result in diffResults) { if (result.operation != DiffMatchPatch.Operation.EQUAL) { System.IO.File.WriteAllText(mdFilePath, docBuilder.ToString()); break; } } } } }
public static void LogDifferences(string diffName, List<Comparence> comparence) { var differ = new DiffMatchPatch.diff_match_patch(); differ.Diff_Timeout = 10; var sb = new StringBuilder(diffName); sb.AppendLine(); foreach (var diff in comparence) { if (diff.Result != CompareResult.HasContentDifferences) { continue; } try { var file1Content = FolderComparer.ReadFile(diff.File1FullPath); if (file1Content == null) { sb.AppendLine(string.Format("DIFF Could not get detailed diff for {0}. Content is null.}", diff.File1FullPath)); continue; } var file2Content = FolderComparer.ReadFile(diff.File2FullPath); if (file2Content == null) { sb.AppendLine(string.Format("DIFF Could not get detailed diff for {0}. Content is null.}", diff.File2FullPath)); continue; } var differences = differ.diff_main(file1Content, file2Content); var diffText = differ.DiffText(differences, true); sb.AppendLine(); sb.AppendLine("DIFF for " + diff.ToString()); sb.AppendLine(); sb.AppendLine("|" + diffText + "|"); } catch (Exception ex) { sb.AppendLine(string.Format("DIFF Could not get detailed diff for {0}. Exception: {1}", diff.ToString(), ex.Message)); } } SimpleLogger.Instance.WriteLine(string.Empty); LogWarning(sb.ToString()); }