Class: Spacer
- Inherits:
-
Object
- Object
- Spacer
- Defined in:
- lib/spacer.rb
Instance Method Summary collapse
- #count_bol_spaces_and_tabs(lines) ⇒ Object
- #count_csharp_bol_spaces_and_tabs(lines) ⇒ Object
- #csharp_tabify(lines, options) ⇒ Object
- #csharp_untabify(lines, options) ⇒ Object
- #error(msg) ⇒ Object
- #execute ⇒ Object
- #get_whitespace_type(bol) ⇒ Object
- #parse(args) ⇒ Object
- #read_file_lines(filename) ⇒ Object
- #tabify(lines, options) ⇒ Object
- #untabify(lines, options) ⇒ Object
Instance Method Details
#count_bol_spaces_and_tabs(lines) ⇒ Object
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 |
# File 'lib/spacer.rb', line 214 def count_bol_spaces_and_tabs(lines) bol = OpenStruct.new bol.spaces = 0 bol.tabs = 0 for line in lines do for i in 0...line.length do c = line[i] if c == " " bol.spaces += 1 elsif c == "\t" bol.tabs += 1 else break end end end bol end |
#count_csharp_bol_spaces_and_tabs(lines) ⇒ Object
182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 |
# File 'lib/spacer.rb', line 182 def count_csharp_bol_spaces_and_tabs(lines) bol = OpenStruct.new bol.tabs = 0 bol.spaces = 0 in_multi_line_string = false for line in lines do in_bol = true i = 0 while i < line.length do c = line[i] c1 = i < line.length - 1 ? line[i + 1] : "\0" if in_multi_line_string and c == "\"" and c1 != "\"" in_multi_line_string = false elsif c == "@" and c1 == "\"" in_multi_line_string = true i += 1 elsif in_bol and !in_multi_line_string and c == " " bol.spaces += 1 elsif in_bol and !in_multi_line_string and c == "\t" bol.tabs += 1 else in_bol = false end i += 1 end end bol end |
#csharp_tabify(lines, options) ⇒ Object
343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 |
# File 'lib/spacer.rb', line 343 def csharp_tabify(lines, ) # Insert tabs for spaces, but only at the beginning of lines and not inside @"..." or "..." strings in_multi_line_string = false i = 0 while i < lines.length do line = lines[i] in_string = false bol = true num_bol_spaces = 0 new_line = "" j = 0 while j < line.length do c_1 = j > 0 ? line[j - 1] : "\0" c = line[j] c1 = j < line.length - 1 ? line[j + 1] : "\0" if !in_string and !in_multi_line_string and bol and c == " " # Just count the spaces num_bol_spaces += 1 elsif !in_string and !in_multi_line_string and bol and c != " " bol = false new_line += "\t" * (num_bol_spaces / .tabsize) if !.round_down_spaces new_line += " " * (num_bol_spaces % .tabsize) end # Process this character again as not BOL j -= 1 elsif !in_multi_line_string and !in_string and c == '"' in_string = true new_line += c elsif !in_multi_line_string and !in_string and c == "@" and c1 == "\"" in_multi_line_string = true new_line += c j += 1 new_line += c1 elsif in_string and c == "\"" and c_1 != "\\" in_string = false new_line += c elsif in_multi_line_string and c == "\"" and c1 != "\"" in_multi_line_string = false new_line += c else new_line += c end lines[i] = new_line j += 1 end i += 1 end end |
#csharp_untabify(lines, options) ⇒ Object
295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 |
# File 'lib/spacer.rb', line 295 def csharp_untabify(lines, ) # Expand tabs anywhere on a line, but not inside @"..." strings in_multi_line_string = false i = 0 while i < lines.length do line = lines[i] in_string = false new_line = "" j = 0 while j < line.length do c_1 = j > 0 ? line[j - 1] : '\0' c = line[j] c1 = j < line.length - 1 ? line[j + 1] : '\0' raise "line #{i + 1} has overlapping regular and multiline strings" if (in_string and in_multi_line_string) if !in_multi_line_string and c == "\t" # Add spaces to next tabstop num_spaces = .tabsize - (new_line.length % .tabsize) new_line += " " * num_spaces elsif !in_multi_line_string and !in_string and c == "\"" in_string = true new_line += c elsif !in_multi_line_string and !in_string and c == "@" and c1 == "\"" in_multi_line_string = true new_line += c j += 1 new_line += c1 elsif in_string and c == "\"" and c_1 != "\\" in_string = false new_line += c elsif in_multi_line_string and c == "\"" and c1 != "\"" in_multi_line_string = false new_line += c else new_line += c end lines[i] = new_line j += 1 end i += 1 end end |
#error(msg) ⇒ Object
399 400 401 |
# File 'lib/spacer.rb', line 399 def error(msg) STDERR.puts "error: #{msg}".colorize(:red) end |
#execute ⇒ Object
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/spacer.rb', line 69 def execute = self.parse(ARGV) if !File.exist?(.input_filename) error "File #{options.input_filename} does not exist" exit end if .output_filename.length == 0 .output_filename = .input_filename end if File.extname(.input_filename) == '.cs' file_type = :csharp else file_type = :other end lines = read_file_lines(.input_filename) if file_type == :csharp before = count_csharp_bol_spaces_and_tabs(lines) else before = count_bol_spaces_and_tabs(lines) end if .convert_mode != nil if file_type == :other untabify(lines, ) else csharp_untabify(lines, ) end if .convert_mode == :tabs if file_type == :other tabify(lines, ) else csharp_tabify(lines, ) end end end ws = get_whitespace_type(before) msg = "\"#{options.input_filename}\", #{file_type.to_s}, #{ws.to_s}" if .convert_mode != nil if file_type == :csharp after = count_csharp_bol_spaces_and_tabs(lines) else after = count_bol_spaces_and_tabs(lines) end ws = get_whitespace_type(after) file = nil begin file = File.new(.output_filename, 'w') for line in lines do file.write(line) end ensure file.close() unless file == nil end msg += " -> \"#{options.output_filename}\", #{ws.to_s}" end puts msg end |
#get_whitespace_type(bol) ⇒ Object
141 142 143 |
# File 'lib/spacer.rb', line 141 def get_whitespace_type(bol) (bol.tabs > 0) ? (bol.spaces > 0 ? :mixed : :tabs) : :spaces end |
#parse(args) ⇒ Object
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/spacer.rb', line 9 def parse(args) = OpenStruct.new .output_filename = '' .input_filename = nil .convert_mode = nil .tabsize = 4 .round_down_spaces = false opt_parser = OptionParser.new do |opts| opts. = %Q(Spacer Text File Space/Tab Fixer Tool. Version #{$VERSION} Copyright (c) John Lyon-Smith, 2015. Usage: #{File.basename(__FILE__)} [options] ) opts.separator %Q(Description: When reporting the tool indicates beginning-of-line \(BOL\) tabs and spaces. When replacing, all tabs not at the beginning of a line are replaced with spaces. Spaces and tabs inside multi-line C# strings (@"...") and inside Ruby \%Q\(...\) strings are ignored. Note that conversion to tabs may still leave the file as mixed as some lines may have spaces that are not a whole number multiple of the tabstop size. In that case use the -round option to remove smooth out the spurious spaces. ) opts.separator %Q(Options: ) opts.on("-o", "--output FILE", String, "The output file. Default is the same as the input file.") do |file| .output_filename = File.(file) end opts.on("-m", "--mode MODE", [:mixed, :tabs, :spaces], "The convert mode (mixed, tabs or spaces)", "Default is to just display the files current state.", "Updates will only be done when this argument is given.") do |mode| .convert_mode = mode end opts.on("-t", "--tabsize SIZE", Integer, "Tab size in spaces to assume. Default is 4 spaces.") do |size| .tabsize = size end opts.on("-r", "--round", "When tabifying, round BOL spaces down to an exact number of tabs.") do |round| .round_down_spaces = round end opts.on_tail("-?", "--help", "Show this message") do puts opts exit end end opt_parser.parse!(args) .input_filename = ARGV.pop if .input_filename == nil error 'Need to specify a file to process' exit end .input_filename = File.(.input_filename) end |
#read_file_lines(filename) ⇒ Object
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
# File 'lib/spacer.rb', line 145 def read_file_lines(filename) # Read the entire file file_contents = File.read(filename) # Convert to a list of lines, preserving the end-of-lines lines = [] s = 0 i = 0 while i < file_contents.length do c = file_contents[i] c1 = i < file_contents.length - 1 ? file_contents[i + 1] : "\0" if c == "\r" i += 1 if c1 == "\n" i += 1 end elsif c == "\n" i += 1 else i += 1 next end lines.push(file_contents[s, i - s]) s = i end if s != i lines.push(file_contents[s, i - s]) end lines end |
#tabify(lines, options) ⇒ Object
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 |
# File 'lib/spacer.rb', line 260 def tabify(lines, ) i = 0 while i < lines.length do line = lines[i] j = 0 bol = true num_bol_spaces = 0 new_line = "" while j < line.length do c = line[j] if bol and c == " " num_bol_spaces += 1 elsif bol and c != " " bol = false new_line += "\t" * (num_bol_spaces / .tabsize) if !.round_down_spaces new_line += " " * (num_bol_spaces % .tabsize) end new_line += c else new_line += c end j += 1 end lines[i] = new_line i += 1 end end |
#untabify(lines, options) ⇒ Object
236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 |
# File 'lib/spacer.rb', line 236 def untabify(lines, ) i = 0 while i < lines.length do line = lines[i] j = 0 new_line = "" while j < line.length do c = line[j] if c == "\t" num_spaces = .tabsize - (new_line.length % .tabsize) new_line += " " * num_spaces else new_line += c end j += 1 end lines[i] = new_line i += 1 end end |