Hello,

2011/10/4 Trans <transfire / gmail.com>:
> Yes, in fact #margin was born from the idea of %L. The downside of
> #margin is that it requires more processing overhead, where as the
> literal notation would be very fast (if it is possible to implement in
> Ruby parser).

Actually, I prefer %L, but didn't succeed to implement it.
It is difficult to determine the end of %L.
My patch requires an empty line at the end.
Though, nobu may be able to overcome the difficulty?


  $ cat t.rb
  p %L!foo
      !bar
      !b#{ ?a }z
  $ ./miniruby t.rb
  "foo\nbar\nbaz"

  $ cat t.rb
  p %L!foo
      !bar
      !b#{ ?a }z
  p 1
  $ ./miniruby t.rb
  t.rb:4: syntax error, unexpected tIDENTIFIER, expecting $end

  $ cat t.rb
  p %L!foo
      !bar
      !b#{ ?a }z

  p 1
  $ ./miniruby t.rb
  "foo\nbar\nbaz"
  1


diff --git a/parse.y b/parse.y
index 437f534..4165a09 100644
--- a/parse.y
+++ b/parse.y
@@ -5878,7 +5878,7 @@ parser_tokadd_string(struct parser_params *parser,
     } while (0)

     while ((c = nextc()) != -1) {
-	if (paren && c == paren) {
+	if (paren && c == paren && !(func & STR_FUNC_INDENT)) {
 	    ++*nest;
 	}
 	else if (c == term) {
@@ -5995,6 +5995,19 @@ parser_parse_string(struct parser_params
*parser, NODE *quote)
 	space = 1;
     }
     if (c == term && !quote->nd_nest) {
+	if (func & STR_FUNC_INDENT) {
+	    do {c = nextc();} while (c != term && ISSPACE(c));
+	    if (c != paren) {
+		lex_state = EXPR_BEG;
+		pushback(c);
+		if (!(func & STR_FUNC_REGEXP)) return tSTRING_END;
+		set_yylval_num(0);
+		return tREGEXP_END;
+	    }
+	    set_yylval_str(STR_NEW2("\n"));
+	    return tSTRING_CONTENT;
+	}
+	else {
 	if (func & STR_FUNC_QWORDS) {
 	    quote->nd_func = -1;
 	    return ' ';
@@ -6002,6 +6015,7 @@ parser_parse_string(struct parser_params
*parser, NODE *quote)
 	if (!(func & STR_FUNC_REGEXP)) return tSTRING_END;
         set_yylval_num(regx_options());
 	return tREGEXP_END;
+	}
     }
     if (space) {
 	pushback(c);
@@ -7563,9 +7577,14 @@ parser_yylex(struct parser_params *parser)
 	if (IS_BEG()) {
 	    int term;
 	    int paren;
+	    int indent;

 	    c = nextc();
 	  quotation:
+	    if (c == 'L') {
+		indent = STR_FUNC_INDENT;
+		c = nextc();
+	    }
 	    if (c == -1 || !ISALNUM(c)) {
 		term = c;
 		c = 'Q';
@@ -7587,14 +7606,18 @@ parser_yylex(struct parser_params *parser)
 	    else if (term == '{') term = '}';
 	    else if (term == '<') term = '>';
 	    else paren = 0;
+	    if (indent) {
+		paren = term;
+		term = '\n';
+	    }

 	    switch (c) {
 	      case 'Q':
-		lex_strterm = NEW_STRTERM(str_dquote, term, paren);
+		lex_strterm = NEW_STRTERM(str_dquote | indent, term, paren);
 		return tSTRING_BEG;

 	      case 'q':
-		lex_strterm = NEW_STRTERM(str_squote, term, paren);
+		lex_strterm = NEW_STRTERM(str_squote | indent, term, paren);
 		return tSTRING_BEG;

 	      case 'W':


-- 
Yusuke Endoh <mame / tsg.ne.jp>