Skip to content

Commit

Permalink
Change to list attributes so you can give style/class to list items (…
Browse files Browse the repository at this point in the history
…taken from PyTextile). Breaks backwards compatibility.
  • Loading branch information
jgarber committed May 22, 2009
1 parent a68d5f7 commit 1a45c0c
Show file tree
Hide file tree
Showing 9 changed files with 175 additions and 44 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG
@@ -1,5 +1,16 @@
=== Edge

* Change to list attributes so you can give style/class to list items (taken from PyTextile). Breaks backwards compatibility.

Before, the style applied to the first list item applied to the entire list. Now, class/id/style placed
before the list applies to the list element and after the hash or asterisk applies to the list item. For
example:
<ul id="groceries">
(#groceries)# Milk <li>milk</li>
# Eggs <li>eggs</li>
#(optional) granola <li class="optional">granola</li>
</ul>

* Separated attributes out to have their own mark/store variable and regs. This way, they won't conflict with captured text or backtracked text. [Jason Garber]

* Added a RedCloth::EXTENSION_LANGUAGE constant so you can tell what version of the parser you are using. [Jason Garber]
Expand Down
2 changes: 1 addition & 1 deletion ext/redcloth_scan/redcloth_attributes.rl
Expand Up @@ -7,7 +7,7 @@

machine redcloth_attributes;

C2 = ( C_CLAS | C_STYL | C_LNGE )+ ;
C2 = ( C_CLASS_ID | C_STYL | C_LNGE )+ ;

mtext_with_attributes = ( C2 mtext >A %T ) >X ;

Expand Down
11 changes: 10 additions & 1 deletion ext/redcloth_scan/redcloth_common.rb.rl
@@ -1,7 +1,6 @@
%%{

machine redcloth_common;
include redcloth_common "redcloth_common.rl";

action esc { rb_str_cat_escaped(@block, @ts, @te); }
action esc_pre { rb_str_cat_escaped_for_preformatted(@block, STR_NEW(@ts, @te-@ts)); }
Expand All @@ -16,5 +15,15 @@
}
action extended { !@extend.nil? }
action not_extended { @extend.nil? }
action following_hash_is_ol_not_id {
if @data[(@p+1), 1] == "#"
@data[(@p+2), 1] == "#" || @data[(@p+2), 1] == "*" || @data[(@p+2), 1] == " "
else
true
end
}


include redcloth_common "redcloth_common.rl";

}%%;
15 changes: 10 additions & 5 deletions ext/redcloth_scan/redcloth_common.rl
Expand Up @@ -20,12 +20,14 @@
A_RIGHT = ">" %{ ATTR_SET("align", "right"); } ;
A_JUSTIFIED = "<>" %{ ATTR_SET("align", "justify"); } ;
A_CENTER = "=" %{ ATTR_SET("align", "center"); } ;
A_PADLEFT = "(" %{ ATTR_INC("padding-left"); } ;
A_PADLEFT = "(" when following_hash_is_ol_not_id %{ ATTR_INC("padding-left"); } ;
A_PADRIGHT = ")" %{ ATTR_INC("padding-right"); } ;
A_HLGN = ( A_LEFT | A_RIGHT | A_JUSTIFIED | A_CENTER | A_PADLEFT | A_PADRIGHT ) ;
A_LIMIT = ( A_LEFT | A_CENTER | A_RIGHT ) ;
A_VLGN = ( "-" %{ ATTR_SET("vertical-align", "middle"); } | "^" %{ ATTR_SET("vertical-align", "top"); } | "~" %{ ATTR_SET("vertical-align", "bottom"); } ) ;
C_CLAS = ( "(" ( [^)#]+ >ATTR %{ STORE_ATTR("class"); } )? ("#" [^)]+ >ATTR %{STORE_ATTR("id");} )? ")" ) ;
C_CLASS = [^()#]+ >ATTR %{ STORE_ATTR("class"); } ;
C_ID = "#" [^) ]+ >ATTR %{STORE_ATTR("id");} ;
C_CLASS_ID = "(" ( C_CLASS | C_ID | C_CLASS C_ID ) ")" ;
C_LNGE = ( "[" [^\]]+ >ATTR %{ STORE_ATTR("lang"); } "]" ) ;
C_STYL = ( "{" [^}]+ >ATTR %{ STORE_ATTR("style"); } "}" ) ;
S_CSPN = ( "\\" [0-9]+ >ATTR %{ STORE_ATTR("colspan"); } ) ;
Expand All @@ -34,7 +36,7 @@
A = ( ( A_HLGN | A_VLGN )* ) ;
A2 = ( A_LIMIT? ) ;
S = ( S_CSPN | S_RSPN )* ;
C = ( C_CLAS | C_STYL | C_LNGE )* ;
C = ( C_CLASS_ID | C_STYL | C_LNGE )* ;
D = ( D_HEADER ) ;
N_CONT = "_" %{ ATTR_SET("list_continue", "true"); };
N_NUM = digit+ >ATTR %{ STORE_ATTR("start"); };
Expand All @@ -52,12 +54,15 @@
A_PADRIGHT_noactions = ")" ;
A_HLGN_noactions = ( A_LEFT_noactions | A_RIGHT_noactions | A_JUSTIFIED_noactions | A_CENTER_noactions | A_PADLEFT_noactions | A_PADRIGHT_noactions ) ;
A_VLGN_noactions = ( "-" | "^" | "~" ) ;
C_CLAS_noactions = ( "(" ( [^)#]+ )? ("#" [^)]+ )? ")" ) ;
C_CLASS_noactions = ( "(" ( [^)#]+ )? ("#" [^)]+ )? ")" ) ;
C_LNGE_noactions = ( "[" [^\]]+ "]" ) ;
C_STYL_noactions = ( "{" [^}]+ "}" ) ;
A_noactions = ( ( A_HLGN_noactions | A_VLGN_noactions )* ) ;
C_noactions = ( C_CLAS_noactions | C_STYL_noactions | C_LNGE_noactions )* ;
C_noactions = ( C_CLASS_noactions | C_STYL_noactions | C_LNGE_noactions )* ;
C_noquotes_noactions = C_noactions -- '"' ;
N_CONT_noactions = "_" ;
N_NUM_noactions = digit+ ;
N_noactions = ( N_CONT_noactions | N_NUM_noactions )? ;

# text blocks
trailing = PUNCT - ("'" | '"') ;
Expand Down
9 changes: 6 additions & 3 deletions ext/redcloth_scan/redcloth_scan.rb.rl
Expand Up @@ -216,7 +216,7 @@ module RedCloth
end
end
def STORE_ATTR(t)
if (@attr_reg && @p > @attr_reg && @attr_reg >= @ts)
if (@attr_reg && @p > @attr_reg && (@attr_reg >= (@ts || 0)))
str = @data[@attr_reg, @p - @attr_reg]
@attr_regs[t.to_sym] = str
# /*printf("STORE_B(" T ") '%s' (p:'%s' reg:'%s')\n", RSTRING_PTR(str), p, reg);*/ \
Expand Down Expand Up @@ -274,14 +274,15 @@ module RedCloth
def RESET_NEST()
@nest = 0
end
def LIST_ITEM_OPEN()
def LIST_LAYOUT()
aint = 0
aval = @list_index[@nest-1]
aint = aval.to_i unless aval.nil?
if (@list_type == "ol")
if (@list_type == "ol" && @nest > 0)
@list_index[@nest-1] = aint + 1
end
if (@nest > @list_layout.length)
SET_ATTRIBUTES();
listm = sprintf("%s_open", @list_type)
if (@regs[:list_continue])
@regs[:list_continue] = nil
Expand All @@ -302,6 +303,8 @@ module RedCloth
ASET("first", true)
end
LIST_CLOSE()
LIST_ITEM_CLOSE() unless @nest == 0
CLEAR_REGS()
@regs[:nest] = @list_layout.length
ASET("type", "li_open")
end
Expand Down
23 changes: 14 additions & 9 deletions ext/redcloth_scan/redcloth_scan.rl
Expand Up @@ -27,9 +27,10 @@
footnote_start = ( ftype A C :> dotspace ) %SET_ATTR ;
ul = "*" %{NEST(); SET_LIST_TYPE("ul");};
ol = "#" %{NEST(); SET_LIST_TYPE("ol");};
ul_start = ( ul | ol )* ul A C :> " "+ %SET_ATTR;
ol_start = ( ul | ol )* ol N A C :> " "+ %SET_ATTR ;
list_start = " "* ( ul_start | ol_start ) >{RESET_NEST();} ;
ul_start = ( ul | ol )* ul A_noactions C_noactions :> " "+ ;
ol_start = ( ul | ol )* ol N A_noactions C_noactions :> " "+ ;
list_start = " "* A C ( ul_start | ol_start ) >B >{RESET_NEST();} @{ fexec(bck); } ;

dt_start = "-" . " "+ ;
dd_start = ":=" ;
long_dd = dd_start " "* LF %{ ADD_BLOCK(); ASET("type", "dd"); } any+ >A %{ TRANSFORM("text"); } :>> "=:" ;
Expand Down Expand Up @@ -134,7 +135,7 @@
double_return next_block_start when not_extended { ADD_BLOCK(); fgoto main; };
html_end_terminating_block when extended { ADD_EXTENDED_BLOCK(); END_EXTENDED(); fgoto main; };
html_end_terminating_block when not_extended { ADD_BLOCK(); fgoto main; };
LF list_start { ADD_BLOCK(); CLEAR_LIST(); LIST_ITEM_OPEN(); fgoto list; };
LF list_start { ADD_BLOCK(); CLEAR_LIST(); LIST_LAYOUT(); fgoto list_item; };

default => cat;
*|;
Expand All @@ -143,10 +144,14 @@
block_end { ADD_BLOCK(); fgoto main; };
default => cat;
*|;

list := |*
LF list_start { LIST_ITEM_CLOSE(); ADD_BLOCK(); LIST_ITEM_OPEN(); };
block_end { LIST_ITEM_CLOSE(); ADD_BLOCK(); RESET_NEST(); LIST_CLOSE(); fgoto main; };

ul_item = ( ul | ol )* ul A C :> " "+ ;
ol_item = ( ul | ol )* ol N_noactions A C :> " "+ ;
list_item := (" "* ( ul_item | ol_item )) @{ SET_ATTRIBUTES(); fgoto list_content; } ;

list_content := |*
LF list_start { ADD_BLOCK(); LIST_LAYOUT(); fgoto list_item; };
block_end { ADD_BLOCK(); RESET_NEST(); LIST_LAYOUT(); fgoto main; };
default => cat;
*|;

Expand All @@ -172,7 +177,7 @@
block_start { fgoto block; };
footnote_start { fgoto footnote; };
horizontal_rule { INLINE(html, "hr"); };
list_start { CLEAR_LIST(); LIST_ITEM_OPEN(); fgoto list; };
list_start { CLEAR_LIST(); LIST_LAYOUT(); fgoto list_item; };
dl_start { fexec(ts + 1); INLINE(html, "dl_open"); ASET("type", "dt"); fgoto dl; };
table { INLINE(table, "table_close"); DONE(table); fgoto block; };
link_alias { STORE_LINK_ALIAS(); DONE(block); };
Expand Down
131 changes: 121 additions & 10 deletions spec/fixtures/lists.yml
Expand Up @@ -306,10 +306,10 @@ in: |-
*(class-two) two
*(class-three) three
html: |-
<ul class="class-one">
<li>one</li>
<li>two</li>
<li>three</li>
<ul>
<li class="class-one">one</li>
<li class="class-two">two</li>
<li class="class-three">three</li>
</ul>
---
name: unordered with alignments
Expand All @@ -319,11 +319,11 @@ in: |-
*<> three
*= four
html: |-
<ul style="text-align:left;">
<li>one</li>
<li>two</li>
<li>three</li>
<li>four</li>
<ul>
<li style="text-align:left;">one</li>
<li style="text-align:right;">two</li>
<li style="text-align:justify;">three</li>
<li style="text-align:center;">four</li>
</ul>
---
name: with attributes that apply to the whole list
Expand All @@ -338,6 +338,42 @@ html: |-
<li>three</li>
</ol>
---
name: with id on the list
in: |-
(#my-id)# one
# two
# three
html: |-
<ol id="my-id">
<li>one</li>
<li>two</li>
<li>three</li>
</ol>
---
name: with class on the list
in: |-
(my-class)# one
# two
# three
html: |-
<ol class="my-class">
<li>one</li>
<li>two</li>
<li>three</li>
</ol>
---
name: with id on the list item
in: |-
# one
#(#my-item) two
# three
html: |-
<ol>
<li>one</li>
<li id="my-item">two</li>
<li>three</li>
</ol>
---
name: with attributes that apply to the first list item
in: |-
#(class#id) one
Expand All @@ -348,4 +384,79 @@ html: |-
<li class="class" id="id">one</li>
<li>two</li>
<li>three</li>
</ol>
</ol>
---
name: changed from textism basics
desc: "This was in Textism basics, but when I changed the format of list styles, I removed it"
in: |-
{color:blue}# one
# two
# three
html: |-
<ol style="color:blue;">
<li>one</li>
<li>two</li>
<li>three</li>
</ol>
---
name: changed from threshold list attributes
desc: "Was: 'Attributes applied to the first list item will apply to the list itself.' but then we changed it"
in: |-
*{color:red} Item one
* Item two
* Item three
html: |-
<ul>
<li style="color:red;">Item one</li>
<li>Item two</li>
<li>Item three</li>
</ul>
---
name: with one padding-left increment
in: "(# one"
html: |-
<ol style="padding-left:1em;">
<li>one</li>
</ol>
---
name: with one padding-left increment and class
in: "((myclass)# one"
html: |-
<ol style="padding-left:1em;" class="myclass">
<li>one</li>
</ol>
---
name: with two padding-left increments
in: "((# two"
html: |-
<ol style="padding-left:2em;">
<li>two</li>
</ol>
---
name: with one padding-right increment
in: ")# one"
html: |-
<ol style="padding-right:1em;">
<li>one</li>
</ol>
---
name: with padding-left and padding-right increments
in: "()# two"
html: |-
<ol style="padding-left:1em;padding-right:1em;">
<li>two</li>
</ol>
---
name: with padding-left and padding-right increments switched
in: ")(# two"
html: |-
<ol style="padding-left:1em;padding-right:1em;">
<li>two</li>
</ol>
---
name: with padding-left and padding-right increments and class
in: "()(myclass)# two"
html: |-
<ol style="padding-left:1em;padding-right:1em;" class="myclass">
<li>two</li>
</ol>
4 changes: 2 additions & 2 deletions spec/fixtures/textism.yml
Expand Up @@ -282,7 +282,7 @@ in: |-
Simple list:
#{color:blue} one
# one
# two
# three
Expand All @@ -305,7 +305,7 @@ html: |-
<p lang="fr">This is a block quote. I&#8217;ll admit it&#8217;s not the most exciting block quote ever devised.</p>
</blockquote>
<p>Simple list:</p>
<ol style="color:blue;">
<ol>
<li>one</li>
<li>two</li>
<li>three</li>
Expand Down
13 changes: 0 additions & 13 deletions spec/fixtures/threshold.yml
Expand Up @@ -565,19 +565,6 @@ html: |-
<li>Item C</li>
</ul>
---
name: list attributes
desc: Attributes applied to the first list item will apply to the list itself.
in: |-
*{color:red} Item one
* Item two
* Item three
html: |-
<ul style="color:red;">
<li>Item one</li>
<li>Item two</li>
<li>Item three</li>
</ul>
---
name: nested lists
desc: Use multiple # or * symbols to create nested lists.
in: |-
Expand Down

0 comments on commit 1a45c0c

Please sign in to comment.