1#!/usr/bin/gawk -f 2 3# Not all 4.x versions of gawk can handle @include without ".awk" extension 4# But the build.awk script and the single build should support gawk 4.0+. 5@include "include/Commons.awk" 6@include "include/Utils.awk" 7@include "include/Languages.awk" 8@include "metainfo.awk" 9 10function init() { 11 BuildPath = "build/" 12 Trans = BuildPath Command 13 TransAwk = Trans ".awk" 14 15 ManPath = "man/" 16 Man = ManPath Command ".1" 17 ManTemplate = Man ".template.md" 18 ManMarkdown = Man ".md" 19 ManHtmlTemplate = Man ".template.html" 20 ManHtml = Man ".html" 21 22 PagesPath = "gh-pages/" 23 BadgeDownload = PagesPath "images/badge-download" 24 BadgeRelease = PagesPath "images/badge-release" 25 Index = PagesPath "index.md" 26 27 ReadmePath = "./" 28 ReadmeTemplate = ReadmePath "README.template.md" 29 Readme = ReadmePath "README.md" 30 31 WikiPath = "wiki/" 32 WikiHome = WikiPath "Home.md" 33 WikiLanguages = WikiPath "Languages.md" 34 WikiLanguagesHtml = WikiLanguages ".html" 35 36 RegistryPath = "registry/" 37 MainRegistryTemplate = RegistryPath "index.template.trans" 38 MainRegistry = RegistryPath "index.trans" 39} 40 41function man( text) { 42 text = readFrom(ManTemplate) 43 gsub(/\$Version\$/, Version, text) 44 gsub(/\$ReleaseDate\$/, ReleaseDate, text) 45 writeTo(text, ManMarkdown) 46 47 if (fileExists(ManHtmlTemplate)) 48 system("pandoc -s -f markdown-smart -t html --toc --toc-depth 1 --template " ManHtmlTemplate " " ManMarkdown " -o " ManHtml) 49 return system("pandoc -s -f markdown-smart -t man " ManMarkdown " -o " Man) 50} 51 52function readme( code, col, cols, content, group, i, j, num, language, r, rows, text) { 53 text = readFrom(ReadmeTemplate) 54 55 content = getOutput("gawk -f translate.awk -- -no-ansi -h") 56 gsub(/\$usage\$/, content, text) 57 58 initBiDi(); initLocale() 59 # number of language codes with stable support 60 num = 0 61 for (code in Locale) 62 if (Locale[code]["support"] != "unstable") 63 num++ 64 rows = int(num / 3) + (num % 3 ? 1 : 0) 65 cols[0][0] = cols[1][0] = cols[2][0] = NULLSTR 66 i = 0 67 saveSortedIn = PROCINFO["sorted_in"] 68 PROCINFO["sorted_in"] = "compName" 69 for (code in Locale) { 70 # Ignore unstable languages 71 if (Locale[code]["support"] == "unstable") continue 72 73 col = int(i / rows) 74 append(cols[col], code) 75 i++ 76 } 77 PROCINFO["sorted_in"] = saveSortedIn 78 r = "| Language | Code | Language | Code | Language | Code |" RS \ 79 "| :------: | :--: | :------: | :--: | :------: | :--: |" RS 80 for (i = 0; i < rows; i++) { 81 r = r "| " 82 for (j = 0; j < 3; j++) 83 if (cols[j][i]) { 84 split(getName(cols[j][i]), group, " ") 85 language = length(group) == 1 ? group[1] "_language" : join(group, "_") 86 r = r "**[" getName(cols[j][i]) "](" "http://en.wikipedia.org/wiki/" language ")** <br/> **" getEndonym(cols[j][i]) "** | **`" cols[j][i] "`** | " 87 } 88 r = r RS 89 } 90 gsub(/\$code-list\$/, r, text) 91 92 content = readFrom(WikiHome) 93 gsub(/\$wiki-home\$/, content, text) 94 95 writeTo(text, Readme) 96 return 0 97} 98 99function wiki( code, group, iso, language, saveSortedIn) { 100 initBiDi(); initLocale() 101 102 #print "***" length(Locale) "*** *languages in total. " 103 print "*Generated from the source code of Translate Shell " Version ".*\n" > WikiLanguages 104 print "*Version: [English](https://github.com/soimort/translate-shell/wiki/Languages) " \ 105 "| [Chinese Simplified](https://github.com/soimort/translate-shell/wiki/Languages-%28%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87%29)*\n" > WikiLanguages 106 print "| Code | Name | Family | [Writing system](https://github.com/soimort/translate-shell/wiki/Writing-Systems-and-Fonts) | Is [RTL](http://en.wikipedia.org/wiki/Right-to-left)? | Has dictionary? |" > WikiLanguages 107 print "| :--: | ---: | -----: | :------------: | :---------------------------------------------------: | :-------------: |" > WikiLanguages 108 saveSortedIn = PROCINFO["sorted_in"] 109 PROCINFO["sorted_in"] = "@ind_num_asc" 110 for (code in Locale) { 111 # Ignore unstable languages 112 if (Locale[code]["support"] == "unstable") continue 113 114 split(getISO(code), group, "-") 115 iso = group[1] 116 split(getName(code), group, " ") 117 language = length(group) == 1 ? group[1] "_language" : 118 group[2] ~ /^\(.*\)$/ ? group[1] "_language" : join(group, "_") 119 print sprintf("| **`%s`** <br/> [`%s`](%s) | **[%s](%s)** <br/> **%s** | %s | `%s` | %s | %s |", 120 getCode(code), iso, "http://www.ethnologue.com/language/" iso, 121 getName(code), "http://en.wikipedia.org/wiki/" language, getEndonym(code), 122 getFamily(code), getScript(code), 123 isRTL(code) ? "✓" : NULLSTR, 124 hasDictionary(code) ? "✓" : NULLSTR) > WikiLanguages 125 } 126 PROCINFO["sorted_in"] = saveSortedIn 127 128 return system("pandoc -s -t html " WikiLanguages " -o " WikiLanguagesHtml) 129} 130 131function doc() { 132 man() 133 readme() 134 wiki() 135 return 0 136} 137 138function readSqueezed(fileName, squeezed, group, line, ret) { 139 if (fileName ~ /\*$/) # glob simulation 140 return readSqueezed(fileName ".awk", squeezed) 141 142 ret = NULLSTR 143 if (fileExists(fileName)) 144 while (getline line < fileName) { 145 match(line, /^[[:space:]]*@include[[:space:]]*"(.*)"$/, group) 146 if (RSTART) { # @include 147 if (group[1] ~ /\.awk$/) 148 append(Includes, group[1]) 149 150 if (ret) ret = ret RS 151 ret = ret readSqueezed(group[1], squeezed) 152 } else if (!squeezed || line = squeeze(line)) { # effective LOC 153 if (ret) ret = ret RS 154 ret = ret line 155 } 156 } 157 return ret 158} 159 160function build(target, type, i, group, inline, line, temp) { 161 # Default target: bash 162 if (!target) target = "bash" 163 164 ("mkdir -p " parameterize(BuildPath)) | getline 165 166 if (target == "bash" || target == "zsh") { 167 168 print "#!/usr/bin/env " target > Trans 169 170 if (fileExists("DISCLAIMER")) { 171 print "#" > Trans 172 while (getline line < "DISCLAIMER") 173 print "# " line > Trans 174 print "#" > Trans 175 } 176 177 print "export TRANS_ENTRY=\"$0\"" > Trans 178 print "if [[ ! $LANG =~ (UTF|utf)-?8$ ]]; then export LANG=en_US.UTF-8; fi" > Trans 179 180 print "read -r -d '' TRANS_PROGRAM << 'EOF'" > Trans 181 print readSqueezed(EntryPoint, TRUE) > Trans 182 print "EOF" > Trans 183 184 print "read -r -d '' TRANS_MANPAGE << 'EOF'" > Trans 185 if (fileExists(Man)) 186 while (getline line < Man) 187 print line > Trans 188 print "EOF" > Trans 189 print "export TRANS_MANPAGE" > Trans 190 191 if (type == "release") 192 print "export TRANS_BUILD=release" temp > Trans 193 else { 194 temp = getGitHead() 195 if (temp) 196 print "export TRANS_BUILD=git:" temp > Trans 197 } 198 199 print "gawk -f <(echo -E \"$TRANS_PROGRAM\") - \"$@\"" > Trans 200 201 ("chmod +x " parameterize(Trans)) | getline 202 203 # Rebuild EntryScript 204 print "#!/bin/sh" > EntryScript 205 print "export TRANS_DIR=`dirname $0`" > EntryScript 206 print "gawk \\" > EntryScript 207 for (i = 0; i < length(Includes) - 1; i++) 208 print "-i \"${TRANS_DIR}/" Includes[i] "\" \\" > EntryScript 209 print "-f \"${TRANS_DIR}/" Includes[i] "\" -- \"$@\"" > EntryScript 210 ("chmod +x " parameterize(EntryScript)) | getline 211 return 0 212 213 } else if (target == "awk" || target == "gawk") { 214 215 "uname -s" | getline temp 216 print (temp == "Darwin" ? 217 "#!/usr/bin/env gawk -f" : # macOS 218 "#!/usr/bin/gawk -f") > TransAwk 219 220 print readSqueezed(EntryPoint, TRUE) > TransAwk 221 222 ("chmod +x " parameterize(TransAwk)) | getline 223 return 0 224 225 } else { 226 227 w("[FAILED] Unknown target: " ansi("underline", target)) 228 w(" Supported targets: " \ 229 ansi("underline", "bash") ", " \ 230 ansi("underline", "zsh") ", " \ 231 ansi("underline", "gawk")) 232 return 1 233 234 } 235} 236 237function clean() { 238 ("rm -f " BuildPath Command "*") | getline 239 return 0 240} 241 242function release( content, group, sha1, size, temp, text) { 243 d("Updating registry ...") 244 # Update registry 245 text = readFrom(MainRegistryTemplate) 246 gsub(/\$Version\$/, Version, text) 247 writeTo(text, MainRegistry) 248 249 d("Updating gh-pages/images ...") 250 # Update gh-pages/images/badge-release 251 text = readFrom(BadgeRelease ".temp") 252 gsub(/\$Version\$/, Version, text) 253 writeTo(text, BadgeRelease) 254 system("save-to-png " BadgeRelease) 255 # Update gh-pages/images/badge-download 256 ("wc -c " Trans) | getline temp 257 split(temp, group) 258 size = int(group[1] / 1000) 259 text = readFrom(BadgeDownload ".temp") 260 gsub(/\$Size\$/, size, text) 261 writeTo(text, BadgeDownload) 262 system("save-to-png " BadgeDownload) 263 264 d("Updating gh-pages/index.md ...") 265 # Update gh-pages/index.md 266 ("sha1sum " Trans) | getline temp 267 split(temp, group) 268 sha1 = group[1] 269 content = readFrom(Readme) 270 text = readFrom(Index ".temp") 271 gsub(/\$sha1\$/, sha1, text) 272 gsub(/\$Version\$/, Version, text) 273 gsub(/\$readme\$/, content, text) 274 writeTo(text, Index) 275 276 return 0 277} 278 279function test() { 280 return 0 281} 282 283BEGIN { 284 init() 285 286 pos = 0 287 while (ARGV[++pos]) { 288 # -target TARGET 289 match(ARGV[pos], /^--?target(=(.*)?)?$/, group) 290 if (RSTART) { 291 target = tolower(group[2] ? group[2] : ARGV[++pos]) 292 continue 293 } 294 295 # -type TYPE 296 match(ARGV[pos], /^--?type(=(.*)?)?$/, group) 297 if (RSTART) { 298 type = tolower(group[2] ? group[2] : ARGV[++pos]) 299 continue 300 } 301 302 # TASK 303 match(ARGV[pos], /^[^\-]/, group) 304 if (RSTART) { 305 append(tasks, ARGV[pos]) 306 continue 307 } 308 } 309 310 # Default task: build 311 if (!anything(tasks)) tasks[0] = "build" 312 313 for (i = 0; i < length(tasks); i++) { 314 task = tasks[i] 315 status = 0 316 switch (task) { 317 318 case "man": 319 status = man() 320 break 321 322 case "readme": 323 status = readme() 324 break 325 326 case "wiki": 327 status = wiki() 328 break 329 330 case "doc": 331 status = doc() 332 break 333 334 case "build": 335 status = build(target, type) 336 break 337 338 case "clean": 339 status = clean() 340 break 341 342 case "release": 343 status = release() 344 break 345 346 case "test": 347 status = test() 348 break 349 350 default: # unknown task 351 status = -1 352 } 353 354 if (status == 0) { 355 d("[OK] Task " ansi("bold", task) " completed.") 356 } else if (status < 0) { 357 w("[FAILED] Unknown task: " ansi("bold", task)) 358 exit 1 359 } else { 360 w("[FAILED] Task " ansi("bold", task) " failed.") 361 exit 1 362 } 363 } 364} 365