Глянул повнимательнее на этот проект: https://github.com/noraj/vbsmin. Ребята написали неплохой "уменьшитель" VBScript, но на Ruby. Видимо есть у них такая необходимость.
Я не знаю Ruby, но там и так все понятно:
-- переписал на VBScript (лицензия MIT вроде бы позволяет), почти в лоб, пока с очень минимальной отпимизацией под язык
-- выкинул некоторые методы, сделал на публичных функциях, не стал оформлять в класс (потому как черновик только)
-- намеренно оставил все комментарии (с небольшими правками)
-- убрал избыточнные телодвижения с вводом/выводом - это дело вызывающей программы, а не модуля
Прогнал несколько раз свой модуль:
0. контрольный прогон через ruby 2.6.4p104 (2019-08-28 revision 67798) [x86_64-cygwin]
1.1. "уменьшил" исходный код модуля своим модулем
1.2. "уменьшенную" версию прогнал еще раз
Ожидаемый результаты: версии 1.1 и 1.2 совпадат с версией 0
2.1. "уменьшил" исходный код модуля уменьшенной весрией
2.2. "уменьшенную" версию прогнал еще раз
Ожидаемый результаты: "уменьшенная" версия работает; версии 2.1 и 2.2 совпадат с версией 0
' Minify a VBScript input (make a minified copy)
'
' @param [String] original VBScript text
' @return [String] minified VBScript text
Function minify(text)
Dim lines, i, line, result
result = ""
' Parse the entire text as separate lines
lines = Split(text, Chr(10))
For i = 0 To UBound(lines)
line = lines(i)
line = minify_line(line)
If line <> "" Then
result = result & line
End If
Next
' Remove trailing ":", if any
If Right(result, 1) = ":" Then
result = Left(result, Len(result) - 1)
End If
minify = result
End Function
Function minify_line(line)
Dim eol
' End of file char
eol = ":"
' Remove inline comment (must be before whitespace striping)
line = inline_comment(line)
' Remove leading and trailing whitespaces: null, horizontal tab, line feed,
' vertical tab, form feed, carriage return, space
line = strip(line)
' Remove comments except inline ones (must be after whitespace striping)
If Mid(line, 1, 1) = "'" Or UCase(Mid(line, 1, 3)) = "REM" Then
line = ""
End If
' Remove space when several spaces between two keywords
line = internal_space(line)
' Remove line splitting
If Right(line, 2) = " _" Then
line = Left(line, Len(line) - 1)
eol = ""
End If
If line <> "" Then
line = line & eol
End If
minify_line = line
End Function
' Remove inline comments
' In VBS there is no single quote strings so it's safe to remove until the end
' of string when ecountering a single quote.
' The only case to handle if is a single quote appears in a double quote string.
Function inline_comment(line)
Dim quotes, i, c
' For each single quote, if there is an odd number of double quote before
' we are in a string, but if there is an even number of double quote before
' we are out of a string so this is an inline comment and we can remove all
' that comes after.
quotes = 0
For i = 1 To Len(line)
c = Mid(line, i, 1)
If c = Chr(34) Then
quotes = quotes + 1
End If
If c = "'" And quotes Mod 2 = 0 Then
inline_comment = Mid(line, 1, i - 1)
Exit Function
End If
Next
inline_comment = line
End Function
' Remove all the characters supposed to be whitespaces
Function strip(line)
Dim re
set re = New RegExp
re.Pattern = "^[\t\r\n\f\v ]*|[\t\r\n\f\v ]*$"
re.Global = True
strip = re.Replace(line, "")
End Function
' Remove extra spaces (several spaces between two keywords except in a string)
' More reliable than internal_space_old which use string replacement and string
' split
Function internal_space(line)
Dim quotes, prev, i, c, result
' For each single quote, if there is an odd number of double quote before
' we are in a string, but if there is an even number of double quote before
' we are out of a string.
quotes = 0
prev = ""
result = ""
For i = 1 To Len(line)
c = Mid(line, i, 1)
If c = Chr(34) Then
quotes = quotes + 1
End If
If Not ( prev = " " And c = " " And quotes Mod 2 = 0 ) Then
result = result & c
End If
prev = c
Next
internal_space = result
End Function
text = WScript.StdIn.ReadAll()
text = minify(text)
WScript.StdOut.Write(text)
( 2 * b ) || ! ( 2 * b )