#!/usr/bin/env ruby

arg = ARGV.pop


# Usage example:
#
#   ./etc/examples/generators/syntax.rb %Q > etc/examples/syntax/Q.rb
#
# then read the output file with 'foldlevel' 0

puts "# Generated by `" <<
     "./etc/examples/generators/syntax.rb #{arg}" <<
     " > etc/examples/syntax/#{arg.sub('%', '')}.rb" <<
     "`\n\n"



# %Q {{{
# Generalized Double Quoted String and Array of Strings and Shell Command Output
if arg == '%Q'
  # Note: %= is not matched here as the beginning of a double quoted string
  %Q[~`!@\#$%^&*_-+|:;"',.?/].split(//).each do |s|
    puts <<-END.gsub(/^\s{4}/, '')
      %#{s}
        foo
        \\#{s}
        \\\\\\#{s}
        bar
      #{s}


    END
  end

  %w(Q W x).each do |leading|
    %Q[~`!@\#$%^&*_-+=|:;"',.?/].split(//).each do |s|
      puts <<-END.gsub(/^\s{6}/, '')
        %#{leading}#{s}
          foo
          \\#{s}
          \\\\\\#{s}
          bar
        #{s}


      END
    end

    %w({} <> [] ()).each do |pair|
      puts <<-END.gsub(/^\s{6}/, '')
        %#{leading}#{pair[0]}
          foo
          \\#{pair[1]}
          \\\\\\#{pair[1]}
          bar
        #{pair[1]}


      END
    end

    puts "  %#{leading} foo\\ \\\\\\ bar\nbaz \n\n" unless leading == 'W'
  end
end
# }}}



# %q {{{
# Generalized Single Quoted String, Symbol and Array of Strings
if arg == '%q'
  %w(q w s).each do |leading|
    %Q[~`!@\#$%^&*_-+=|:;"',.?/].split(//).each do |s|
      puts <<-END.gsub(/^\s{6}/, '')
        %#{leading}#{s}
          foo
          \\#{s}
          \\\\\\#{s}
          bar
        #{s}


      END
    end

    %w({} <> [] ()).each do |pair|
      puts <<-END.gsub(/^\s{6}/, '')
        %#{leading}#{pair[0]}
          foo
          \\#{pair[1]}
          \\\\\\#{pair[1]}
          bar
        #{pair[1]}


      END
    end

    puts "  %#{leading} foo\\ \\\\\\ bar\nbaz \n\n" unless leading == 'w'
  end
end
# }}}



# %r {{{
# Generalized Regular Expression
if arg == '%r'
  %Q[~`!@\#$%^&*_-+=|:;"',.?/].split(//).each do |s|
    puts <<-END.gsub(/^\s{4}/, '')
      %r#{s}
        foo
        \\#{s}
        \\\\\\#{s}
        bar
      #{s}


    END
  end

  puts "  %r foo\\ \\\\\\ bar\nbaz \n\n"

  %w({} <> [] ()).each do |pair|
    puts <<-END.gsub(/^\s{4}/, '')
      %r#{pair[0]}
        foo
        \\#{pair[1]}
        \\\\\\#{pair[1]}
        bar
      #{pair[1]}


    END
  end
end
# }}}



# %i / %I {{{
# Array of Symbols
# Array of interpolated Symbols
if %w(%i %I).include?(arg)
  %w(i I).each do |leading|
    %Q[~`!@\#$%^&*_-+=|:;"',.?/].split(//).each do |s|
      puts <<-END.gsub(/^\s{6}/, '')
        %#{leading}#{s}
          foo
          \\#{s}
          \\\\\\#{s}
          bar
        #{s}


      END
    end

    %w({} <> [] ()).each do |pair|
      puts <<-END.gsub(/^\s{6}/, '')
        %#{leading}#{pair[0]}
          foo
          \\#{pair[1]}
          \\\\\\#{pair[1]}
          bar
        #{pair[1]}


      END
    end
  end
end
# }}}



# string  {{{
# Normal String and Shell Command Output
if arg == 'string'
  %w(' " `).each do |quote|
    puts <<-END.gsub(/^\s{4}/, '')
      #{quote}
        foo
        \\#{quote}
        \\\\\\#{quote}
        bar
      #{quote}


    END
  end
end
# }}}



# regex (Normal Regular Expression) {{{
if arg == 'regexp'
  'iomxneus'.split('').unshift('').each do |option|
    puts "\n# Begin test for option '#{option}' {{{\n\n"

    puts <<-END.gsub(/^\s{4}/, '')
        /
          foo
          \\\/
          \\\\\\\/
          bar
        /#{option}


    END

    %w(and or while until unless if elsif when not then else).each do |s|
      puts <<-END.gsub(/^\s{6}/, '')
        #{s}/
          foo
          \\\/
          \\\\\\\/
          bar
        /#{option}


      END
    end

    %w(; \ ~ = ! | \( & , { [ < > ? : * + -).each do |s|
      puts <<-END.gsub(/^\s{6}/, '')
        #{s}/
          foo
          \\\/
          \\\\\\\/
          bar
        /#{option}


      END
    end

    [' ', "\t", '=', 'OK'].each do |s|
      puts <<-END.gsub(/^\s{6}/, '')
        _foo  /#{s}
          foo
          \\\/
          \\\\\\\/
          bar
        /#{option}


      END
    end

    puts "# }}} End test for option '#{option}'\n"
  end

  puts "\n# Test for ternary operation (8c1c484) {{{\n\n"
  puts 'yo = 4 ? /quack#{3}/ : /quack/'
  puts "\n# }}} End test for ternary operation\n"
end
# }}}



# symbol {{{
# Symbol region
if arg == 'symbol'
  %w(' ").each do |quote|
    %Q_]})\"':_.split(//).unshift('').each do |s|
      puts <<-END.gsub(/^\s{6}/, '')
        #{s}:#{quote}
          foo
          \\#{quote}
          \\\\\\#{quote}
          bar
        #{quote}
      #{"  #{s} # close string to ensure next case clean" if %w(' ").include?(s) && s != quote }


      END
    end
  end
end
# }}}



# heredoc {{{
# Here Documents
if arg == 'heredoc'
  puts "\n# Begin of valid cases {{{\n\n"

  %w(' " `).unshift('').each do |quote|
    puts <<-END.gsub(/^\s{6}/, '')
        <<#{quote}_LABEL#{quote}.?!, foo
          bar baz
      _LABEL
      \n

        <<-#{quote}_LABEL#{quote}.?!, foo
          bar baz
        _LABEL
      \n

          <<~#{quote}_LABEL#{quote}.?!, foo
            bar baz
          _LABEL


    END
  end

  puts "# }}} End of valid cases'\n\n"


  puts "\n# Begin of INVALID cases {{{\n\n"

  # NOTE: for simplification, omit test for different quotes " ' `,
  # they are all invalid anyway

  %w(class ::).each do |s|
    puts <<-END.gsub(/^\s{6}/, '')
      #{s}\n <<LABEL
        foo
      LABEL


    END
  end

  %Q_]})\"'._.split(//).each do |s|
    puts <<-END.gsub(/^\s{4}/, '')
    #{s} <<LABEL
      foo
    LABEL
    #{"  #{s} # close to ensure next case clean" if %w(' ").include?(s)}

    END
  end

  %w(09 aZ _w).each do |s|
    puts <<-END.gsub(/^\s{6}/, '')
      #{s}<<LABEL
        foo
      LABEL


    END
  end

  %w(' " `).unshift('').each do |quote|
    puts <<-END.gsub(/^\s{6}/, '')
      <<LABEL foo<<#{quote}_bar
        baz
      LABEL
      #{"  #{quote} # close to ensure next case clean" if %w(' ").include?(quote)}
      \n

      <<LABEL foo<<-#{quote}_bar
        baz
      LABEL
      #{"  #{quote} # close to ensure next case clean" if %w(' ").include?(quote)}


    END
  end

  puts "# }}} End of INVALID cases'\n\n"
end
# }}}



# blocks  {{{
# simple blocks (def, class, module, do, begin, case)
if arg == 'blocks'
  puts <<-END.gsub(/^\s{4}/, '')
    def
      foo
      def
        bar
      end
    end


  END

  %w(class module do begin case).each do |s|
    puts <<-END.gsub(/^\s{6}/, '')
      #{s}
        foo
      end


    END
  end
end
# }}}



# brackets  {{{
# curly bracket block and hash literal
if arg == 'brackets'
  puts <<-END.gsub(/^\s{4}/, '')
    {
      foo
    }


  END

  %w<_xxx ] } )>.unshift('').each do |s|
    puts <<-END.gsub(/^\s{6}/, '')
      #{s}[
        foo
      ]


    END
  end
