diff --git a/CHANGELOG b/CHANGELOG
index 155b5912..69af5b10 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,7 @@
=== Edge
+* 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]
* Added a NotCompiledError to give a friendlier message when people just unpack RedCloth into their projects. [Jason Garber]
diff --git a/Rakefile b/Rakefile
index 018af256..3cdcfbfa 100644
--- a/Rakefile
+++ b/Rakefile
@@ -121,10 +121,12 @@ def ragel(target_file, source_file)
preferred_code_style = case host_language
when "R"
"F1"
- else
+ when "C"
"T0"
+ else
+ nil
end
- code_style = " -" + (@code_style || preferred_code_style)
+ code_style = preferred_code_style ? " -" + (@code_style || preferred_code_style) : ""
ensure_ragel_version(target_file) do
sh %{ragel #{source_file} -#{host_language}#{code_style} -o #{target_file}}
end
@@ -216,11 +218,12 @@ end
require 'rubygems'
require 'spec/rake/spectask'
Rake::Task[:default].prerequisites.clear
-Spec::Rake::SpecTask.new(:default) do |t|
- t.spec_opts = ["--color", "--require=spec/differs/inline.rb", "--diff=RedClothDiffers::Inline"]
+Spec::Rake::SpecTask.new do |t|
+ t.spec_opts = ["--options #{File.dirname(__FILE__) + '/spec/spec.opts'}"]
t.spec_files = FileList['spec/**/*_spec.rb']
end
+task :default => :spec
task :spec => [:compile]
task :remove_other_platforms do
diff --git a/ext/redcloth_scan/redcloth.h b/ext/redcloth_scan/redcloth.h
index 7a6e75ae..67f5396e 100644
--- a/ext/redcloth_scan/redcloth.h
+++ b/ext/redcloth_scan/redcloth.h
@@ -49,10 +49,11 @@ VALUE red_pass(VALUE, VALUE, VALUE, ID, VALUE);
VALUE red_pass_code(VALUE, VALUE, VALUE, ID);
/* parser macros */
-#define CLEAR_REGS() regs = rb_hash_new();
+#define CLEAR_REGS() regs = rb_hash_new(); attr_regs = rb_hash_new();
#define RESET_REG() reg = NULL
#define MARK() reg = p;
#define MARK_B() bck = p;
+#define MARK_ATTR() attr_reg = p;
#define CAT(H) rb_str_cat(H, ts, te-ts)
#define CLEAR(H) H = STR_NEW2("")
#define RSTRIP_BANG(H) rb_funcall(H, rb_intern("rstrip!"), 0)
@@ -75,13 +76,16 @@ VALUE red_pass_code(VALUE, VALUE, VALUE, ID);
#define ADD_BLOCKCODE() rb_str_append(html, red_blockcode(self, regs, block)); CLEAR(block); CLEAR_REGS()
#define ADD_EXTENDED_BLOCKCODE() rb_str_append(html, red_blockcode(self, regs, block)); CLEAR(block);
#define ASET(T, V) rb_hash_aset(regs, ID2SYM(rb_intern(T)), STR_NEW2(V));
-#define AINC(T) red_inc(regs, ID2SYM(rb_intern(T)));
+#define ATTR_SET(T, V) rb_hash_aset(attr_regs, ID2SYM(rb_intern(T)), STR_NEW2(V));
+#define ATTR_INC(T) red_inc(attr_regs, ID2SYM(rb_intern(T)));
#define INC(N) N++;
#define SET_ATTRIBUTES() \
SET_ATTRIBUTE("class_buf", "class"); \
SET_ATTRIBUTE("id_buf", "id"); \
SET_ATTRIBUTE("lang_buf", "lang"); \
- SET_ATTRIBUTE("style_buf", "style");
+ SET_ATTRIBUTE("style_buf", "style"); \
+ rb_funcall(regs, rb_intern("merge!"), 1, attr_regs); \
+ attr_regs = rb_hash_new();
#define SET_ATTRIBUTE(B, A) \
if (rb_hash_aref(regs, ID2SYM(rb_intern(B))) != Qnil) rb_hash_aset(regs, ID2SYM(rb_intern(A)), rb_hash_aref(regs, ID2SYM(rb_intern(B))));
#define TRANSFORM(T) \
@@ -108,6 +112,15 @@ VALUE red_pass_code(VALUE, VALUE, VALUE, ID);
} else { \
rb_hash_aset(regs, ID2SYM(rb_intern(T)), Qnil); \
}
+#define STORE_ATTR(T) \
+ if (p > attr_reg && attr_reg >= ts) { \
+ VALUE str = STR_NEW(attr_reg, p-attr_reg); \
+ rb_hash_aset(attr_regs, ID2SYM(rb_intern(T)), str); \
+ /*printf("STORE_B(" T ") '%s' (p:'%s' reg:'%s')\n", RSTRING_PTR(str), p, reg);*/ \
+ } else { \
+ rb_hash_aset(attr_regs, ID2SYM(rb_intern(T)), Qnil); \
+ }
+
#define STORE_URL(T) \
if (p > reg && reg >= ts) { \
char punct = 1; \
diff --git a/ext/redcloth_scan/redcloth_attributes.c.rl b/ext/redcloth_scan/redcloth_attributes.c.rl
index 23dcf820..2bbc1b1c 100644
--- a/ext/redcloth_scan/redcloth_attributes.c.rl
+++ b/ext/redcloth_scan/redcloth_attributes.c.rl
@@ -24,8 +24,9 @@ redcloth_attribute_parser(machine, self, p, pe)
char *p, *pe;
{
int cs, act;
- char *ts = 0, *te = 0, *reg = 0, *bck = NULL, *eof = NULL;
+ char *ts = 0, *te = 0, *reg = 0, *bck = NULL, *attr_reg = NULL, *eof = NULL;
VALUE regs = rb_hash_new();
+ VALUE attr_regs = rb_hash_new();
%% write init;
diff --git a/ext/redcloth_scan/redcloth_attributes.java.rl b/ext/redcloth_scan/redcloth_attributes.java.rl
index ca47c896..16ee83a0 100644
--- a/ext/redcloth_scan/redcloth_attributes.java.rl
+++ b/ext/redcloth_scan/redcloth_attributes.java.rl
@@ -35,19 +35,6 @@ public class RedclothAttributes extends RedclothScanService.Base {
%% write data nofinal;
- public void SET_ATTRIBUTES() {
- SET_ATTRIBUTE("class_buf", "class");
- SET_ATTRIBUTE("id_buf", "id");
- SET_ATTRIBUTE("lang_buf", "lang");
- SET_ATTRIBUTE("style_buf", "style");
- }
-
- public void SET_ATTRIBUTE(String B, String A) {
- if(!((RubyHash)regs).aref(runtime.newSymbol(B)).isNil()) {
- ((RubyHash)regs).aset(runtime.newSymbol(A), ((RubyHash)regs).aref(runtime.newSymbol(B)));
- }
- }
-
private int machine;
public RedclothAttributes(int machine, IRubyObject self, byte[] data, int p, int pe) {
@@ -66,6 +53,7 @@ public class RedclothAttributes extends RedclothScanService.Base {
this.orig_pe = this.pe;
this.regs = RubyHash.newHash(runtime);
+ this.attr_regs = RubyHash.newHash(runtime);
this.machine = machine;
}
diff --git a/ext/redcloth_scan/redcloth_attributes.rb.rl b/ext/redcloth_scan/redcloth_attributes.rb.rl
index 311fba13..eb17ddfe 100644
--- a/ext/redcloth_scan/redcloth_attributes.rb.rl
+++ b/ext/redcloth_scan/redcloth_attributes.rb.rl
@@ -25,6 +25,7 @@ module RedCloth
def redcloth_attribute_parser(cs, data)
@data = data + "\0"
@regs = {}
+ @attr_regs = {}
@p = 0
@pe = @data.length
diff --git a/ext/redcloth_scan/redcloth_attributes.rl b/ext/redcloth_scan/redcloth_attributes.rl
index b99e7f77..8bb8a960 100644
--- a/ext/redcloth_scan/redcloth_attributes.rl
+++ b/ext/redcloth_scan/redcloth_attributes.rl
@@ -7,10 +7,7 @@
machine redcloth_attributes;
- C2_CLAS = ( "(" ( [^)#]+ >A %{ STORE("class_buf"); } )? ("#" [^)]+ >A %{STORE("id_buf");} )? ")" ) ;
- C2_LNGE = ( "[" [^\[\]]+ >A %{ STORE("lang_buf"); } "]" ) ;
- C2_STYL = ( "{" [^}]+ >A %{ STORE("style_buf"); } "}" ) ;
- C2 = ( C2_CLAS | C2_STYL | C2_LNGE )+ ;
+ C2 = ( C_CLAS | C_STYL | C_LNGE )+ ;
mtext_with_attributes = ( C2 mtext >A %T ) >X ;
diff --git a/ext/redcloth_scan/redcloth_common.rl b/ext/redcloth_scan/redcloth_common.rl
index 9232a1bf..1d61d7e3 100644
--- a/ext/redcloth_scan/redcloth_common.rl
+++ b/ext/redcloth_scan/redcloth_common.rl
@@ -4,6 +4,8 @@
action A { MARK(); }
action B { MARK_B(); }
+ action ATTR { MARK_ATTR(); }
+ action SET_ATTR { SET_ATTRIBUTES(); }
action T { STORE("text"); }
action X { CLEAR_REGS(); RESET_REG(); }
action cat { CAT(block); }
@@ -13,29 +15,29 @@
default = ^0 ;
EOF = 0 ;
- # textile modifiers
- A_LEFT = "<" %{ ASET("align", "left"); } ;
- A_RIGHT = ">" %{ ASET("align", "right"); } ;
- A_JUSTIFIED = "<>" %{ ASET("align", "justify"); } ;
- A_CENTER = "=" %{ ASET("align", "center"); } ;
- A_PADLEFT = "(" >A %{ AINC("padding-left"); } ;
- A_PADRIGHT = ")" >A %{ AINC("padding-right"); } ;
+ # textile element attributes
+ A_LEFT = "<" %{ ATTR_SET("align", "left"); } ;
+ 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_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 = ( "-" %{ ASET("vertical-align", "middle"); } | "^" %{ ASET("vertical-align", "top"); } | "~" %{ ASET("vertical-align", "bottom"); } ) ;
- C_CLAS = ( "(" ( [^)#]+ >A %{ STORE("class"); } )? ("#" [^)]+ >A %{STORE("id");} )? ")" ) ;
- C_LNGE = ( "[" [^\]]+ >A %{ STORE("lang"); } "]" ) ;
- C_STYL = ( "{" [^}]+ >A %{ STORE("style"); } "}" ) ;
- S_CSPN = ( "\\" [0-9]+ >A %{ STORE("colspan"); } ) ;
- S_RSPN = ( "/" [0-9]+ >A %{ STORE("rowspan"); } ) ;
- D_HEADER = "_" %{ ASET("th", "true"); } ;
+ 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_LNGE = ( "[" [^\]]+ >ATTR %{ STORE_ATTR("lang"); } "]" ) ;
+ C_STYL = ( "{" [^}]+ >ATTR %{ STORE_ATTR("style"); } "}" ) ;
+ S_CSPN = ( "\\" [0-9]+ >ATTR %{ STORE_ATTR("colspan"); } ) ;
+ S_RSPN = ( "/" [0-9]+ >ATTR %{ STORE_ATTR("rowspan"); } ) ;
+ D_HEADER = "_" %{ ATTR_SET("th", "true"); } ;
A = ( ( A_HLGN | A_VLGN )* ) ;
A2 = ( A_LIMIT? ) ;
S = ( S_CSPN | S_RSPN )* ;
C = ( C_CLAS | C_STYL | C_LNGE )* ;
D = ( D_HEADER ) ;
- N_CONT = "_" %{ ASET("list_continue", "true"); };
- N_NUM = digit+ >A %{ STORE("start"); };
+ N_CONT = "_" %{ ATTR_SET("list_continue", "true"); };
+ N_NUM = digit+ >ATTR %{ STORE_ATTR("start"); };
N = ( N_CONT | N_NUM )? ;
PUNCT = ( "!" | '"' | "#" | "$" | "%" | "&" | "'" | "," | "-" | "." | "/" | ":" | ";" | "=" | "?" | "\\" | "^" | "`" | "|" | "~" | "[" | "]" | "(" | ")" | "<" ) ;
dotspace = ("." " "*) ;
@@ -106,7 +108,7 @@
uri = (target | absolute_uri | absolute_path | rel_path) ;
# common
- title = ( '(' default+ >A %{ STORE("title"); } :> ')' ) ;
+ title = ( '(' default+ >ATTR %{ STORE_ATTR("title"); } :> ')' ) ;
word = ( alnum | safe | " " ) ;
mspace = ( ( " " | "\t" | LF )+ ) -- LF{2} ;
mtext = ( chars (mspace chars)* ) ;
diff --git a/ext/redcloth_scan/redcloth_inline.c.rl b/ext/redcloth_scan/redcloth_inline.c.rl
index a1a043c5..9750bc95 100644
--- a/ext/redcloth_scan/redcloth_inline.c.rl
+++ b/ext/redcloth_scan/redcloth_inline.c.rl
@@ -96,6 +96,7 @@ red_block(VALUE self, VALUE regs, VALUE block, VALUE refs)
VALUE sym_text = ID2SYM(rb_intern("text"));
VALUE btype = rb_hash_aref(regs, ID2SYM(rb_intern("type")));
block = rb_funcall(block, rb_intern("strip"), 0);
+ VALUE attr_regs = rb_hash_new();
if ((!NIL_P(block)) && !NIL_P(btype))
{
method = rb_str_intern(btype);
@@ -147,10 +148,11 @@ redcloth_inline(self, p, pe, refs)
VALUE refs;
{
int cs, act;
- char *ts = NULL, *te = NULL, *reg = NULL, *eof = NULL;
+ char *ts = NULL, *te = NULL, *reg = NULL, *attr_reg = NULL, *eof = NULL;
char *orig_p = p;
VALUE block = STR_NEW2("");
VALUE regs = Qnil;
+ VALUE attr_regs = Qnil;
%% write init;
diff --git a/ext/redcloth_scan/redcloth_inline.java.rl b/ext/redcloth_scan/redcloth_inline.java.rl
index f0e3d936..44ee32bf 100644
--- a/ext/redcloth_scan/redcloth_inline.java.rl
+++ b/ext/redcloth_scan/redcloth_inline.java.rl
@@ -87,7 +87,7 @@ public class RedclothInline extends RedclothScanService.Base {
return regs;
}
- public void PASS_CODE(IRubyObject H, String A, String T, int O) {
+ public void PASS_CODE(IRubyObject H, String A, String T) {
((RubyString)H).append(red_pass_code(self, regs, runtime.newSymbol(A), T));
}
@@ -122,6 +122,7 @@ public class RedclothInline extends RedclothScanService.Base {
this.refs = refs;
this.block = RubyString.newEmptyString(runtime);
this.regs = runtime.getNil();
+ this.attr_regs = runtime.getNil();
this.opts = 0;
}
diff --git a/ext/redcloth_scan/redcloth_inline.rl b/ext/redcloth_scan/redcloth_inline.rl
index 27ae2eb1..4b8f8230 100644
--- a/ext/redcloth_scan/redcloth_inline.rl
+++ b/ext/redcloth_scan/redcloth_inline.rl
@@ -35,8 +35,8 @@
image_title = ( '(' mtext ')' ) ;
image_is = ( A2 C ". "? (uri image_title?) >A %{ STORE("src"); } ) ;
image_link = ( ":" uri >A %{ STORE_URL("href"); } ) ;
- image = ( "!" image_is "!" %A image_link? ) >X ;
- bracketed_image = ( "[!" image_is "!" %A image_link? "]" ) >X ;
+ image = ( "!" image_is "!" %A image_link? ) >X %SET_ATTR ;
+ bracketed_image = ( "[!" image_is "!" %A image_link? "]" ) >X %SET_ATTR ;
# footnotes
footno = "[" >X %A digit+ %T "]" ;
diff --git a/ext/redcloth_scan/redcloth_scan.c.rl b/ext/redcloth_scan/redcloth_scan.c.rl
index cc084037..4727e432 100644
--- a/ext/redcloth_scan/redcloth_scan.c.rl
+++ b/ext/redcloth_scan/redcloth_scan.c.rl
@@ -32,11 +32,11 @@ redcloth_transform(self, p, pe, refs)
{
char *orig_p = p, *orig_pe = pe;
int cs, act, nest = 0;
- char *ts = NULL, *te = NULL, *reg = NULL, *bck = NULL, *eof = NULL;
+ char *ts = NULL, *te = NULL, *reg = NULL, *bck = NULL, *attr_reg = NULL, *eof = NULL;
VALUE html = STR_NEW2("");
VALUE table = STR_NEW2("");
VALUE block = STR_NEW2("");
- VALUE regs; CLEAR_REGS()
+ VALUE regs, attr_regs; CLEAR_REGS()
VALUE list_layout = Qnil;
diff --git a/ext/redcloth_scan/redcloth_scan.java.rl b/ext/redcloth_scan/redcloth_scan.java.rl
index 821bd9cf..b54c13d1 100644
--- a/ext/redcloth_scan/redcloth_scan.java.rl
+++ b/ext/redcloth_scan/redcloth_scan.java.rl
@@ -26,7 +26,22 @@ import org.jruby.util.ByteList;
public class RedclothScanService implements BasicLibraryService {
public static class Base {
-
+
+ public void SET_ATTRIBUTES() {
+ SET_ATTRIBUTE("class_buf", "class");
+ SET_ATTRIBUTE("id_buf", "id");
+ SET_ATTRIBUTE("lang_buf", "lang");
+ SET_ATTRIBUTE("style_buf", "style");
+ regs.callMethod(runtime.getCurrentContext(), "merge!", attr_regs);
+ attr_regs = RubyHash.newHash(runtime);
+ }
+
+ public void SET_ATTRIBUTE(String B, String A) {
+ if(!((RubyHash)regs).aref(runtime.newSymbol(B)).isNil()) {
+ ((RubyHash)regs).aset(runtime.newSymbol(A), ((RubyHash)regs).aref(runtime.newSymbol(B)));
+ }
+ }
+
public void CLEAR_LIST() {
list_layout = runtime.newArray();
}
@@ -232,6 +247,7 @@ public class RedclothScanService implements BasicLibraryService {
public void CLEAR_REGS() {
regs = RubyHash.newHash(runtime);
+ attr_regs = RubyHash.newHash(runtime);
}
public void RESET_REG() {
@@ -246,6 +262,10 @@ public class RedclothScanService implements BasicLibraryService {
bck = p;
}
+ public void MARK_ATTR() {
+ attr_reg = p;
+ }
+
public void CAT(IRubyObject H) {
((RubyString)H).cat(data, ts, te-ts);
}
@@ -288,8 +308,9 @@ public class RedclothScanService implements BasicLibraryService {
CLEAR(block);
}
- public void AINC(String T) {
- red_inc(regs, runtime.newSymbol(T));
+
+ public void ATTR_INC(String T) {
+ red_inc(attr_regs, runtime.newSymbol(T));
}
public void INC(int N) {
@@ -305,6 +326,10 @@ public class RedclothScanService implements BasicLibraryService {
((RubyHash)regs).aset(runtime.newSymbol(T), runtime.newString(V));
}
+ public void ATTR_SET(String T, String V) {
+ ((RubyHash)attr_regs).aset(runtime.newSymbol(T), runtime.newString(V));
+ }
+
public void STORE(String T) {
if(p > reg && reg >= ts) {
@@ -324,6 +349,15 @@ public class RedclothScanService implements BasicLibraryService {
}
}
+ public void STORE_ATTR(String T) {
+ if(p > attr_reg && attr_reg >= ts) {
+ IRubyObject str = RubyString.newString(runtime, data, attr_reg, p-attr_reg);
+ ((RubyHash)attr_regs).aset(runtime.newSymbol(T), str);
+ } else {
+ ((RubyHash)attr_regs).aset(runtime.newSymbol(T), runtime.getNil());
+ }
+ }
+
public IRubyObject self;
public byte[] data;
public int p, pe;
@@ -336,12 +370,14 @@ public class RedclothScanService implements BasicLibraryService {
public int te = -1;
public int reg = -1;
public int bck = -1;
+ public int attr_reg = -1;
public int eof = -1;
public IRubyObject html;
public IRubyObject table;
public IRubyObject block;
public IRubyObject regs;
+ public IRubyObject attr_regs;
public IRubyObject list_layout;
public String list_type = null;
diff --git a/ext/redcloth_scan/redcloth_scan.rb.rl b/ext/redcloth_scan/redcloth_scan.rb.rl
index 4b2695b2..8ddafc6b 100644
--- a/ext/redcloth_scan/redcloth_scan.rb.rl
+++ b/ext/redcloth_scan/redcloth_scan.rb.rl
@@ -85,7 +85,7 @@ module RedCloth
attr_accessor :p, :pe, :refs
attr_reader :data
attr_accessor :orig_data, :cs, :act, :ts, :te, :reg, :bck, :eof,
- :html, :table, :block, :regs
+ :html, :table, :block, :regs, :attr_regs
attr_accessor :list_layout, :list_type, :list_index, :list_continue, :listm,
:refs_found, :plain_block
@@ -98,8 +98,12 @@ module RedCloth
def MARK_B()
@bck = @p
end
+ def MARK_ATTR()
+ @attr_reg = @p
+ end
def CLEAR_REGS()
@regs = {}
+ @attr_regs = {}
end
def RESET_REG()
@reg = nil
@@ -168,14 +172,18 @@ module RedCloth
def ASET(t, v)
@regs[t.to_sym] = v
end
- def AINC(t)
- red_inc(@regs, t.to_sym)
+ def ATTR_SET(t, v)
+ @attr_regs[t.to_sym] = v
+ end
+ def ATTR_INC(t)
+ red_inc(@attr_regs, t.to_sym)
end
def SET_ATTRIBUTES()
SET_ATTRIBUTE("class_buf", "class")
SET_ATTRIBUTE("id_buf", "id")
SET_ATTRIBUTE("lang_buf", "lang")
SET_ATTRIBUTE("style_buf", "style")
+ @regs.merge!(@attr_regs)
end
def SET_ATTRIBUTE(b, a)
@regs[a.to_sym] = @regs[b.to_sym] unless @regs[b.to_sym].nil?
@@ -207,6 +215,15 @@ module RedCloth
@regs[t.to_sym] = nil
end
end
+ def STORE_ATTR(t)
+ if (@attr_reg && @p > @attr_reg && @attr_reg >= @ts)
+ 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);*/ \
+ else
+ @attr_regs[t.to_sym] = nil
+ end
+ end
def STORE_URL(t)
if (@reg && @p > @reg && @reg >= @ts)
punct = true
diff --git a/ext/redcloth_scan/redcloth_scan.rl b/ext/redcloth_scan/redcloth_scan.rl
index 823c92e4..e6aaba30 100644
--- a/ext/redcloth_scan/redcloth_scan.rl
+++ b/ext/redcloth_scan/redcloth_scan.rl
@@ -10,25 +10,25 @@
# blocks
notextile_tag = notextile (LF | EOF) ;
noparagraph_line_start = " "+ ;
- notextile_block_start = ( "notextile" >A %{ STORE("type"); } A C :> "." ( "." %extend | "" ) " "+ ) ;
+ notextile_block_start = ( "notextile" >A %{ STORE("type"); } A C :> "." ( "." %extend | "" ) " "+ ) %SET_ATTR ;
pre_tag_start = "
]* ">" (space* code_tag_start)? ;
pre_tag_end = (code_tag_end space*)? "
" LF? ;
- pre_block_start = ( "pre" >A %{ STORE("type"); } A C :> "." ( "." %extend | "" ) " "+ ) ;
- bc_start = ( "bc" >A %{ STORE("type"); } A C :> "." ( "." %extend | "" ) " "+ ) ;
- bq_start = ( "bq" >A %{ STORE("type"); } A C :> "." ( "." %extend | "" ) ( ":" %A uri %{ STORE("cite"); } )? " "+ ) ;
+ pre_block_start = ( "pre" >A %{ STORE("type"); } A C :> "." ( "." %extend | "" ) " "+ ) %SET_ATTR ;
+ bc_start = ( "bc" >A %{ STORE("type"); } A C :> "." ( "." %extend | "" ) " "+ ) %SET_ATTR ;
+ bq_start = ( "bq" >A %{ STORE("type"); } A C :> "." ( "." %extend | "" ) ( ":" %A uri %{ STORE("cite"); } )? " "+ ) %SET_ATTR ;
non_ac_btype = ( "bq" | "bc" | "pre" | "notextile" | "table" );
btype = (alpha alnum*) -- (non_ac_btype | "fn" digit+);
- block_start = ( btype >A %{ STORE("type"); } A C :> "." ( "." %extend | "" ) " "+ ) >B %{ STORE_B("fallback"); };
+ block_start = ( btype >A %{ STORE("type"); } A C :> "." ( "." %extend | "" ) " "+ ) >B %{ STORE_B("fallback"); } %SET_ATTR ;
all_btypes = btype | non_ac_btype;
next_block_start = ( all_btypes A_noactions C_noactions :> "."+ " " ) >A @{ fexec(reg); } ;
double_return = LF [ \t]* LF ;
block_end = ( double_return | EOF );
ftype = ( "fn" >A %{ STORE("type"); } digit+ >A %{ STORE("id"); } ) ;
- footnote_start = ( ftype A C :> dotspace ) ;
+ 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 :> " "+ ;
- ol_start = ( ul | ol )* ol N A C :> " "+ ;
+ 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();} ;
dt_start = "-" . " "+ ;
dd_start = ":=" ;
@@ -56,12 +56,12 @@
# tables
para = ( default+ ) -- LF ;
btext = para ( LF{2} )? ;
- tddef = ( D? S A C :> dotspace ) ;
+ tddef = ( D? S A C :> dotspace ) %SET_ATTR ;
td = ( tddef? btext >A %T :> "|" >{PASS(table, "text", "td");} ) >X ;
- trdef = ( A C :> dotspace ) ;
+ trdef = ( A C :> dotspace ) %SET_ATTR ;
tr = ( trdef? "|" %{INLINE(table, "tr_open");} td+ ) >X %{INLINE(table, "tr_close");} ;
trows = ( tr (LF >X tr)* ) ;
- tdef = ( "table" >X A C :> dotspace LF ) ;
+ tdef = ( "table" >X A C :> dotspace LF ) %SET_ATTR ;
table = ( tdef? trows >{CLEAR(table); INLINE(table, "table_open"); RESET_REG();} ) ;
# info
diff --git a/spec/differs/inline.rb b/spec/differs/inline.rb
index deefafbd..caab1552 100644
--- a/spec/differs/inline.rb
+++ b/spec/differs/inline.rb
@@ -16,7 +16,7 @@ def initialize(options)
}
def diff_as_string(data_new, data_old)
- output = ""
+ output = "\e[0m"
last_action = nil
sdiff = Diff::LCS.sdiff(data_old, data_new)
sdiff.each do |change|
diff --git a/spec/fixtures/table.yml b/spec/fixtures/table.yml
index 1336c06e..54440478 100644
--- a/spec/fixtures/table.yml
+++ b/spec/fixtures/table.yml
@@ -346,3 +346,25 @@ html: |-
3 |
+---
+name: with cell attributes
+in: |[en]. lang-ok|{color:red;}. style-ok|(myclass). class-ok|
+html: |-
+
+
+ lang-ok |
+ style-ok |
+ class-ok |
+
+
+---
+name: with improper cell attributes
+in: |[en]lang-bad|{color:red;}style-bad|(myclass)class-bad|
+html: |-
+
+
+ [en]lang-bad |
+ {color:red;}style-bad |
+ (myclass)class-bad |
+
+
diff --git a/spec/spec.opts b/spec/spec.opts
new file mode 100644
index 00000000..b921ac63
--- /dev/null
+++ b/spec/spec.opts
@@ -0,0 +1,3 @@
+--color
+--require=spec/differs/inline.rb
+--diff=RedClothDiffers::Inline
\ No newline at end of file