Parent

Included Modules

Class Index [+]

Quicksearch

Sass::SCSS::Parser

The parser for SCSS. It parses a string of code into a tree of {Sass::Tree::Node}s.

Constants

DIRECTIVES
EXPR_NAMES
TOK_NAMES

Public Class Methods

new(str, line = 1) click to toggle source

@param str [String, StringScanner] The source document to parse.

  Note that `Parser` *won't* raise a nice error message if this isn't properly parsed;
  for that, you should use the higher-level {Sass::Engine} or {Sass::CSS}.

@param line [Fixnum] The line on which the source string appeared,

  if it's part of another document
    # File lib/sass/scss/parser.rb, line 14
14:       def initialize(str, line = 1)
15:         @template = str
16:         @line = line
17:         @strs = []
18:       end

Private Class Methods

expected(scanner, expected, line) click to toggle source

@private

     # File lib/sass/scss/parser.rb, line 785
785:       def self.expected(scanner, expected, line)
786:         pos = scanner.pos
787: 
788:         after = scanner.string[0...pos]
789:         # Get rid of whitespace between pos and the last token,
790:         # but only if there's a newline in there
791:         after.gsub!(/\s*\n\s*$/, '')
792:         # Also get rid of stuff before the last newline
793:         after.gsub!(/.*\n/, '')
794:         after = "..." + after[15..1] if after.size > 18
795: 
796:         was = scanner.rest.dup
797:         # Get rid of whitespace between pos and the next token,
798:         # but only if there's a newline in there
799:         was.gsub!(/^\s*\n\s*/, '')
800:         # Also get rid of stuff after the next newline
801:         was.gsub!(/\n.*/, '')
802:         was = was[0...15] + "..." if was.size > 18
803: 
804:         raise Sass::SyntaxError.new(
805:           "Invalid CSS after \"#{after}\": expected #{expected}, was \"#{was}\"",
806:           :line => line)
807:       end
sass_script_parser() click to toggle source

@private

     # File lib/sass/scss/parser.rb, line 729
729:       def self.sass_script_parser; @sass_script_parser; end

Public Instance Methods

parse() click to toggle source

Parses an SCSS document.

@return [Sass::Tree::RootNode] The root node of the document tree @raise [Sass::SyntaxError] if there’s a syntax error in the document

    # File lib/sass/scss/parser.rb, line 24
24:       def parse
25:         init_scanner!
26:         root = stylesheet
27:         expected("selector or at-rule") unless @scanner.eos?
28:         root
29:       end
parse_interp_ident() click to toggle source

Parses an identifier with interpolation. Note that this won’t assert that the identifier takes up the entire input string; it’s meant to be used with `StringScanner`s as part of other parsers.

@return [Array, nil]

  The interpolated identifier, or nil if none could be parsed
    # File lib/sass/scss/parser.rb, line 37
37:       def parse_interp_ident
38:         init_scanner!
39:         interp_ident
40:       end

Private Instance Methods

_interp_string(type) click to toggle source
     # File lib/sass/scss/parser.rb, line 679
679:       def _interp_string(type)
680:         return unless start = tok(Sass::Script::Lexer::STRING_REGULAR_EXPRESSIONS[[type, false]])
681:         res = [start]
682: 
683:         mid_re = Sass::Script::Lexer::STRING_REGULAR_EXPRESSIONS[[type, true]]
684:         # @scanner[2].empty? means we've started an interpolated section
685:         while @scanner[2] == '#{'
686:           @scanner.pos -= 2 # Don't consume the #{
687:           res.last.slice!(2..1)
688:           res << expr!(:interpolation) << tok(mid_re)
689:         end
690:         res
691:       end
_selector() click to toggle source
     # File lib/sass/scss/parser.rb, line 409
409:       def _selector
410:         # The combinator here allows the "> E" hack
411:         return unless val = combinator || simple_selector_sequence
412:         nl = str{ss}.include?("\n")
413:         res = []
414:         res << val
415:         res << "\n" if nl
416: 
417:         while val = combinator || simple_selector_sequence
418:           res << val
419:           res << "\n" if str{ss}.include?("\n")
420:         end
421:         Selector::Sequence.new(res.compact)
422:       end
attrib() click to toggle source
     # File lib/sass/scss/parser.rb, line 493
493:       def attrib
494:         return unless tok(/\[/)
495:         ss
496:         ns, name = attrib_name!
497:         ss
498: 
499:         if op = tok(/=/) ||
500:             tok(INCLUDES) ||
501:             tok(DASHMATCH) ||
502:             tok(PREFIXMATCH) ||
503:             tok(SUFFIXMATCH) ||
504:             tok(SUBSTRINGMATCH)
505:           @expected = "identifier or string"
506:           ss
507:           if val = tok(IDENT)
508:             val = [val]
509:           else
510:             val = expr!(:interp_string)
511:           end
512:           ss
513:         end
514:         tok(/\]/)
515: 
516:         Selector::Attribute.new(merge(name), merge(ns), op, merge(val))
517:       end
attrib_name!() click to toggle source
     # File lib/sass/scss/parser.rb, line 519
519:       def attrib_name!
520:         if name_or_ns = interp_ident
521:           # E, E|E
522:           if tok(/\|(?!=)/)
523:             ns = name_or_ns
524:             name = interp_ident
525:           else
526:             name = name_or_ns
527:           end
528:         else
529:           # *|E or |E
530:           ns = [tok(/\*/) || ""]
531:           tok!(/\|/)
532:           name = expr!(:interp_ident)
533:         end
534:         return ns, name
535:       end
block(node, context) click to toggle source
     # File lib/sass/scss/parser.rb, line 310
310:       def block(node, context)
311:         node.has_children = true
312:         tok!(/\{/)
313:         block_contents(node, context)
314:         tok!(/\}/)
315:         node
316:       end
block_child(context) click to toggle source
     # File lib/sass/scss/parser.rb, line 329
329:       def block_child(context)
330:         return variable || directive || ruleset if context == :stylesheet
331:         variable || directive || declaration_or_ruleset
332:       end
block_contents(node, context) click to toggle source

A block may contain declarations and/or rulesets

     # File lib/sass/scss/parser.rb, line 319
319:       def block_contents(node, context)
320:         block_given? ? yield : ss_comments(node)
321:         node << (child = block_child(context))
322:         while tok(/;/) || (child && child.has_children)
323:           block_given? ? yield : ss_comments(node)
324:           node << (child = block_child(context))
325:         end
326:         node
327:       end
class_selector() click to toggle source
     # File lib/sass/scss/parser.rb, line 461
461:       def class_selector
462:         return unless tok(/\./)
463:         @expected = "class name"
464:         Selector::Class.new(merge(expr!(:interp_ident)))
465:       end
combinator() click to toggle source
     # File lib/sass/scss/parser.rb, line 424
424:       def combinator
425:         tok(PLUS) || tok(GREATER) || tok(TILDE)
426:       end
debug_directive() click to toggle source
     # File lib/sass/scss/parser.rb, line 147
147:       def debug_directive
148:         node(Sass::Tree::DebugNode.new(sass_script(:parse)))
149:       end
declaration() click to toggle source
     # File lib/sass/scss/parser.rb, line 569
569:       def declaration
570:         # This allows the "*prop: val", ":prop: val", and ".prop: val" hacks
571:         if s = tok(/[:\*\.]|\#(?!\{)/)
572:           @use_property_exception = s !~ /[\.\#]/
573:           name = [s, str{ss}, *expr!(:interp_ident)]
574:         else
575:           return unless name = interp_ident
576:           name = [name] if name.is_a?(String)
577:         end
578:         if comment = tok(COMMENT)
579:           name << comment
580:         end
581:         ss
582: 
583:         tok!(/:/)
584:         space, value = value!
585:         ss
586:         require_block = tok?(/\{/)
587: 
588:         node = node(Sass::Tree::PropNode.new(name.flatten.compact, value, :new))
589: 
590:         return node unless require_block
591:         nested_properties! node, space
592:       end
declaration_or_ruleset() click to toggle source

This is a nasty hack, and the only place in the parser that requires backtracking. The reason is that we can’t figure out if certain strings are declarations or rulesets with fixed finite lookahead. For example, “foo:bar baz baz baz...“ could be either a property or a selector.

To handle this, we simply check if it works as a property (which is the most common case) and, if it doesn’t, try it as a ruleset.

We could eke some more efficiency out of this by handling some easy cases (first token isn’t an identifier, no colon after the identifier, whitespace after the colon), but I’m not sure the gains would be worth the added complexity.

     # File lib/sass/scss/parser.rb, line 349
349:       def declaration_or_ruleset
350:         pos = @scanner.pos
351:         line = @line
352:         old_use_property_exception, @use_property_exception =
353:           @use_property_exception, false
354:         begin
355:           decl = declaration
356:           unless decl && decl.has_children
357:             # We want an exception if it's not there,
358:             # but we don't want to consume if it is
359:             tok!(/[;}]/) unless tok?(/[;}]/)
360:           end
361:           return decl
362:         rescue Sass::SyntaxError => decl_err
363:         end
364: 
365:         @line = line
366:         @scanner.pos = pos
367: 
368:         begin
369:           return ruleset
370:         rescue Sass::SyntaxError => ruleset_err
371:           raise @use_property_exception ? decl_err : ruleset_err
372:         end
373:       ensure
374:         @use_property_exception = old_use_property_exception
375:       end
directive() click to toggle source
     # File lib/sass/scss/parser.rb, line 103
103:       def directive
104:         return unless tok(/@/)
105:         name = tok!(IDENT)
106:         ss
107: 
108:         if dir = special_directive(name)
109:           return dir
110:         end
111: 
112:         val = str do
113:           # Most at-rules take expressions (e.g. @import),
114:           # but some (e.g. @page) take selector-like arguments
115:           expr || selector
116:         end
117:         node = node(Sass::Tree::DirectiveNode.new("@#{name} #{val}".strip))
118: 
119:         if tok(/\{/)
120:           node.has_children = true
121:           block_contents(node, :directive)
122:           tok!(/\}/)
123:         end
124: 
125:         node
126:       end
element_name() click to toggle source
     # File lib/sass/scss/parser.rb, line 473
473:       def element_name
474:         return unless name = interp_ident || tok(/\*/) || (tok?(/\|/) && "")
475:         if tok(/\|/)
476:           @expected = "element name or *"
477:           ns = name
478:           name = interp_ident || tok!(/\*/)
479:         end
480: 
481:         if name == '*'
482:           Selector::Universal.new(merge(ns))
483:         else
484:           Selector::Element.new(merge(name), merge(ns))
485:         end
486:       end
else_block(node) click to toggle source
     # File lib/sass/scss/parser.rb, line 193
193:       def else_block(node)
194:         return unless tok(/@else/)
195:         ss
196:         else_node = block(
197:           Sass::Tree::IfNode.new((sass_script(:parse) if tok(/if/))),
198:           :directive)
199:         node.add_else(else_node)
200:         pos = @scanner.pos
201:         ss
202: 
203:         else_block(node) ||
204:           begin
205:             # Backtrack in case there are any comments we want to parse
206:             @scanner.pos = pos
207:             node
208:           end
209:       end
expected(name) click to toggle source
     # File lib/sass/scss/parser.rb, line 780
780:       def expected(name)
781:         self.class.expected(@scanner, @expected || name, @line)
782:       end
expr() click to toggle source
     # File lib/sass/scss/parser.rb, line 632
632:       def expr
633:         return unless t = term
634:         res = [t, str{ss}]
635: 
636:         while (o = operator) && (t = term)
637:           res << o << t << str{ss}
638:         end
639: 
640:         res
641:       end
expr!(name) click to toggle source
     # File lib/sass/scss/parser.rb, line 762
762:       def expr!(name)
763:         (e = send(name)) && (return e)
764:         expected(EXPR_NAMES[name] || name.to_s)
765:       end
extend_directive() click to toggle source
     # File lib/sass/scss/parser.rb, line 211
211:       def extend_directive
212:         node(Sass::Tree::ExtendNode.new(expr!(:selector)))
213:       end
for_directive() click to toggle source
     # File lib/sass/scss/parser.rb, line 155
155:       def for_directive
156:         tok!(/\$/)
157:         var = tok! IDENT
158:         ss
159: 
160:         tok!(/from/)
161:         from = sass_script(:parse_until, Set["to", "through"])
162:         ss
163: 
164:         @expected = '"to" or "through"'
165:         exclusive = (tok(/to/) || tok!(/through/)) == 'to'
166:         to = sass_script(:parse)
167:         ss
168: 
169:         block(node(Sass::Tree::ForNode.new(var, from, to, exclusive)), :directive)
170:       end
function() click to toggle source
     # File lib/sass/scss/parser.rb, line 660
660:       def function
661:         return unless name = tok(FUNCTION)
662:         if name == "expression(" || name == "calc("
663:           str, _ = Haml::Shared.balance(@scanner, ((, )), 1)
664:           [name, str]
665:         else
666:           [name, str{ss}, expr, tok!(/\)/)]
667:         end
668:       end
id_selector() click to toggle source
     # File lib/sass/scss/parser.rb, line 467
467:       def id_selector
468:         return unless tok(/#(?!\{)/)
469:         @expected = "id name"
470:         Selector::Id.new(merge(expr!(:interp_name)))
471:       end
if_directive() click to toggle source
     # File lib/sass/scss/parser.rb, line 178
178:       def if_directive
179:         expr = sass_script(:parse)
180:         ss
181:         node = block(node(Sass::Tree::IfNode.new(expr)), :directive)
182:         pos = @scanner.pos
183:         ss
184: 
185:         else_block(node) ||
186:           begin
187:             # Backtrack in case there are any comments we want to parse
188:             @scanner.pos = pos
189:             node
190:           end
191:       end
import_directive() click to toggle source
     # File lib/sass/scss/parser.rb, line 215
215:       def import_directive
216:         @expected = "string or url()"
217:         arg = tok(STRING) || (uri = tok!(URI))
218:         path = @scanner[1] || @scanner[2] || @scanner[3]
219:         ss
220: 
221:         media = str {media_query_list}.strip
222: 
223:         if uri || path =~ /^http:\/\// || !media.strip.empty? || use_css_import?
224:           return node(Sass::Tree::DirectiveNode.new("@import #{arg} #{media}".strip))
225:         end
226: 
227:         node(Sass::Tree::ImportNode.new(path.strip))
228:       end
include_directive() click to toggle source
     # File lib/sass/scss/parser.rb, line 140
140:       def include_directive
141:         name = tok! IDENT
142:         args = sass_script(:parse_mixin_include_arglist)
143:         ss
144:         node(Sass::Tree::MixinNode.new(name, args))
145:       end
init_scanner!() click to toggle source
    # File lib/sass/scss/parser.rb, line 46
46:       def init_scanner!
47:         @scanner =
48:           if @template.is_a?(StringScanner)
49:             @template
50:           else
51:             StringScanner.new(@template.gsub("\r", ""))
52:           end
53:       end
interp_ident(start = IDENT) click to toggle source
     # File lib/sass/scss/parser.rb, line 693
693:       def interp_ident(start = IDENT)
694:         return unless val = tok(start) || interpolation
695:         res = [val]
696:         while val = tok(NAME) || interpolation
697:           res << val
698:         end
699:         res
700:       end
interp_name() click to toggle source
     # File lib/sass/scss/parser.rb, line 702
702:       def interp_name
703:         interp_ident NAME
704:       end
interp_string() click to toggle source
     # File lib/sass/scss/parser.rb, line 675
675:       def interp_string
676:         _interp_string(:double) || _interp_string(:single)
677:       end
interpolation() click to toggle source
     # File lib/sass/scss/parser.rb, line 670
670:       def interpolation
671:         return unless tok(INTERP_START)
672:         sass_script(:parse_interpolated)
673:       end
interpolation_selector() click to toggle source
     # File lib/sass/scss/parser.rb, line 488
488:       def interpolation_selector
489:         return unless script = interpolation
490:         Selector::Interpolation.new(script)
491:       end
media_directive() click to toggle source
     # File lib/sass/scss/parser.rb, line 232
232:       def media_directive
233:         val = str {media_query_list}.strip
234:         block(node(Sass::Tree::DirectiveNode.new("@media #{val}")), :directive)
235:       end
media_expr() click to toggle source
     # File lib/sass/scss/parser.rb, line 267
267:       def media_expr
268:         return unless tok(/\(/)
269:         ss
270:         @expected = "media feature (e.g. min-device-width, color)"
271:         tok!(IDENT)
272:         ss
273: 
274:         if tok(/:/)
275:           ss; expr!(:expr)
276:         end
277:         tok!(/\)/)
278:         ss
279: 
280:         true
281:       end
media_query() click to toggle source
     # File lib/sass/scss/parser.rb, line 249
249:       def media_query
250:         if tok(/only|not/)
251:           ss
252:           @expected = "media type (e.g. print, screen)"
253:           tok!(IDENT)
254:           ss
255:         elsif !tok(IDENT) && !media_expr
256:           return
257:         end
258: 
259:         ss
260:         while tok(/and/)
261:           ss; expr!(:media_expr); ss
262:         end
263: 
264:         true
265:       end
media_query_list() click to toggle source

www.w3.org/TR/css3-mediaqueries/#syntax

     # File lib/sass/scss/parser.rb, line 238
238:       def media_query_list
239:         return unless media_query
240: 
241:         ss
242:         while tok(/,/)
243:           ss; expr!(:media_query); ss
244:         end
245: 
246:         true
247:       end
merge(arr) click to toggle source
     # File lib/sass/scss/parser.rb, line 739
739:       def merge(arr)
740:         arr && Haml::Util.merge_adjacent_strings([arr].flatten)
741:       end
mixin_directive() click to toggle source
     # File lib/sass/scss/parser.rb, line 133
133:       def mixin_directive
134:         name = tok! IDENT
135:         args = sass_script(:parse_mixin_definition_arglist)
136:         ss
137:         block(node(Sass::Tree::MixinDefNode.new(name, args)), :directive)
138:       end
negation() click to toggle source
     # File lib/sass/scss/parser.rb, line 560
560:       def negation
561:         return unless name = tok(NOT) || tok(MOZ_ANY)
562:         ss
563:         @expected = "selector"
564:         sel = selector_comma_sequence
565:         tok!(/\)/)
566:         Selector::SelectorPseudoClass.new(name[1...1], sel)
567:       end
nested_properties!(node, space) click to toggle source
     # File lib/sass/scss/parser.rb, line 621
621:       def nested_properties!(node, space)
622:         raise Sass::SyntaxError.new(Invalid CSS: a space is required between a property and its definitionwhen it has other properties nested beneath it., :line => @line) unless space
623: 
624:         @use_property_exception = true
625:         @expected = 'expression (e.g. 1px, bold) or "{"'
626:         block(node, :property)
627:       end
node(node) click to toggle source
     # File lib/sass/scss/parser.rb, line 721
721:       def node(node)
722:         node.line = @line
723:         node
724:       end
operator() click to toggle source
     # File lib/sass/scss/parser.rb, line 293
293:       def operator
294:         # Many of these operators (all except / and ,)
295:         # are disallowed by the CSS spec,
296:         # but they're included here for compatibility
297:         # with some proprietary MS properties
298:         str {ss if tok(/[\/,:.=]/)}
299:       end
parent_selector() click to toggle source
     # File lib/sass/scss/parser.rb, line 456
456:       def parent_selector
457:         return unless tok(/&/)
458:         Selector::Parent.new
459:       end
plain_value() click to toggle source
     # File lib/sass/scss/parser.rb, line 610
610:       def plain_value
611:         return unless tok(/:/)
612:         space = !str {ss}.empty?
613:         @use_property_exception ||= space || !tok?(IDENT)
614: 
615:         expression = expr
616:         expression << tok(IMPORTANT) if expression
617:         # expression, space, value
618:         return expression, space, expression || [""]
619:       end
process_comment(text, node) click to toggle source
    # File lib/sass/scss/parser.rb, line 89
89:       def process_comment(text, node)
90:         single_line = text =~ /^\/\//
91:         pre_str = single_line ? "" : @scanner.
92:           string[0...@scanner.pos].
93:           reverse[/.*?\*\/(.*?)($|\Z)/, 1].
94:           reverse.gsub(/[^\s]/, ' ')
95:         text = text.sub(/^\s*\/\//, '/*').gsub(/^\s*\/\//, ' *') + ' */' if single_line
96:         comment = Sass::Tree::CommentNode.new(pre_str + text, single_line)
97:         comment.line = @line - text.count("\n")
98:         node << comment
99:       end
pseudo() click to toggle source
     # File lib/sass/scss/parser.rb, line 537
537:       def pseudo
538:         return unless s = tok(/::?/)
539:         @expected = "pseudoclass or pseudoelement"
540:         name = expr!(:interp_ident)
541:         if tok(/\(/)
542:           ss
543:           arg = expr!(:pseudo_expr)
544:           tok!(/\)/)
545:         end
546:         Selector::Pseudo.new(s == ':' ? :class : :element, merge(name), merge(arg))
547:       end
pseudo_expr() click to toggle source
     # File lib/sass/scss/parser.rb, line 549
549:       def pseudo_expr
550:         return unless e = tok(PLUS) || tok(/-/) || tok(NUMBER) ||
551:           interp_string || tok(IDENT) || interpolation
552:         res = [e, str{ss}]
553:         while e = tok(PLUS) || tok(/-/) || tok(NUMBER) ||
554:             interp_string || tok(IDENT) || interpolation
555:           res << e << str{ss}
556:         end
557:         res
558:       end
ruleset() click to toggle source
     # File lib/sass/scss/parser.rb, line 305
305:       def ruleset
306:         return unless rules = selector_sequence
307:         block(node(Sass::Tree::RuleNode.new(rules.flatten.compact)), :ruleset)
308:       end
s(node) click to toggle source
    # File lib/sass/scss/parser.rb, line 60
60:       def s(node)
61:         while tok(S) || tok(CDC) || tok(CDO) || (c = tok(SINGLE_LINE_COMMENT)) || (c = tok(COMMENT))
62:           next unless c
63:           process_comment c, node
64:           c = nil
65:         end
66:         true
67:       end
sass_script(*args) click to toggle source
     # File lib/sass/scss/parser.rb, line 731
731:       def sass_script(*args)
732:         parser = self.class.sass_script_parser.new(@scanner, @line,
733:           @scanner.pos - (@scanner.string[0...@scanner.pos].rindex("\n") || 0))
734:         result = parser.send(*args)
735:         @line = parser.line
736:         result
737:       end
selector() click to toggle source
     # File lib/sass/scss/parser.rb, line 393
393:       def selector
394:         return unless sel = _selector
395:         sel.to_a
396:       end
selector_comma_sequence() click to toggle source
     # File lib/sass/scss/parser.rb, line 398
398:       def selector_comma_sequence
399:         return unless sel = _selector
400:         selectors = [sel]
401:         while tok(/,/)
402:           ws = str{ss}
403:           selectors << expr!(:_selector)
404:           selectors[1] = Selector::Sequence.new(["\n"] + selectors.last.members) if ws.include?("\n")
405:         end
406:         Selector::CommaSequence.new(selectors)
407:       end
selector_sequence() click to toggle source
     # File lib/sass/scss/parser.rb, line 377
377:       def selector_sequence
378:         if sel = tok(STATIC_SELECTOR)
379:           return [sel]
380:         end
381: 
382:         rules = []
383:         return unless v = selector
384:         rules.concat v
385: 
386:         while tok(/,/)
387:           rules << ',' << str {ss}
388:           rules.concat expr!(:selector)
389:         end
390:         rules
391:       end
simple_selector_sequence() click to toggle source
     # File lib/sass/scss/parser.rb, line 428
428:       def simple_selector_sequence
429:         # This allows for stuff like http://www.w3.org/TR/css3-animations/#keyframes-
430:         return expr unless e = element_name || id_selector || class_selector ||
431:           attrib || negation || pseudo || parent_selector || interpolation_selector
432:         res = [e]
433: 
434:         # The tok(/\*/) allows the "E*" hack
435:         while v = element_name || id_selector || class_selector ||
436:             attrib || negation || pseudo || interpolation_selector ||
437:             (tok(/\*/) && Selector::Universal.new(nil))
438:           res << v
439:         end
440: 
441:         if tok?(/&/)
442:           begin
443:             expected('"{"')
444:           rescue Sass::SyntaxError => e
445:             e.message << "\n\n" << In Sass 3, the parent selector & can only be used where element names are valid,since it could potentially be replaced by an element name.
446:             raise e
447:           end
448:         end
449: 
450:         Selector::SimpleSequence.new(res)
451:       end
special_directive(name) click to toggle source
     # File lib/sass/scss/parser.rb, line 128
128:       def special_directive(name)
129:         sym = name.gsub('-', '_').to_sym
130:         DIRECTIVES.include?(sym) && send("#{sym}_directive")
131:       end
ss() click to toggle source
    # File lib/sass/scss/parser.rb, line 69
69:       def ss
70:         nil while tok(S) || tok(SINGLE_LINE_COMMENT) || tok(COMMENT)
71:         true
72:       end
ss_comments(node) click to toggle source
    # File lib/sass/scss/parser.rb, line 74
74:       def ss_comments(node)
75:         while tok(S) || (c = tok(SINGLE_LINE_COMMENT)) || (c = tok(COMMENT))
76:           next unless c
77:           process_comment c, node
78:           c = nil
79:         end
80: 
81:         true
82:       end
str() click to toggle source
     # File lib/sass/scss/parser.rb, line 706
706:       def str
707:         @strs.push ""
708:         yield
709:         @strs.last
710:       ensure
711:         @strs.pop
712:       end
str?() click to toggle source
     # File lib/sass/scss/parser.rb, line 714
714:       def str?
715:         @strs.push ""
716:         yield && @strs.last
717:       ensure
718:         @strs.pop
719:       end
stylesheet() click to toggle source
    # File lib/sass/scss/parser.rb, line 55
55:       def stylesheet
56:         node = node(Sass::Tree::RootNode.new(@scanner.string))
57:         block_contents(node, :stylesheet) {s(node)}
58:       end
term() click to toggle source
     # File lib/sass/scss/parser.rb, line 643
643:       def term
644:         unless e = tok(NUMBER) ||
645:             tok(URI) ||
646:             function ||
647:             interp_string ||
648:             tok(UNICODERANGE) ||
649:             tok(IDENT) ||
650:             tok(HEXCOLOR) ||
651:             interpolation
652: 
653:           return unless op = unary_operator
654:           @expected = "number or function"
655:           return [op, tok(NUMBER) || expr!(:function)]
656:         end
657:         e
658:       end
tok(rx) click to toggle source
     # File lib/sass/scss/parser.rb, line 809
809:       def tok(rx)
810:         res = @scanner.scan(rx)
811:         if res
812:           @line += res.count("\n")
813:           @expected = nil
814:           if !@strs.empty? && rx != COMMENT && rx != SINGLE_LINE_COMMENT
815:             @strs.each {|s| s << res}
816:           end
817:         end
818: 
819:         res
820:       end
tok!(rx) click to toggle source
     # File lib/sass/scss/parser.rb, line 767
767:       def tok!(rx)
768:         (t = tok(rx)) && (return t)
769:         name = TOK_NAMES[rx]
770: 
771:         unless name
772:           # Display basic regexps as plain old strings
773:           string = rx.source.gsub(/\\(.)/, '\1')
774:           name = rx.source == Regexp.escape(string) ? string.inspect : rx.inspect
775:         end
776: 
777:         expected(name)
778:       end
tok?(rx) click to toggle source
     # File lib/sass/scss/parser.rb, line 758
758:       def tok?(rx)
759:         @scanner.match?(rx)
760:       end
unary_operator() click to toggle source
     # File lib/sass/scss/parser.rb, line 301
301:       def unary_operator
302:         tok(/[+-]/)
303:       end
use_css_import?() click to toggle source
     # File lib/sass/scss/parser.rb, line 230
230:       def use_css_import?; false; end
value!() click to toggle source
     # File lib/sass/scss/parser.rb, line 594
594:       def value!
595:         space = !str {ss}.empty?
596:         @use_property_exception ||= space || !tok?(IDENT)
597: 
598:         return true, Sass::Script::String.new("") if tok?(/\{/)
599:         # This is a bit of a dirty trick:
600:         # if the value is completely static,
601:         # we don't parse it at all, and instead return a plain old string
602:         # containing the value.
603:         # This results in a dramatic speed increase.
604:         if val = tok(STATIC_VALUE)
605:           return space, Sass::Script::String.new(val.strip)
606:         end
607:         return space, sass_script(:parse)
608:       end
variable() click to toggle source
     # File lib/sass/scss/parser.rb, line 283
283:       def variable
284:         return unless tok(/\$/)
285:         name = tok!(IDENT)
286:         ss; tok!(/:/); ss
287: 
288:         expr = sass_script(:parse)
289:         guarded = tok(DEFAULT)
290:         node(Sass::Tree::VariableNode.new(name, expr, guarded))
291:       end
warn_directive() click to toggle source
     # File lib/sass/scss/parser.rb, line 151
151:       def warn_directive
152:         node(Sass::Tree::WarnNode.new(sass_script(:parse)))
153:       end
while_directive() click to toggle source
     # File lib/sass/scss/parser.rb, line 172
172:       def while_directive
173:         expr = sass_script(:parse)
174:         ss
175:         block(node(Sass::Tree::WhileNode.new(expr)), :directive)
176:       end
whitespace() click to toggle source
    # File lib/sass/scss/parser.rb, line 84
84:       def whitespace
85:         return unless tok(S) || tok(SINGLE_LINE_COMMENT) || tok(COMMENT)
86:         ss
87:       end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.