end
# }}}



# if {{{
# if/else blocks
if arg == 'if'
  %w(if unless).each do |start|
    puts <<-END.gsub(/^ {6}/, '')
      #{start} 1
        foo
      else
        bar
      end

      foo \\
        #{start} 1
          foo
        else
          bar
        end

      baz ...= #{start} 1
        foo
      else
        bar
      end


    END

    ['?', '!'].each do |mark|
      puts <<-END.gsub(/^ {8}/, '')
        42foo#{mark} #{start} 1
          bar
        else
          baz
        end


      END
    end

    '{:,;([<>~\*%&^|+=-'.split(//).each do |expr|
      puts <<-END.gsub(/^ {8}/, '')
        foo #{expr} #{start} 1
          bar
        else
          baz
        end


      END
    end

    # c7cb532 match correct `end`
    puts <<-END.gsub(/^ {6}/, '')
      #{start} 1
        (1..5).end
        :: end
      end

      #{start} 1
      ..end


    END

    # INVALID cases
    puts <<-END.gsub(/^ {6}/, '')
      not_BOF #{start} 1
        bar
      else
        baz
      end


    END

    ['?', '!'].each do |mark|
      puts <<-END.gsub(/^ {8}/, '')
        _foo#{mark} #{start} 1
          bar
        else
          baz
        end


      END
    end
  end
end
# }}}



# for {{{
# rubyRepeatExpression (for, while, until)
if arg == 'for'
  puts <<-END.gsub(/^ {4}/, '')
    for 1
      foo
    end


  END

  %w(until while).each do |start|
    puts <<-END.gsub(/^ {6}/, '')
      #{start} 1
        foo
      end


      baz ...= #{start} 1
        foo
      end


    END

    '{:,;([<>~\*/%&^|+-'.split(//).each do |expr|
      puts <<-END.gsub(/^ {8}/, '')
        foo #{expr} #{start} 1
          bar
        end


      END
    end

    # INVALID cases
    puts <<-END.gsub(/^ {6}/, '')
      not_BOF #{start} 1
        bar
      end


    END

    ['?', '!'].each do |mark|
      puts <<-END.gsub(/^ {8}/, '')
        _foo#{mark} #{start} 1
          bar
        end


      END
    end
  end
end
# }}}



# comment {{{
if arg == 'comment'
  puts <<-END.gsub(/^ {4}/, '')
      # foo
      # foo
        # bar

      baz



    =begin foo bar
      comment
    =end baz


  END
end
# }}}



# __END__ {{{
if arg == '__END__'
  puts <<-EOF.gsub(/^ {4}/, '')
      __END__
      invalid
      invalid


    __END__
      valid
      valid


  EOF
end
# }}}



puts "#\svim:foldmethod=syntax"


# vim:foldmethod=marker