Skip to content

Instantly share code, notes, and snippets.

@ramontayag
Created December 23, 2010 14:42
Show Gist options
  • Save ramontayag/753062 to your computer and use it in GitHub Desktop.
Save ramontayag/753062 to your computer and use it in GitHub Desktop.
# Used to parse through an scss stylesheet to make editing of that stylesheet simpler
# Ex. Given a file called style.scss
#
# // @name Masthead Background Color
# // @type color
# // @description Background color of the masthead.
# $masthead_bg_color: #444;
#
# sp = StyleParser.new(contents of style.scss)
#
# # Reading
# sp.masthead_bg_color.value # returns "#444"
# sp.masthead_bg_color.name # returns "Masthead Background Color"
# sp.masthead_bg_color.type # returns "color"
# sp.masthead_bg_color.description # returns "Background color of the masthead."
#
# # Writing
# sp.masthead_bg_color.value = "#555"
# sp.render # returns all the text above except masthead_bg_color is now #555;
# Useful stuff:
# string = "my name is"
# string.index("name") # returns 3
# File.open("test.txt").each_with_index do |...| # to go to the line we want
# How to get the lines surrounding certain text: http://stackoverflow.com/questions/2760759/ruby-equivalent-to-grep-c-5-to-get-context-of-lines-around-the-match
class StyleParser
def initialize(text)
@text = text
@variables = {}
@eol = '\n'
@context_lines = 3
@comment = /\/\//
@context = "(^(?:#{@comment}\s@.*#{@eol}){#{@context_lines}})"
end
# Works this way: http://rubular.com/r/jWSYvfVrjj
# From http://rubular.com/r/jWSYvfVrjj
# Derived from http://stackoverflow.com/questions/2760759/ruby-equivalent-to-grep-c-5-to-get-context-of-lines-around-the-match
def get_context(s)
regexp = /.*\${1}#{s}:.*;[#{@eol}]*/
@text =~ /^#{@context}(#{regexp})/
before, match = $1, $2
#puts "Before: #{before}; match #{match};"
"#{before}#{match}"
end
def update_attributes(args)
args.each do |k, v|
send(k) # Instantiate it, so it will exist in @variables
@variables[k].value = v unless @variables[k].nil? || v.nil?
end
end
def render
@variables.each do |key, var|
@text.gsub!(/^\$#{key}: .+;/, %Q($#{key}: #{var.value};))
end
@text
end
def method_missing(method_name)
if method_name.to_s =~ /[\w]+/
context = get_context(method_name)
# If there's no context (no variable with the proper
# commented metadata), then it should not be accessible
# and it won't come out in the form
if context.blank?
nil
else
@variables[method_name] ||= StyleVariable.new(method_name, context, @comment)
end
end
end
end
class StyleVariable
METADATA = %w(name kind description)
def initialize(var, text, comment)
@var = var
@text = text
@comment = comment
end
def method_missing(method_name)
if METADATA.include? method_name.to_s
content_of(method_name.to_s)
end
end
def value
@text.each do |string|
string =~ /^\${1}#{@var}: (.+);/
return $1 if $1
end
end
def value=(val)
@text.gsub!(/^\$#{@var}: .+;/, "$#{@var}: #{val};")
end
private
def content_of(variable)
@text.each do |string|
string =~ /^#{@comment} @([\w]+[^\s]) (.+)/
return $2 if $1 == variable
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment