-
-
Save sorbits/989679 to your computer and use it in GitHub Desktop.
align.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Alignes the source | |
def align(text, regexp, width) | |
text.to_a.map do |line| | |
if offset = offsetOfRegexpInLine(line, regexp) | |
if shouldInsertBefore(line, regexp) | |
before = line[0..offset-1] | |
before + ' ' * (width - (before.length)) + line[offset..line.length-1] | |
else | |
before = line[0..offset] | |
before + ' ' * (width - (before.length-1)) + line[offset+1..line.length-1] | |
end | |
else | |
line | |
end | |
end.join | |
end | |
# Figures out if the spacing should be added before or after the match | |
def shouldInsertBefore(line, regexp) | |
offset = offsetOfRegexpInLine(line,regexp) | |
if line.chars.to_a[offset-1] =~ /\s/ then true else false end | |
end | |
# Finds the width of the line with the most text before the regexp. | |
def width(text, regexp) | |
text.split("\n").collect { |line| offsetOfRegexpInLine(line,regexp) }.max | |
end | |
# The offset of a regexp in a line of text. -1 if it doesn't match | |
def offsetOfRegexpInLine(line, regexp) | |
if match = regexp.match(line) | |
match.offset(match.size > 1 ? 1 : 0)[0] | |
else | |
-1 | |
end | |
end | |
# Checks that the regexp matches every line | |
def hasMatchForAll(text, regexp) | |
text.to_a.select { |x| not x =~ /^\s*$/}.all? { |line| line =~ regexp } | |
end | |
# Checks if the first occurance of the regexp is at the same column in each line | |
def notAlignedIn(text,regexp) | |
not text.to_a.collect { |line| offsetOfRegexpInLine(line, regexp) }.reduce { |acc, x| x == acc } | |
end | |
# sorts and filters the regular expressions so the ones with the captures with the | |
# lowest offset comes first. The ones that aren't matched at all are filtered. | |
def prioritizeRegexps(text, regexps) | |
regexps.select{ |regexp| | |
hasMatchForAll(text, regexp) && notAlignedIn(text, regexp) | |
}.collect { |regexp| { | |
"min_offset" => text.split("\n").collect { |line| offsetOfRegexpInLine(line,regexp) }.min, | |
"regexp" => regexp | |
}}.sort { |dict1,dict2| | |
dict1['min_offset'] <=> dict2['min_offset'] | |
}.select { |dict| | |
dict['min_offset'] > 0 | |
}.collect { |dict| | |
dict['regexp'] | |
} | |
end | |
=begin | |
Lets give it a try | |
=end | |
regexps = [ /(,)(?!$)/, /\}/, /<-/, /\s[-+\/*|]?(=)\s/, /\s(=>)\s/,/:/,/\/\// ] | |
text = DATA.read | |
prioritizeRegexps(text, regexps).each { |regexp| | |
text = align(text, regexp, width(text, regexp)) | |
} | |
puts text | |
__END__ | |
{ capitalizeWord, flag::insert }, | |
{ changeCaseOfLetter, flag::insert }, | |
{ changeCaseOfWord, flag::insert }, | |
{ complete, flag::insert|flag::unselect }, | |
{ deleteBackward, flag::erase }, | |
{ deleteBackwardByDecomposingPreviousCharacter, flag::insert }, | |
{ deleteForward, flag::erase }, | |
{ deleteSubWordBackward, flag::erase }, | |
{ deleteSubWordForward, flag::erase }, | |
{ deleteToBeginningOfLine, flag::erase }, | |
{ deleteToBeginningOfParagraph, flag::erase }, | |
{ deleteToEndOfLine, flag::erase }, | |
{ deleteToEndOfParagraph, flag::erase }, | |
{ deleteToMark, flag::mark }, | |
{ deleteWordBackward, flag::erase }, | |
{ deleteWordForward, flag::erase }, | |
{ indent, flag::insert }, | |
{ insertBacktab, flag::insert|flag::unselect }, | |
{ insertNewline, flag::insert|flag::unselect }, | |
{ insertNewlineIgnoringFieldEditor, flag::insert|flag::unselect }, | |
{ insertTab, flag::insert|flag::unselect }, | |
{ insertTabIgnoringFieldEditor, flag::insert|flag::unselect }, | |
{ moveBackward, flag::simple_movement }, | |
{ moveDown, flag::require_continuous_selection|flag::simple_movement }, | |
{ moveDownAndModifySelection, flag::require_continuous_selection }, | |
{ moveForward, flag::simple_movement }, | |
{ moveParagraphBackwardAndModifySelection, flag::require_continuous_selection }, | |
{ moveParagraphForwardAndModifySelection, flag::require_continuous_selection }, | |
{ moveToBeginningOfColumn, flag::require_continuous_selection }, | |
{ moveToBeginningOfColumnAndModifySelection, flag::require_continuous_selection }, | |
{ moveToBeginningOfDocument, flag::require_continuous_selection }, | |
{ moveToBeginningOfDocumentAndModifySelection, flag::require_continuous_selection }, | |
{ moveToBeginningOfParagraph, flag::require_continuous_selection }, | |
{ moveToEndOfColumn, flag::require_continuous_selection }, | |
{ moveToEndOfColumnAndModifySelection, flag::require_continuous_selection }, | |
{ moveToEndOfDocument, flag::require_continuous_selection }, | |
{ moveToEndOfDocumentAndModifySelection, flag::require_continuous_selection }, | |
{ moveToEndOfParagraph, flag::require_continuous_selection }, | |
{ moveUp, flag::require_continuous_selection|flag::simple_movement }, | |
{ moveUpAndModifySelection, flag::require_continuous_selection }, | |
{ moveWordBackward, flag::simple_movement }, | |
{ moveWordForward, flag::simple_movement }, | |
{ nextCompletion, flag::insert|flag::unselect }, | |
{ pageDown, flag::require_continuous_selection }, | |
{ pageDownAndModifySelection, flag::require_continuous_selection }, | |
{ pageUp, flag::require_continuous_selection }, | |
{ pageUpAndModifySelection, flag::require_continuous_selection }, | |
{ previousCompletion, flag::insert|flag::unselect }, | |
{ reformatText, flag::insert }, | |
{ reformatTextAndJustify, flag::insert }, | |
{ selectToMark, flag::mark }, | |
{ shiftLeft, flag::insert }, | |
{ shiftRight, flag::insert }, | |
{ swapWithMark, flag::mark }, | |
{ transpose, flag::insert }, | |
{ unwrapText, flag::insert }, |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment