|
| 1 | +import 'package:gsy_github_app_flutter/common/style/GSYStyle.dart'; |
| 2 | + |
| 3 | +/** |
| 4 | + * Created by guoshuyu |
| 5 | + * on 2018/7/27. |
| 6 | + */ |
| 7 | + |
| 8 | +class HtmlUtils { |
| 9 | + static generateCode2HTml(String mdData, {String backgroundColor = GSYColors.miWhiteString, String lang = 'java', userBR = true}) { |
| 10 | + String currentData = (mdData != null && mdData.indexOf("<code>") == -1) |
| 11 | + ? "<body>\n" + "<pre class=\"pre\">\n" + "<code lang='$lang'>\n" + mdData + "</code>\n" + "</pre>\n" + "</body>\n" |
| 12 | + : "<body>\n" + "<pre class=\"pre\">\n" + mdData + "</pre>\n" + "</body>\n"; |
| 13 | + return generateHtml(currentData, backgroundColor: backgroundColor, userBR: userBR); |
| 14 | + } |
| 15 | + |
| 16 | + static generateHtml(String mdData, {String backgroundColor = GSYColors.webDraculaBackgroundColorString, userBR = true}) { |
| 17 | + if (mdData == null) { |
| 18 | + return ""; |
| 19 | + } |
| 20 | + RegExp exp = new RegExp("<code(([\s\S])*?)<\/code>"); |
| 21 | + Iterable<Match> tags = exp.allMatches(mdData); |
| 22 | + String mdDataCode = mdData; |
| 23 | + for (Match m in tags) { |
| 24 | + String match = m.group(0).replaceAll(new RegExp("\n"), "\n\r<br>"); |
| 25 | + mdDataCode = mdDataCode.replaceAll(m.group(0), match); |
| 26 | + } |
| 27 | + |
| 28 | + exp = new RegExp("<pre(([\s\S])*?)<\/pre>"); |
| 29 | + tags = exp.allMatches(mdDataCode); |
| 30 | + for (Match m in tags) { |
| 31 | + if (m.group(0).indexOf("<code>") < 0) { |
| 32 | + String match = m.group(0).replaceAll(new RegExp("\n"), "\n\r<br>"); |
| 33 | + mdDataCode = mdDataCode.replaceAll(m.group(0), match); |
| 34 | + } |
| 35 | + } |
| 36 | + |
| 37 | + exp = new RegExp("<pre>(([\s\S])*?)<\/pre>"); |
| 38 | + tags = exp.allMatches(mdDataCode); |
| 39 | + for (Match m in tags) { |
| 40 | + if (m.group(0).indexOf("<code>") < 0) { |
| 41 | + String match = m.group(0).replaceAll(new RegExp("\n"), "\n\r<br>"); |
| 42 | + mdDataCode = mdDataCode.replaceAll(m.group(0), match); |
| 43 | + } |
| 44 | + } |
| 45 | + |
| 46 | + exp = new RegExp("href=\"(.*?)\""); |
| 47 | + tags = exp.allMatches(mdDataCode); |
| 48 | + for (Match m in tags) { |
| 49 | + String capture = m.group(0); |
| 50 | + if (capture.indexOf("http://") < 0 && capture.indexOf("https://") < 0 && capture.indexOf("#") != 0) { |
| 51 | + mdDataCode = mdDataCode.replaceAll(m.group(0), "gsygithub://" + capture); |
| 52 | + } |
| 53 | + } |
| 54 | + |
| 55 | + return generateCodeHtml(mdDataCode, false, backgroundColor: backgroundColor, actionColor: GSYColors.actionBlueString, userBR: userBR); |
| 56 | + } |
| 57 | + |
| 58 | + /** |
| 59 | + * style for mdHTml |
| 60 | + */ |
| 61 | + static generateCodeHtml(mdHTML, wrap, {backgroundColor = GSYColors.white, String actionColor = GSYColors.actionBlueString, userBR = true}) { |
| 62 | + return "<html>\n" + |
| 63 | + "<head>\n" + |
| 64 | + "<meta charset=\"utf-8\" />\n" + |
| 65 | + "<title></title>\n" + |
| 66 | + "<meta name=\"viewport\" content=\"width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;\"/>" + |
| 67 | + "<link href=\"https:\/\/cdn.bootcss.com/highlight.js/9.12.0/styles/dracula.min.css\" rel=\"stylesheet\">\n" + |
| 68 | + "<script src=\"https:\/\/cdn.bootcss.com/highlight.js/9.12.0/highlight.min.js\"></script> " + |
| 69 | + "<script>hljs.configure({'useBR': " + |
| 70 | + userBR.toString() + |
| 71 | + "});hljs.initHighlightingOnLoad();</script> " + |
| 72 | + "<style>" + |
| 73 | + "body{background: " + |
| 74 | + backgroundColor + |
| 75 | + ";}" + |
| 76 | + "a {color:" + |
| 77 | + actionColor + |
| 78 | + " !important;}" + |
| 79 | + ".highlight pre, pre {" + |
| 80 | + " word-wrap: " + |
| 81 | + (wrap ? "break-word" : "normal") + |
| 82 | + "; " + |
| 83 | + " white-space: " + |
| 84 | + (wrap ? "pre-wrap" : "pre") + |
| 85 | + "; " + |
| 86 | + "}" + |
| 87 | + "thead, tr {" + |
| 88 | + "background:" + |
| 89 | + GSYColors.miWhiteString + |
| 90 | + ";}" + |
| 91 | + "td, th {" + |
| 92 | + "padding: 5px 10px;" + |
| 93 | + "font-size: 12px;" + |
| 94 | + "direction:hor" + |
| 95 | + "}" + |
| 96 | + ".highlight {overflow: scroll; background: " + |
| 97 | + GSYColors.miWhiteString + |
| 98 | + "}" + |
| 99 | + "tr:nth-child(even) {" + |
| 100 | + "background:" + |
| 101 | + GSYColors.primaryLightValueString + |
| 102 | + ";" + |
| 103 | + "color:" + |
| 104 | + GSYColors.miWhiteString + |
| 105 | + ";" + |
| 106 | + "}" + |
| 107 | + "tr:nth-child(odd) {" + |
| 108 | + "background: " + |
| 109 | + GSYColors.miWhiteString + |
| 110 | + ";" + |
| 111 | + "color:" + |
| 112 | + GSYColors.primaryLightValueString + |
| 113 | + ";" + |
| 114 | + "}" + |
| 115 | + "th {" + |
| 116 | + "font-size: 14px;" + |
| 117 | + "color:" + |
| 118 | + GSYColors.miWhiteString + |
| 119 | + ";" + |
| 120 | + "background:" + |
| 121 | + GSYColors.primaryLightValueString + |
| 122 | + ";" + |
| 123 | + "}" + |
| 124 | + "</style>" + |
| 125 | + "</head>\n" + |
| 126 | + "<body>\n" + |
| 127 | + mdHTML + |
| 128 | + "</body>\n" + |
| 129 | + "</html>"; |
| 130 | + } |
| 131 | + |
| 132 | + static parseDiffSource(String diffSource, bool wrap) { |
| 133 | + if (diffSource == null) { |
| 134 | + return ""; |
| 135 | + } |
| 136 | + List<String> lines = diffSource.split("\n"); |
| 137 | + String source = ""; |
| 138 | + int addStartLine = -1; |
| 139 | + int removeStartLine = -1; |
| 140 | + int addLineNum = 0; |
| 141 | + int removeLineNum = 0; |
| 142 | + int normalLineNum = 0; |
| 143 | + for (int i = 0; i < lines.length; i++) { |
| 144 | + String line = lines[i]; |
| 145 | + String lineNumberStr = ""; |
| 146 | + String classStr = ""; |
| 147 | + int curAddNumber = -1; |
| 148 | + int curRemoveNumber = -1; |
| 149 | + |
| 150 | + if (line.indexOf("+") == 0) { |
| 151 | + classStr = "class=\"hljs-addition\";"; |
| 152 | + curAddNumber = addStartLine + normalLineNum + addLineNum; |
| 153 | + addLineNum++; |
| 154 | + } else if (line.indexOf("-") == 0) { |
| 155 | + classStr = "class=\"hljs-deletion\";"; |
| 156 | + curRemoveNumber = removeStartLine + normalLineNum + removeLineNum; |
| 157 | + removeLineNum++; |
| 158 | + } else if (line.indexOf("@@") == 0) { |
| 159 | + classStr = "class=\"hljs-literal\";"; |
| 160 | + removeStartLine = getRemoveStartLine(line); |
| 161 | + addStartLine = getAddStartLine(line); |
| 162 | + addLineNum = 0; |
| 163 | + removeLineNum = 0; |
| 164 | + normalLineNum = 0; |
| 165 | + } else if (!(line.indexOf("\\") == 0)) { |
| 166 | + curAddNumber = addStartLine + normalLineNum + addLineNum; |
| 167 | + curRemoveNumber = removeStartLine + normalLineNum + removeLineNum; |
| 168 | + normalLineNum++; |
| 169 | + } |
| 170 | + lineNumberStr = |
| 171 | + getDiffLineNumber(curRemoveNumber == -1 ? "" : (curRemoveNumber.toString() + ""), curAddNumber == -1 ? "" : (curAddNumber.toString() + "")); |
| 172 | + source = source + "\n" + "<div " + classStr + ">" + (wrap ? "" : lineNumberStr + getBlank(1)) + line + "</div>"; |
| 173 | + } |
| 174 | + return source; |
| 175 | + } |
| 176 | + |
| 177 | + static getRemoveStartLine(line) { |
| 178 | + try { |
| 179 | + return int.parse(line.substring(line.indexOf("-") + 1, line.indexOf(","))); |
| 180 | + } catch (e) { |
| 181 | + return 1; |
| 182 | + } |
| 183 | + } |
| 184 | + |
| 185 | + static getAddStartLine(line) { |
| 186 | + try { |
| 187 | + return int.parse(line.substring(line.indexOf("+") + 1, line.indexOf(",", line.indexOf("+")))); |
| 188 | + } catch (e) { |
| 189 | + return 1; |
| 190 | + } |
| 191 | + } |
| 192 | + |
| 193 | + static getDiffLineNumber(String removeNumber, String addNumber) { |
| 194 | + int minLength = 4; |
| 195 | + return getBlank(minLength - removeNumber.length) + removeNumber + getBlank(1) + getBlank(minLength - addNumber.length) + addNumber; |
| 196 | + } |
| 197 | + |
| 198 | + static getBlank(num) { |
| 199 | + String builder = ""; |
| 200 | + for (int i = 0; i < num; i++) { |
| 201 | + builder += " "; |
| 202 | + } |
| 203 | + return builder; |
| 204 | + } |
| 205 | +} |
0 commit comments