/// <summary> /// aspx页面中整体样式替换方法--编辑页面 /// </summary> /// <param name="textDocument"></param> /// <param name="patternString"></param> internal void PrcoessAspxPageEdit(TextDocument textDocument) { string pattern = @"(?isx) #匹配模式(i:忽略大小写 s:单行支持跨行 x:忽略表达式中空格) <table.*?<td[^>]*?> (?<title>\s*[\u4e00-\u9fa5]+\s*) #标题匹配 </td\s*>(?:.*?)<table[^>]*?>[^<>]*? (?:<tr[^>]*?>[^<>]*?<td[^>]*?>(?<where>.*?)</td\s*>[^<>]*?</tr>\s*)+ #查询条件匹配 ((?!<table).)*?(?<dataHead><asp:GridView(((?!class|>).)*?))(?<cls>(class|CssClass)\s*=\s*\"".*?\"")?(?<dataFooter>(((?!class|>).)*?)>.*?</asp:GridView>) ((?!<table).)*?<td[^<]*?(?<page><uc1:(?:(?!/>).)*?/>\s*)*</td\s*> #分页匹配 ((?!</table>).)*?</table>"; //替换表达式拼接 string strBody = "<div class=\"card-body\">"; string strGroup = "<div class=\"form-group\">"; StringBuilder replaceMentBody = new StringBuilder(); replaceMentBody.AppendLine(@"<div class=""container-fluid row""> <div class=""col-lg-12""> <div class=""card"">"); replaceMentBody.AppendLine(strBody); replaceMentBody.AppendLine("<div class=\"right-title\">${title}</div>"); replaceMentBody.AppendLine(strGroup); replaceMentBody.AppendLine("${where}"); replaceMentBody.AppendLine("</div>"); replaceMentBody.AppendLine("</div>"); replaceMentBody.AppendLine(strBody); replaceMentBody.AppendLine("${dataHead} class=\"table table-bordered table-hover table-striped\"${dataFooter}"); replaceMentBody.AppendLine("${page}"); replaceMentBody.AppendLine("</div>"); replaceMentBody.AppendLine(@"</div> </div> </div>"); TextDocumentHelper.SubstituteAllStringMatches(textDocument, pattern, replaceMentBody.ToString()); }
/// <summary> /// Removes blank spaces before a closing angle bracket. /// </summary> /// <param name="textDocument">The text document to cleanup.</param> internal void RemoveBlankSpacesBeforeClosingAngleBracket(TextDocument textDocument) { if (!Settings.Default.Cleaning_RemoveBlankSpacesBeforeClosingAngleBrackets) { return; } // Remove blank spaces before regular closing angle brackets. string pattern = _package.UsePOSIXRegEx ? @"\n*:b+\>\n" : @"(\r?\n)*[ \t]+>\r?\n"; string replacement = @">" + Environment.NewLine; TextDocumentHelper.SubstituteAllStringMatches(textDocument, pattern, replacement); // Handle blank spaces before self closing angle brackets based on insert blank space setting. if (Settings.Default.Cleaning_InsertBlankSpaceBeforeSelfClosingAngleBrackets) { string oneSpacePattern = _package.UsePOSIXRegEx ? @"\n*:b:b+/\>\n" : @"(\r?\n)*[ \t]{2,}/>\r?\n"; string oneSpaceReplacement = @" />" + Environment.NewLine; TextDocumentHelper.SubstituteAllStringMatches(textDocument, oneSpacePattern, oneSpaceReplacement); } else { string noSpacePattern = _package.UsePOSIXRegEx ? @"\n*:b+/\>\n" : @"(\r?\n)*[ \t]+/>\r?\n"; string noSpaceReplacement = @"/>" + Environment.NewLine; TextDocumentHelper.SubstituteAllStringMatches(textDocument, noSpacePattern, noSpaceReplacement); } }
/// <summary> /// Joins the specified multi-line method onto a single line. /// </summary> /// <param name="method">The method to update.</param> private void JoinMultiLineMethodOntoSingleLine(CodeFunction method) { var start = method.StartPoint.CreateEditPoint(); var end = method.EndPoint.CreateEditPoint(); const string pattern = @"[ \t]*\r?\n[ \t]*"; const string replacement = @" "; // Substitute all new lines (and optional surrounding whitespace) with a single space. TextDocumentHelper.SubstituteAllStringMatches(start, end, pattern, replacement); }
/// <summary> /// Removes multiple consecutive blank lines from the specified text document. /// </summary> /// <param name="textDocument">The text document to cleanup.</param> internal void RemoveMultipleConsecutiveBlankLines(TextDocument textDocument) { if (!Settings.Default.Cleaning_RemoveMultipleConsecutiveBlankLines) { return; } const string pattern = @"(?<!@""(""""|[^""])*)(\r?\n){3,}"; string replacement = Environment.NewLine + Environment.NewLine; TextDocumentHelper.SubstituteAllStringMatches(textDocument, pattern, replacement); }
/// <summary> /// Removes blank lines between chained statements. /// </summary> /// <param name="textDocument">The text document to cleanup.</param> internal void RemoveBlankLinesBetweenChainedStatements(TextDocument textDocument) { if (!Settings.Default.Cleaning_RemoveBlankLinesBetweenChainedStatements) { return; } const string pattern = @"(\r?\n){2,}([ \t]*)(else|catch|finally)( |\t|\r?\n)"; string replacement = Environment.NewLine + @"$2$3$4"; TextDocumentHelper.SubstituteAllStringMatches(textDocument, pattern, replacement); }
/// <summary> /// Removes blank lines before a closing tag. /// </summary> /// <param name="textDocument">The text document to cleanup.</param> internal void RemoveBlankLinesBeforeClosingTag(TextDocument textDocument) { if (!Settings.Default.Cleaning_RemoveBlankLinesBeforeClosingTags) { return; } const string pattern = @"(\r?\n){2,}([ \t]*)</"; string replacement = Environment.NewLine + @"$2</"; TextDocumentHelper.SubstituteAllStringMatches(textDocument, pattern, replacement); }
/// <summary> /// Removes blank lines after an opening brace. /// </summary> /// <param name="textDocument">The text document to cleanup.</param> internal void RemoveBlankLinesAfterOpeningBrace(TextDocument textDocument) { if (!Settings.Default.Cleaning_RemoveBlankLinesAfterOpeningBrace) { return; } const string pattern = @"\{([ \t]*(//[^\r\n]*)*)(\r?\n){2,}"; string replacement = @"{$1" + Environment.NewLine; TextDocumentHelper.SubstituteAllStringMatches(textDocument, pattern, replacement); }
/// <summary> /// Inserts a blank line before single line comments except where adjacent to a brace, /// another single line comment line or a quadruple slash comment. /// </summary> /// <param name="textDocument">The text document.</param> internal void InsertPaddingBeforeSingleLineComments(TextDocument textDocument) { if (!Settings.Default.Cleaning_InsertBlankLinePaddingBeforeSingleLineComments) { return; } const string pattern = @"(^[ \t]*(?!//)[^ \t\r\n\{].*\r?\n)([ \t]*//)(?!//)"; string replacement = @"$1" + Environment.NewLine + @"$2"; TextDocumentHelper.SubstituteAllStringMatches(textDocument, pattern, replacement); }
/// <summary> /// Inserts a blank line before case statements except for single-line case statements. /// </summary> /// <param name="textDocument">The text document.</param> internal void InsertPaddingBeforeCaseStatements(TextDocument textDocument) { if (!Settings.Default.Cleaning_InsertBlankLinePaddingBeforeCaseStatements) { return; } const string pattern = @"(^[ \t]*)(break;|return([ \t][^;]*)?;)\r?\n([ \t]*)(case|default)"; string replacement = @"$1$2" + Environment.NewLine + Environment.NewLine + @"$4$5"; TextDocumentHelper.SubstituteAllStringMatches(textDocument, pattern, replacement); }
/// <summary> /// Inserts a single blank space before a self-closing angle bracket. /// </summary> /// <param name="textDocument">The text document to cleanup.</param> internal void InsertBlankSpaceBeforeSelfClosingAngleBracket(TextDocument textDocument) { if (!Settings.Default.Cleaning_InsertBlankSpaceBeforeSelfClosingAngleBrackets) { return; } const string pattern = @"([^ \t])/>"; const string replacement = @"$1 />"; TextDocumentHelper.SubstituteAllStringMatches(textDocument, pattern, replacement); }
/// <summary> /// Removes blank lines after attributes. /// </summary> /// <param name="textDocument">The text document to cleanup.</param> internal void RemoveBlankLinesAfterAttributes(TextDocument textDocument) { if (!Settings.Default.Cleaning_RemoveBlankLinesAfterAttributes) { return; } const string pattern = @"(^[ \t]*\[[^\]]+\][ \t]*(//[^\r\n]*)*)(\r?\n){2}(?![ \t]*//)"; string replacement = @"$1" + Environment.NewLine; TextDocumentHelper.SubstituteAllStringMatches(textDocument, pattern, replacement); }
/// <summary> /// Removes all blank lines from the specified text document. /// </summary> /// <param name="textDocument">The text document to cleanup.</param> internal void RemoveAllBlankLines(TextDocument textDocument) { if (!Settings.Default.Cleaning_RemoveAllBlankLines) { return; } string pattern = @"(?m)^[ \t]*[\r?\n]+"; string replacement = String.Empty; TextDocumentHelper.SubstituteAllStringMatches(textDocument, pattern, replacement); }
/// <summary> /// Removes all end of line whitespace from the specified text document. /// </summary> /// <param name="textDocument">The text document to cleanup.</param> internal void RemoveEOLWhitespace(TextDocument textDocument) { if (!Settings.Default.Cleaning_RemoveEndOfLineWhitespace) { return; } string pattern = _package.UsePOSIXRegEx ? @":b+\n" : @"[ \t]+\r?\n"; string replacement = Environment.NewLine; TextDocumentHelper.SubstituteAllStringMatches(textDocument, pattern, replacement); }
/// <summary> /// Removes multiple consecutive blank lines from the specified text document. /// </summary> /// <param name="textDocument">The text document to cleanup.</param> internal void RemoveMultipleConsecutiveBlankLines(TextDocument textDocument) { if (!Settings.Default.Cleaning_RemoveMultipleConsecutiveBlankLines) { return; } string pattern = _package.UsePOSIXRegEx ? @"\n\n\n+" : @"(\r?\n){3,}"; string replacement = Environment.NewLine + Environment.NewLine; TextDocumentHelper.SubstituteAllStringMatches(textDocument, pattern, replacement); }
/// <summary> /// aspx页面中整体样式替换方法-列表页面 /// </summary> /// <param name="textDocument"></param> /// <param name="patternString"></param> internal void PrcoessAspxPageList(TextDocument textDocument) { //string pattern = "(?isx)<table.*?<td[^>]*?>(?<title>[\u4e00-\u9fa5]+)(?:.*?)<table[^>]*?>[^<>]*?(?:<tr[^>]*?>[^<>]*?<td[^>]*?>(?<row>.*?)</td>[^<>]*?</tr>\\s*)+((?!<table).)*?(?<dataHead><asp:GridView(((?!class|>).)*?))(?<cls>(class|CssClass)\\s*=\\s*\".*?\")?(?<dataFooter>(((?!class|>).)*?)>.*?</asp:GridView>)((?!</table>).)*?</table>"; string pattern = @"(?isx) #匹配模式(i:忽略大小写 s:单行支持跨行 x:忽略表达式中空格) <table.*?<td[^>]*?> (?<title>\s*[\u4e00-\u9fa5]+\s*) #标题匹配 </td\s*>(?:.*?)<table[^>]*?>[^<>]*? (?:<tr[^>]*?>[^<>]*?<td[^>]*?>(?<where>.*?)(?<btns><asp:Button(?:(?(?!</td>).)*)/>)\s*</td\s*>[^<>]*?</tr>\s*)+ #查询条件匹配 ((?!<table).)*?(?<dataHead><asp:GridView(((?!class|>).)*?))(?<cls>(class|CssClass)\s*=\s*\"".*?\"")?(?<dataFooter>(((?!class|>).)*?)>.*?</asp:GridView>) ((?!<table).)*?<td.*?(?<page>(?(<%--)<%--|)<uc1:(?:(?!/>).)*?/>(?(--%>)--%>|)\s*).*</td\s*> #分页匹配 ((?!</table>).)*?</table>"; //替换表达式拼接 string strBody = "<div class=\"card-body\">"; string strGroup = "<div class=\"form-group\">"; StringBuilder replaceMentBody = new StringBuilder(); replaceMentBody.AppendLine(@"<div class=""container-fluid row""> <div class=""col-lg-12""> <div class=""card"">"); replaceMentBody.AppendLine(strBody); replaceMentBody.AppendLine("<div class=\"right-title\">${title}</div>"); replaceMentBody.AppendLine("${where}"); replaceMentBody.AppendLine(strGroup); //添加查询条件按钮的样式开始标签 replaceMentBody.AppendLine("${btns}"); replaceMentBody.AppendLine("</div>"); //添加查询条件按钮的样式结束标签 replaceMentBody.AppendLine("</div>"); replaceMentBody.AppendLine(strBody); replaceMentBody.AppendLine("${dataHead} class=\"table table-bordered table-hover table-striped\"${dataFooter}"); replaceMentBody.AppendLine("${page}"); replaceMentBody.AppendLine("</div>"); replaceMentBody.AppendLine(@"</div> </div> </div>"); TextDocumentHelper.SubstituteAllStringMatches(textDocument, pattern, replaceMentBody.ToString()); //页面的查询条件控件样式替换表达式 pattern = @"(?isx) #匹配模式(i:忽略大小写 s:单行支持跨行 x:忽略表达式中空格) (?<title>[\u4e00-\u9fa5]+[::])[\s ]*(?<body><asp:(?<tag>[^>]*?)\b[^>]*?>(?:(?![\u4e00-\u9fa5]+[::]).)*</asp:\k<tag>>)\s*(?: )*"; //替换表达式拼接 replaceMentBody = new StringBuilder(); replaceMentBody.AppendLine("<div class=\"form-group\">"); replaceMentBody.AppendLine("<label class=\"lf formlabel\">${title}</label>"); replaceMentBody.AppendLine("<div class=\"col-xs-1\">"); replaceMentBody.AppendLine("${body}");//页面的查询条件样式通过其他替换表达式来完成效果 replaceMentBody.AppendLine("</div>"); replaceMentBody.AppendLine("</div>"); TextDocumentHelper.SubstituteAllStringMatches(textDocument, pattern, replaceMentBody.ToString()); }
/// <summary> /// Removes blank lines after attributes. /// </summary> /// <param name="textDocument">The text document to cleanup.</param> internal void RemoveBlankLinesAfterAttributes(TextDocument textDocument) { if (!Settings.Default.Cleaning_RemoveBlankLinesAfterAttributes) { return; } string pattern = _package.UsePOSIXRegEx ? @"\]{:b*(//.*)*}\n\n~(:b*//)" : @"\]([ \t]*(//[^\r\n]*)*)(\r?\n){2}(?![ \t]*//)"; string replacement = _package.UsePOSIXRegEx ? @"\]\1" + Environment.NewLine : @"]$1" + Environment.NewLine; TextDocumentHelper.SubstituteAllStringMatches(textDocument, pattern, replacement); }
/// <summary> /// Removes blank lines between chained statements. /// </summary> /// <param name="textDocument">The text document to cleanup.</param> internal void RemoveBlankLinesBetweenChainedStatements(TextDocument textDocument) { if (!Settings.Default.Cleaning_RemoveBlankLinesBetweenChainedStatements) { return; } string pattern = _package.UsePOSIXRegEx ? @"\n\n{:b*}{else|catch|finally}{:b|\n}" : @"(\r?\n){2,}([ \t]*)(else|catch|finally)( |\t|\r?\n)"; string replacement = _package.UsePOSIXRegEx ? Environment.NewLine + @"\1\2\3" : Environment.NewLine + @"$2$3$4"; TextDocumentHelper.SubstituteAllStringMatches(textDocument, pattern, replacement); }
/// <summary> /// Removes blank lines before a closing tag. /// </summary> /// <param name="textDocument">The text document to cleanup.</param> internal void RemoveBlankLinesBeforeClosingTag(TextDocument textDocument) { if (!Settings.Default.Cleaning_RemoveBlankLinesBeforeClosingTags) { return; } string pattern = _package.UsePOSIXRegEx ? @"\n\n{:b*}\</" : @"(\r?\n){2,}([ \t]*)</"; string replacement = _package.UsePOSIXRegEx ? Environment.NewLine + @"\1</" : Environment.NewLine + @"$2</"; TextDocumentHelper.SubstituteAllStringMatches(textDocument, pattern, replacement); }
/// <summary> /// Removes blank lines after an opening brace. /// </summary> /// <param name="textDocument">The text document to cleanup.</param> internal void RemoveBlankLinesAfterOpeningBrace(TextDocument textDocument) { if (!Settings.Default.Cleaning_RemoveBlankLinesAfterOpeningBrace) { return; } string pattern = _package.UsePOSIXRegEx ? @"\{{:b*(//.*)*}\n\n" : @"\{([ \t]*(//[^\r\n]*)*)(\r?\n){2,}"; string replacement = _package.UsePOSIXRegEx ? @"\{\1" + Environment.NewLine : @"{$1" + Environment.NewLine; TextDocumentHelper.SubstituteAllStringMatches(textDocument, pattern, replacement); }
/// <summary> /// Inserts a blank line before single line comments except where adjacent to a brace, /// another single line comment line or a quadruple slash comment. /// </summary> /// <param name="textDocument">The text document.</param> internal void InsertPaddingBeforeSingleLineComments(TextDocument textDocument) { if (!Settings.Default.Cleaning_InsertBlankLinePaddingBeforeSingleLineComments) { return; } string pattern = _package.UsePOSIXRegEx ? @"{^:b*~(//)[^:b\r\n\{].*\n}{:b*//}~(//)" : @"(^[ \t]*(?!//)[^ \t\r\n\{].*\r?\n)([ \t]*//)(?!//)"; string replacement = _package.UsePOSIXRegEx ? @"\1" + Environment.NewLine + @"\2" : @"$1" + Environment.NewLine + @"$2"; TextDocumentHelper.SubstituteAllStringMatches(textDocument, pattern, replacement); }
/// <summary> /// Inserts a single blank space before a self-closing angle bracket. /// </summary> /// <param name="textDocument">The text document to cleanup.</param> internal void InsertBlankSpaceBeforeSelfClosingAngleBracket(TextDocument textDocument) { if (!Settings.Default.Cleaning_InsertBlankSpaceBeforeSelfClosingAngleBrackets) { return; } string pattern = _package.UsePOSIXRegEx ? @"{[^:b]}/\>" : @"([^ \t])/>"; string replacement = _package.UsePOSIXRegEx ? @"\1 />" : @"$1 />"; TextDocumentHelper.SubstituteAllStringMatches(textDocument, pattern, replacement); }
/// <summary> /// Inserts a blank line before case statements except for single-line case statements. /// </summary> /// <param name="textDocument">The text document.</param> internal void InsertPaddingBeforeCaseStatements(TextDocument textDocument) { if (!Settings.Default.Cleaning_InsertBlankLinePaddingBeforeCaseStatements) { return; } string pattern = _package.UsePOSIXRegEx ? @"{^:b*}{break;|return;}\n{:b*}{case|default}" : @"(^[ \t]*)(break;|return([ \t][^;]*)?;)\r?\n([ \t]*)(case|default)"; string replacement = _package.UsePOSIXRegEx ? @"\1\2" + Environment.NewLine + Environment.NewLine + @"\3\4" : @"$1$2" + Environment.NewLine + Environment.NewLine + @"$4$5"; TextDocumentHelper.SubstituteAllStringMatches(textDocument, pattern, replacement); }
/// <summary> /// Joins the text within the specified text selection. /// </summary> /// <param name="textSelection">The text selection.</param> private void JoinText(TextSelection textSelection) { // If the selection has no length, try to pick up the next line. if (textSelection.IsEmpty) { textSelection.LineDown(true); textSelection.EndOfLine(true); } const string pattern = @"[ \t]*\r?\n[ \t]*"; const string replacement = @" "; // Substitute all new lines (and optional surrounding whitespace) with a single space. TextDocumentHelper.SubstituteAllStringMatches(textSelection, pattern, replacement); // Move the cursor forward, clearing the selection. textSelection.CharRight(); }
/// <summary> /// html文件内的标签格式化逻辑 /// </summary> /// <param name="textDocument"></param> internal void HtmlTagFormat(TextDocument textDocument) { //读取配置文件 if (!Settings.Default.Formatting_AspxHtml) { return; } //判断是否是aspx页面全部都替换 if (Settings.Default.Cleaning_FormattingAspxCleanupAsk == 0) { //替换aspx中table标签,增加div标签和属性等; PrcoessAspxPageList(textDocument); //PrcoessAspxPageEdit(textDocument); } //正则表达式 替换aspx中的带有class的Button string pattern = @"(?is)<asp:Button(((?!class|<asp).)*?)(\b(class|CssClass)\s*=\s*\""(?(txthidden|btn)(?!)|(((?!class|<asp).)*?))\"")?(?<center>((?!class|<asp).)*?)(?<wid>(?:width\s*=\s*\""\d{2,3}px\""\s*height\s*=\s*\""\d{2,3}px\""\s?)|(?:width\s*=\s*\""\d{2,3}px\""\s*))?(?<footer>((?!class|<asp|width).)*?)/>"; string replaceMent = "<asp:Button $1class=\"btn btn-info m-r-5\"${center}${footer}/>"; TextDocumentHelper.SubstituteAllStringMatches(textDocument, pattern, replaceMent); //替换aspx中的带有CssClass的TextBox DropDownList22 pattern = @"(?is)(<asp:(TextBox|DropDownList)((?!class|</).)*?)(\b(class|CssClass)\s*=\s*\""(?(txthidden)(?!)|(((?!class|/>).)*?))\"")?(?<footer>((?!class).)*?(</asp:\2>|/>))"; replaceMent = "$1 CssClass=\"form-controlnew\"${footer}"; TextDocumentHelper.SubstituteAllStringMatches(textDocument, pattern, replaceMent); //只有不是全部时才会按照控件gridview来替换,全部按照页面格式来替换 if (Settings.Default.Cleaning_FormattingAspxCleanupAsk == 1) { //替换aspx页面中gridview中class样式 pattern = @"(?is)(?<dataHead><asp:GridView(((?!class|>).)*?))(?<cls>(class|CssClass)\s*=\s*\"".*?\"")?(?<dataFooter>(((?!class|>).)*?)>.*?</asp:GridView>)"; replaceMent = "${dataHead} class=\"table table-bordered table-hover table-striped\"${dataFooter}"; TextDocumentHelper.SubstituteAllStringMatches(textDocument, pattern, replaceMent); } }