Gnosygnu has submitted this change and it was merged.

Change subject: v1.12.1.1
......................................................................


v1.12.1.1

Change-Id: I7c232d090225cdab2af8b01070e297fba6355055
---
M 140_dbs/src_110_dbQry/gplx/dbs/Db_stmt_sql.java
M 400_xowa/src/gplx/core/brys/Bit_.java
M 400_xowa/src/gplx/core/brys/Bit__tst.java
M 400_xowa/src/gplx/core/brys/Bry_rdr.java
M 400_xowa/src/gplx/xowa/Xoa_app_.java
M 400_xowa/src/gplx/xowa/hdumps/Xodb_hdump_mgr__write_tst.java
M 400_xowa/src/gplx/xowa/html/hzips/Xow_hzip_itm__anchor.java
M 400_xowa/src/gplx/xowa/html/hzips/Xow_hzip_itm__anchor_tst.java
M 400_xowa/src/gplx/xowa/html/hzips/Xow_hzip_itm__file_tst.java
M 400_xowa/src/gplx/xowa/html/lnkis/Xoh_file_html_fmtr__hdump.java
M 400_xowa/src/gplx/xowa/parsers/paras/Xop_para_wkr.java
M 400_xowa/src/gplx/xowa/parsers/paras/Xop_para_wkr_pre_tst.java
M 400_xowa/src/gplx/xowa/xtns/dynamicPageList/Dpl_xnde_tst.java
M 400_xowa/src/gplx/xowa/xtns/scribunto/lib/Scrib_lib_wikibase_srl.java
M 400_xowa/src_060_utl/gplx/Gfo_usr_dlg_base.java
M 400_xowa/src_490_xnde/gplx/xowa/Xop_xnde_tkn.java
M 400_xowa/src_490_xnde/gplx/xowa/Xop_xnde_wkr.java
M 400_xowa/src_490_xnde/gplx/xowa/Xop_xnde_wkr__err_dangling_tst.java
M tst/400_xowa/root/file/en.wikipedia.org/fsdb.user/fsdb.atr.00.sqlite3
M tst/400_xowa/root/file/en.wikipedia.org/wiki.orig#00.sqlite3
20 files changed, 205 insertions(+), 62 deletions(-)

Approvals:
  Gnosygnu: Verified; Looks good to me, approved



diff --git a/140_dbs/src_110_dbQry/gplx/dbs/Db_stmt_sql.java 
b/140_dbs/src_110_dbQry/gplx/dbs/Db_stmt_sql.java
index fef18b7..d791c20 100644
--- a/140_dbs/src_110_dbQry/gplx/dbs/Db_stmt_sql.java
+++ b/140_dbs/src_110_dbQry/gplx/dbs/Db_stmt_sql.java
@@ -16,7 +16,7 @@
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 package gplx.dbs; import gplx.*;
-class Db_stmt_sql implements Db_stmt {
+class Db_stmt_sql implements Db_stmt {// used for formatting SQL statements; 
not used for actual insert into database
        private Bry_bfr tmp_bfr = Bry_bfr.new_();
        private Bry_fmtr tmp_fmtr = Bry_fmtr.new_();
        private int val_idx = 0;
@@ -97,12 +97,12 @@
                this.Clear();
        }
        public void Add(String v) {Add(-1, v);}
-       public void Add(int idx, String v) {args.Add(v);} ListAdp args = 
ListAdp_.new_();
+       public void Add(int idx, String v) {args.Add(v);} private ListAdp args 
= ListAdp_.new_();
        public String Xto_sql() {
                tmp_fmtr.Bld_bfr_many(tmp_bfr, 
(Object[])args.Xto_ary_and_clear(Object.class));
                return tmp_bfr.Xto_str_and_clear();
        }
-       String sql_orig; 
+       private String sql_orig; 
        public Db_stmt Parse(String sql_str) {
                this.sql_orig = sql_str;
                int arg_idx = 0;
diff --git a/400_xowa/src/gplx/core/brys/Bit_.java 
b/400_xowa/src/gplx/core/brys/Bit_.java
index 2694cc6..60c2db5 100644
--- a/400_xowa/src/gplx/core/brys/Bit_.java
+++ b/400_xowa/src/gplx/core/brys/Bit_.java
@@ -62,6 +62,44 @@
                        v = factor == 0 ? v : (v % factor);     // NOTE: if 0, 
do not do modulus or else div by zero
                }
        }
+       public static byte Xto_byte(byte[] pow_ary, byte... val_ary) {
+               int pow_ary_last = pow_ary.length - 1;
+               int val = 0;
+               for (int i = pow_ary_last; i > -1; --i)
+                       val += pow_ary[i] * val_ary[i];
+               return (byte)val;
+       }
+       public static void Xto_bry(byte[] rv, byte[] pow_ary, byte val) {
+               int pow_ary_len = pow_ary.length;
+               int rv_len = rv.length;
+               for (int i = 0; i < pow_ary_len; i++) {
+                       if (i >= rv_len) break;
+                       rv[i] = (byte)(val / pow_ary[i]);
+                       int factor = pow_ary[i] * rv[i];
+                       val = (byte)(factor == 0 ? val : (val % factor));       
// NOTE: if 0, do not do modulus or else div by zero
+               }
+       }
+       public static int Shift_lhs(int val, int shift) {return val << shift;}
+       public static int Shift_rhs(int val, int shift) {return val >> shift;}
+       public static int Shift_lhs_to_int(int[] shift_ary, int... val_ary) {
+               int val_len = val_ary.length; if (val_len > shift_ary.length) 
throw Err_.new_("vals must be less than shifts; vals={0} shifts=~{1}");
+               int rv = 0;
+               for (int i = 0; i < val_len; ++i) {
+                       int val = val_ary[i];
+                       int shift = shift_ary[i];
+                       rv += val << shift;
+               }
+               return rv;
+       }
+       public static void Shift_rhs_to_ary(int[] rv, int[] shift_ary, int val) 
{
+               int shift_len = shift_ary.length;
+               for (int i = shift_len - 1; i > - 1; --i) {
+                       int shift = shift_ary[i];
+                       int itm = val >> shift;                         
+                       rv[i] = itm;
+                       val -= (itm << shift);
+               }
+       }
        public static int Xto_int_date_short(int[] val_ary) {
                val_ary[0] -= 1900;
                return Xto_int(Pow_ary_date_short, val_ary);
diff --git a/400_xowa/src/gplx/core/brys/Bit__tst.java 
b/400_xowa/src/gplx/core/brys/Bit__tst.java
index 3be8082..1c8bd76 100644
--- a/400_xowa/src/gplx/core/brys/Bit__tst.java
+++ b/400_xowa/src/gplx/core/brys/Bit__tst.java
@@ -18,6 +18,7 @@
 package gplx.core.brys; import gplx.*; import gplx.core.*;
 import org.junit.*;
 public class Bit__tst {
+       @Before public void init() {fxt.Clear();} private Bit__fxt fxt = new 
Bit__fxt();
        @Test  public void XtoBitStr() {
                tst_XtoBitStr(  0, "00000000");
                tst_XtoBitStr(  1, "00000001");
@@ -66,4 +67,43 @@
                Tfds.Eq(expd, date_int);
                Tfds.Eq(date_str, 
Bit_.Xto_date_short(date_int).XtoStr_fmt("yyyyMMdd HHmm"));
        }
+       @Test   public void Shift_lhs() {// simple: shift 1 bit
+               fxt.Test_shift_lhs(1, 1,  2);
+               fxt.Test_shift_lhs(2, 1,  4);
+               fxt.Test_shift_lhs(3, 1,  6);
+               fxt.Test_shift_lhs(4, 1,  8);
+       }
+       @Test   public void Shift_rhs() {
+               fxt.Test_shift_rhs(2, 1,  1);
+               fxt.Test_shift_rhs(4, 1,  2);
+               fxt.Test_shift_rhs(6, 1,  3);
+               fxt.Test_shift_rhs(8, 1,  4);
+       }
+       @Test   public void Shift_lhs_to_int() {
+               int[] shift_ary = Int_.Ary(0, 3, 5);
+               fxt.Test_shift_lhs_to_int(shift_ary, Int_.Ary(0, 0, 0),  0);
+               fxt.Test_shift_lhs_to_int(shift_ary, Int_.Ary(7, 0, 0),  7);    
// 1st 3 bits
+               fxt.Test_shift_lhs_to_int(shift_ary, Int_.Ary(0, 3, 0), 24);    
// 2nd 2 bits
+               fxt.Test_shift_lhs_to_int(shift_ary, Int_.Ary(0, 0, 1), 32);    
// 3rd 1 bit
+               fxt.Test_shift_lhs_to_int(shift_ary, Int_.Ary(7, 3, 1), 63);    
// many bits
+       }
+       @Test   public void Shift_rhs_to_ary() {
+               int[] shift_ary = Int_.Ary(0, 3, 5);
+               fxt.Test_shift_rhs_to_ary(shift_ary,  0, Int_.Ary(0, 0, 0));
+               fxt.Test_shift_rhs_to_ary(shift_ary,  7, Int_.Ary(7, 0, 0));    
// 1st 3 bits
+               fxt.Test_shift_rhs_to_ary(shift_ary, 24, Int_.Ary(0, 3, 0));    
// 2nd 2 bits
+               fxt.Test_shift_rhs_to_ary(shift_ary, 32, Int_.Ary(0, 0, 1));    
// 3rd 1 bit
+               fxt.Test_shift_rhs_to_ary(shift_ary, 63, Int_.Ary(7, 3, 1));    
// many bits
+       }
+}
+class Bit__fxt {
+       public void Clear() {}
+       public void Test_shift_lhs(int val, int shift, int expd) {Tfds.Eq(expd, 
Bit_.Shift_lhs(val, shift));}
+       public void Test_shift_rhs(int val, int shift, int expd) {Tfds.Eq(expd, 
Bit_.Shift_rhs(val, shift));}
+       public void Test_shift_lhs_to_int(int[] shift_ary, int[] val_ary, int 
expd) {Tfds.Eq(expd, Bit_.Shift_lhs_to_int(shift_ary, val_ary));}
+       public void Test_shift_rhs_to_ary(int[] shift_ary, int val, int[] 
expd_ary) {
+               int[] actl_ary = Int_.Ary(0, 0, 0);
+               Bit_.Shift_rhs_to_ary(actl_ary, shift_ary, val);
+               Tfds.Eq_ary(expd_ary, actl_ary);
+       }
 }
diff --git a/400_xowa/src/gplx/core/brys/Bry_rdr.java 
b/400_xowa/src/gplx/core/brys/Bry_rdr.java
index f3c4582..c498cb0 100644
--- a/400_xowa/src/gplx/core/brys/Bry_rdr.java
+++ b/400_xowa/src/gplx/core/brys/Bry_rdr.java
@@ -36,6 +36,7 @@
        public int Read_int_to_comma()  {return Read_int_to(Byte_ascii.Comma);}
        public int Read_int_to_pipe()   {return Read_int_to(Byte_ascii.Pipe);}
        public int Read_int_to_nl()             {return 
Read_int_to(Byte_ascii.NewLine);}
+       public int Read_int_to_quote()  {return Read_int_to(Byte_ascii.Quote);}
        public int Read_int_to(byte to_char) {
                int bgn = pos;
                int rv = 0;
@@ -61,6 +62,8 @@
        }
        public byte[] Read_bry_to_nl()          {return 
Read_bry_to(Byte_ascii.NewLine);}
        public byte[] Read_bry_to_pipe()        {return 
Read_bry_to(Byte_ascii.Pipe);}
+       public byte[] Read_bry_to_quote()       {return 
Read_bry_to(Byte_ascii.Quote);}
+       public byte[] Read_bry_to_apos()        {return 
Read_bry_to(Byte_ascii.Apos);}
        public byte[] Read_bry_to(byte to_char) {
                int bgn = pos;
                while (pos < src_len) {
diff --git a/400_xowa/src/gplx/xowa/Xoa_app_.java 
b/400_xowa/src/gplx/xowa/Xoa_app_.java
index 73761c1..3f1b0c3 100644
--- a/400_xowa/src/gplx/xowa/Xoa_app_.java
+++ b/400_xowa/src/gplx/xowa/Xoa_app_.java
@@ -24,7 +24,7 @@
                boot_mgr.Run(args);
        }
        public static final String Name = "xowa";
-       public static final String Version = "1.11.3.1";
+       public static final String Version = "1.12.1.1";
        public static String Build_date = "2012-12-30 00:00:00";
        public static String Op_sys;
        public static String User_agent = "";
diff --git a/400_xowa/src/gplx/xowa/hdumps/Xodb_hdump_mgr__write_tst.java 
b/400_xowa/src/gplx/xowa/hdumps/Xodb_hdump_mgr__write_tst.java
index 2ac0466..acbe3b2 100644
--- a/400_xowa/src/gplx/xowa/hdumps/Xodb_hdump_mgr__write_tst.java
+++ b/400_xowa/src/gplx/xowa/hdumps/Xodb_hdump_mgr__write_tst.java
@@ -20,13 +20,13 @@
 import gplx.xowa.hdumps.core.*; import gplx.xowa.hdumps.dbs.*; import 
gplx.xowa.hdumps.pages.*; import gplx.xowa.xtns.hieros.*; import 
gplx.xowa.xtns.gallery.*;
 public class Xodb_hdump_mgr__write_tst {
        @Before public void init() {fxt.Clear();} private 
Xodb_hdump_mgr__write_fxt fxt = new Xodb_hdump_mgr__write_fxt();
-       @Test   public void Image_full() {
-               fxt.Expd_itms_xfers(fxt.Make_xfer("A.png", 0, 0, 0, Bool_.Y, 
Xof_ext_.Id_png));
-               fxt.Test_write_all
-               ( "[[File:A.png|test_caption]]"
-               , "<a xtid='a_img_full' xatrs='1|0|0||0|test_caption'/>"
-               );
-       }
+//             @Test   public void Image_full() {
+//                     fxt.Expd_itms_xfers(fxt.Make_xfer("A.png", 0, 0, 0, 
Bool_.Y, Xof_ext_.Id_png));
+//                     fxt.Test_write_all
+//                     ( "[[File:A.png|test_caption]]"
+//                     , "<a xtid='a_img_full' xatrs='1|0|0||0|test_caption'/>"
+//                     );
+//             }
        @Test   public void Image_thumb() {
 //                     fxt.Expd_itms_xfers(fxt.Make_xfer("A.png", 0, 0, 0, 
Bool_.N, Xof_ext_.Id_png));
 //                     fxt.Test_write_all
diff --git a/400_xowa/src/gplx/xowa/html/hzips/Xow_hzip_itm__anchor.java 
b/400_xowa/src/gplx/xowa/html/hzips/Xow_hzip_itm__anchor.java
index a70e61a..4f7b3e8 100644
--- a/400_xowa/src/gplx/xowa/html/hzips/Xow_hzip_itm__anchor.java
+++ b/400_xowa/src/gplx/xowa/html/hzips/Xow_hzip_itm__anchor.java
@@ -19,7 +19,7 @@
 import gplx.core.brys.*; import gplx.html.*; import gplx.xowa.apps.ttls.*; 
import gplx.xowa.hdumps.srls.*;
 public class Xow_hzip_itm__anchor {
        private Xow_hzip_mgr hzip_mgr; private Xoa_ttl_parser ttl_parser; 
private Byte_obj_ref xtid_ref = Byte_obj_ref.zero_();
-       // private Bry_rdr bry_rdr = new Bry_rdr();
+       private Bry_rdr bry_rdr = new Bry_rdr();
        public Xow_hzip_itm__anchor(Xow_hzip_mgr hzip_mgr, Xoa_ttl_parser 
ttl_parser) {this.hzip_mgr = hzip_mgr; this.ttl_parser = ttl_parser;}
        public int Save_a_rhs(Bry_bfr bfr, Xow_hzip_stats stats, byte[] src, 
int src_len, int bgn, int pos) {
                bfr.Add(Xow_hzip_dict.Bry_a_rhs);
@@ -39,19 +39,21 @@
                        default:                                                
                        return hzip_mgr.Warn_by_pos("a.xtid_unknown", bgn, pos);
                }
        }
+       private static int[] Save_img_full_pow = new int[] {0, 1, 2};
        private int Save_img_full(Bry_bfr bfr, Xow_hzip_stats stats, byte[] 
src, int src_len, int bgn, int pos) {
-//                     tmp_bfr.Add_str_ascii(a_cls == 
Xoh_lnki_consts.Tid_a_cls_none ? "0|" : "1|");   // a_cls                       
 : "" || image
-//                     tmp_bfr.Add_str_ascii(a_rel == 
Xoh_lnki_consts.Tid_a_rel_none ? "0|" : "1|");   // a_rel                       
 : "" || nofollow
-//                     tmp_bfr.Add_int_fixed(img_cls, 1).Add_byte_pipe();      
                                                        // img_cls              
        : "" || thumbborder || thumbimage || other
-//                     tmp_bfr.Add_safe(img_cls_other).Add_byte_pipe();        
                                                        // img_cls_other        
: "" || {other}
-//                     tmp_bfr.Add_int_variable(uid).Add_byte_pipe();
-//                     Html_utl.Escape_html_to_bfr(tmp_bfr, img_alt, 0, 
img_alt.length, Bool_.N, Bool_.N, Bool_.N, Bool_.N, Bool_.Y);
-               return Xow_hzip_mgr.Unhandled;
-//                     int xatrs_bgn = Bry_finder.Move_fwd(src, 
Find_img_xatrs, pos, src_len);                         if (xatrs_bgn == 
Bry_finder.Not_found) return 
hzip_mgr.Warn_by_pos_add_dflt("a.img_xatrs_missing", bgn, pos);
-//                     byte a_cls              = src[xatrs_bgn    ] - 
Byte_ascii.Num_0;
-//                     byte a_rel              = src[xatrs_bgn + 2] - 
Byte_ascii.Num_0;
-//                     byte img_rel    = src[xatrs_bgn + 4] - Byte_ascii.Num_0;
-//                     byte meta = img_cls + Enm_.Add_byte(2, img_rel);
+               bfr.Add(Xow_hzip_dict.Bry_img_full);
+               int xatrs_bgn = Bry_finder.Move_fwd(src, Find_img_xatrs, pos, 
src_len);                         if (xatrs_bgn == Bry_finder.Not_found) return 
hzip_mgr.Warn_by_pos_add_dflt("a.img_xatrs_missing", bgn, pos);
+               bry_rdr.Src_(src).Pos_(xatrs_bgn);
+               int a_cls               = bry_rdr.Read_int_to_pipe();
+               int a_rel               = bry_rdr.Read_int_to_pipe();
+               int img_rel             = bry_rdr.Read_int_to_pipe();
+               byte meta               = 
(byte)Bit_.Shift_lhs_to_int(Save_img_full_pow, a_cls, a_rel, img_rel);
+               bfr.Add_byte(meta);                                             
                                                                // meta
+               Hpg_srl_itm_.Save_bin_int_abrv(bfr, 
bry_rdr.Read_int_to_pipe());                // uid
+               bfr.Add(bry_rdr.Read_bry_to_pipe()).Add_byte_pipe();            
                        // img_cls_other
+               bfr.Add(bry_rdr.Read_bry_to_apos());                            
                                        // alt
+               bfr.Add_byte(Xow_hzip_dict.Escape);
+               return bry_rdr.Pos() + 2;                                       
                                                        // +2=/>
        }
        public int Save_lnki(Bry_bfr bfr, Xow_hzip_stats stats, byte[] src, int 
src_len, int bgn, int pos, boolean caption) {
                int ttl_bgn = Bry_finder.Find_fwd(src, Find_href_wiki_bry, pos, 
src_len);                       if (ttl_bgn == Bry_finder.Not_found) return 
Xow_hzip_mgr.Unhandled;//hzip_mgr.Warn_by_pos_add_dflt("a.ttl_bgn_missing", 
bgn, pos);
@@ -156,17 +158,22 @@
                return rv;
        }
        public void Html_plain(Bry_bfr bfr, Xop_lnki_tkn lnki) {
-               bfr.Add_str(lnki.Caption_exists() ? "<a xtid='a_lnki_text_y' 
href=\"" : "<a xtid='a_lnki_text_n' href=\"");
+               bfr.Add_str
+                       (  lnki.Caption_exists()                                
// caption exists; EX: [[A|b]]
+                       || lnki.Tail_bgn() != -1                                
// trailing chars; EX: [[A]]b
+                       ? "<a xtid='a_lnki_text_y' href=\""             // 
embed caption
+                       : "<a xtid='a_lnki_text_n' href=\""             // use 
link only
+                       );
        }
        private static final byte[]
          Find_href_wiki_bry    = Bry_.new_ascii_("href=\"/wiki/")
        , Find_href_bry                 = Bry_.new_ascii_("href=\"")
        , Find_a_rhs_bgn_bry    = Bry_.new_ascii_("</a>")
-//             , Find_img_xatrs                = Bry_.new_ascii_("xatrs='")
+       , Find_img_xatrs                = Bry_.new_ascii_("xatrs='")
        ;
        private static final int 
          Find_href_wiki_len    = Find_href_wiki_bry.length
        , Find_href_len                 = Find_href_bry.length
        , Find_a_rhs_bgn_len    = Find_a_rhs_bgn_bry.length
        ;
-}
+}      
diff --git a/400_xowa/src/gplx/xowa/html/hzips/Xow_hzip_itm__anchor_tst.java 
b/400_xowa/src/gplx/xowa/html/hzips/Xow_hzip_itm__anchor_tst.java
index b76f2eb..9587136 100644
--- a/400_xowa/src/gplx/xowa/html/hzips/Xow_hzip_itm__anchor_tst.java
+++ b/400_xowa/src/gplx/xowa/html/hzips/Xow_hzip_itm__anchor_tst.java
@@ -72,12 +72,15 @@
                fxt.Test_save(brys, "<a xtid='a_lnke_brk_n' class=\"external 
autonumber\"  rel=\"nofollow\" href=\"http://a.org\";>[123]</a>");
                fxt.Test_load(brys, "<a rel=\"nofollow\" class=\"external 
autonumber\" href=\"http://a.org\";>[123]</a>");
        }
-       @Test   public void Html_ttl() {
+       @Test   public void Html_lnki_ttl() {
                fxt.Test_html("[[A]]", "<a xtid='a_lnki_text_n' 
href=\"/wiki/A\" xowa_redlink='1'>A</a>");
        }
-       @Test   public void Html_capt() {
+       @Test   public void Html_lnki_capt() {
                fxt.Test_html("[[A|a]]", "<a xtid='a_lnki_text_y' 
href=\"/wiki/A\" xowa_redlink='1'>a</a>");
        }
+       @Test   public void Html_lnki_trail() {
+               fxt.Test_html("[[A]]b", "<a xtid='a_lnki_text_y' 
href=\"/wiki/A\" xowa_redlink='1'>Ab</a>");
+       }
        @Test   public void Html_lnke_txt() {
                fxt.Test_html("http://a.org";, "<a xtid='a_lnke_txt' 
href=\"http://a.org\"; class=\"external text\" 
rel=\"nofollow\">http://a.org</a>");
        }
diff --git a/400_xowa/src/gplx/xowa/html/hzips/Xow_hzip_itm__file_tst.java 
b/400_xowa/src/gplx/xowa/html/hzips/Xow_hzip_itm__file_tst.java
index 205d446..91ae25d 100644
--- a/400_xowa/src/gplx/xowa/html/hzips/Xow_hzip_itm__file_tst.java
+++ b/400_xowa/src/gplx/xowa/html/hzips/Xow_hzip_itm__file_tst.java
@@ -19,9 +19,9 @@
 import org.junit.*; import gplx.xowa.html.*; import gplx.xowa.hdumps.srls.*;
 public class Xow_hzip_itm__file_tst {
        @Before public void init() {fxt.Clear();} private Xow_hzip_mgr_fxt fxt 
= new Xow_hzip_mgr_fxt();
-       @Test   public void Srl_img_full() {
-//                     byte[][] brys = Bry_.Ary(Xow_hzip_dict.Bry_img_full, 
Bry_.ints_(2), Bry_.new_ascii_("A"), Xow_hzip_dict.Escape_bry);
-//                     fxt.Test_save(brys, "<a xtid='a_img_full' 
href=\"/wiki/A\" id='xowa_lnki_0' title='A'>A</a>");
-//                     fxt.Test_load(brys, "<a href='/wiki/A' 
title='A'>A</a>");
+       @Test   public void Srl_lnki_img_full() {
+               byte[][] brys = Bry_.Ary(Xow_hzip_dict.Bry_img_full, 
Bry_.ints_(7), Bry_.ints_(12, 0), Bry_.new_ascii_("cls_other"), 
Bry_.new_ascii_("|caption_other"), Xow_hzip_dict.Escape_bry);
+               fxt.Test_save(brys, "<a xtid='a_img_full' 
xatrs='1|1|1|12|cls_other|caption_other'/>");
+//                     fxt.Test_load(brys, "a_1<a href='/wiki/A' 
title='A'>A</a>a_2");
        }
 }
diff --git a/400_xowa/src/gplx/xowa/html/lnkis/Xoh_file_html_fmtr__hdump.java 
b/400_xowa/src/gplx/xowa/html/lnkis/Xoh_file_html_fmtr__hdump.java
index eec9b8d..b2fba9f 100644
--- a/400_xowa/src/gplx/xowa/html/lnkis/Xoh_file_html_fmtr__hdump.java
+++ b/400_xowa/src/gplx/xowa/html/lnkis/Xoh_file_html_fmtr__hdump.java
@@ -24,18 +24,18 @@
 //             public override void Html_full_media(Bry_bfr tmp_bfr, byte[] 
a_href, byte[] a_title, Bry_fmtr_arg html) {
 //                     fmtr_full_media.Bld_bfr_many(tmp_bfr, a_href, a_title, 
html);
 //             }
-       @Override public void Html_full_img(Bry_bfr tmp_bfr, Xoh_wtr_ctx hctx, 
Xoa_page page, Xof_xfer_itm xfer_itm, int uid
-               , byte[] a_href, byte a_cls, byte a_rel, byte[] a_title, byte[] 
a_xowa_title
-               , int img_w, int img_h, byte[] img_src, byte[] img_alt, byte 
img_cls, byte[] img_cls_other) {
-               tmp_bfr.Add_str_ascii("<a xtid='a_img_full' xatrs='");
-               tmp_bfr.Add_str_ascii(a_cls == Xoh_lnki_consts.Tid_a_cls_none ? 
"0|" : "1|");   // a_cls                        : "" || image
-               tmp_bfr.Add_str_ascii(a_rel == Xoh_lnki_consts.Tid_a_rel_none ? 
"0|" : "1|");   // a_rel                        : "" || nofollow
-               tmp_bfr.Add_int_fixed(img_cls, 1).Add_byte_pipe();              
                                                // img_cls                      
: "" || thumbborder || thumbimage || other
-               tmp_bfr.Add_safe(img_cls_other).Add_byte_pipe();                
                                                // img_cls_other        : "" || 
{other}
-               tmp_bfr.Add_int_variable(uid).Add_byte_pipe();
-               Html_utl.Escape_html_to_bfr(tmp_bfr, img_alt, 0, 
img_alt.length, Bool_.N, Bool_.N, Bool_.N, Bool_.N, Bool_.Y);
-               tmp_bfr.Add_str_ascii("'/>");
-       }
+//             public override void Html_full_img(Bry_bfr tmp_bfr, Xoh_wtr_ctx 
hctx, Xoa_page page, Xof_xfer_itm xfer_itm, int uid
+//                     , byte[] a_href, byte a_cls, byte a_rel, byte[] 
a_title, byte[] a_xowa_title
+//                     , int img_w, int img_h, byte[] img_src, byte[] img_alt, 
byte img_cls, byte[] img_cls_other) {
+//                     tmp_bfr.Add_str_ascii("<a xtid='a_img_full' xatrs='");
+//                     tmp_bfr.Add_str_ascii(a_cls == 
Xoh_lnki_consts.Tid_a_cls_none ? "0|" : "1|");   // a_cls                       
 : "" || image
+//                     tmp_bfr.Add_str_ascii(a_rel == 
Xoh_lnki_consts.Tid_a_rel_none ? "0|" : "1|");   // a_rel                       
 : "" || nofollow
+//                     tmp_bfr.Add_int_fixed(img_cls, 1).Add_byte_pipe();      
                                                        // img_cls              
        : "" || thumbborder || thumbimage || other
+//                     tmp_bfr.Add_int_variable(uid).Add_byte_pipe();          
                                                        // uid
+//                     tmp_bfr.Add_safe(img_cls_other).Add_byte_pipe();        
                                                        // img_cls_other        
: "" || {other}
+//                     Html_utl.Escape_html_to_bfr(tmp_bfr, img_alt, 0, 
img_alt.length, Bool_.N, Bool_.N, Bool_.N, Bool_.N, Bool_.Y);
+//                     tmp_bfr.Add_str_ascii("'/>");
+//             }
        @Override public void Html_thumb_core(Bry_bfr bfr, int uid, byte[] 
div1_halign, int div2_width, byte[] div2_content) {
                tmp_bfr.Add(Hdump_html_consts.Key_img_style);
                tmp_bfr.Add_int_variable(uid);
diff --git a/400_xowa/src/gplx/xowa/parsers/paras/Xop_para_wkr.java 
b/400_xowa/src/gplx/xowa/parsers/paras/Xop_para_wkr.java
index de8846d..5582c06 100644
--- a/400_xowa/src/gplx/xowa/parsers/paras/Xop_para_wkr.java
+++ b/400_xowa/src/gplx/xowa/parsers/paras/Xop_para_wkr.java
@@ -16,7 +16,7 @@
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 package gplx.xowa.parsers.paras; import gplx.*; import gplx.xowa.*; import 
gplx.xowa.parsers.*;
-import gplx.xowa.parsers.tblws.*;
+import gplx.xowa.parsers.tblws.*; import gplx.core.btries.*;
 public class Xop_para_wkr implements Xop_ctx_wkr {
        private boolean para_enabled;
        private byte cur_mode;
@@ -157,7 +157,8 @@
        }
        public int Process_pre(Xop_ctx ctx, Xop_tkn_mkr tkn_mkr, Xop_root_tkn 
root, byte[] src, int src_len, int bgn_pos, int cur_pos, int txt_pos) {
                Dd_clear(ctx);
-               Object o = ctx.App().Utl_trie_tblw_ws().Match_bgn(src, txt_pos, 
src_len);
+               Btrie_slim_mgr tblw_ws_trie = ctx.App().Utl_trie_tblw_ws();
+               Object o = tblw_ws_trie.Match_bgn(src, txt_pos, src_len);
                if (o != null) {        // tblw_ws found
                        Xop_tblw_ws_itm ws_itm = (Xop_tblw_ws_itm)o;
                        byte tblw_type = ws_itm.Tblw_type();
@@ -170,9 +171,18 @@
                                        }
                                        break;
                                case Xop_tblw_ws_itm.Type_xnde:
-                                       if (bgn_pos != Xop_parser_.Doc_bgn_bos)
-                                               ctx.Para().Process_nl(ctx, 
root, src, bgn_pos, cur_pos);
-                                       return ctx.Xnde().Make_tkn(ctx, 
tkn_mkr, root, src, src_len, txt_pos, txt_pos + 1);
+                                       int nxt_pos = tblw_ws_trie.Match_pos();
+                                       if (nxt_pos < src_len) {        // 
bounds check
+                                               switch (src[nxt_pos]) { // 
check that next char is "end" of xnde name; guard against false matches like 
"<trk" PAGE:de.v:Via_Jutlandica/Gpx DATE:2014-11-29
+                                                       case Byte_ascii.Space: 
case Byte_ascii.NewLine: case Byte_ascii.Tab:            // whitespace
+                                                       case Byte_ascii.Slash: 
case Byte_ascii.Gt:                                                             
         // end node
+                                                       case Byte_ascii.Quote: 
case Byte_ascii.Apos:                                                           
 // quotes
+                                                               if (bgn_pos != 
Xop_parser_.Doc_bgn_bos)
+                                                                       
ctx.Para().Process_nl(ctx, root, src, bgn_pos, cur_pos);
+                                                               return 
ctx.Xnde().Make_tkn(ctx, tkn_mkr, root, src, src_len, txt_pos, txt_pos + 1);
+                                               }
+                                       }
+                                       break;
                                default: {
                                        int tblw_rv = 
ctx.Tblw().Make_tkn_bgn(ctx, tkn_mkr, root, src, src_len, bgn_pos, txt_pos + 
ws_itm.Hook_len(), false, tblw_type, Xop_tblw_wkr.Called_from_pre, -1, -1);
                                        if (tblw_rv != -1)      // \n\s| is 
valid tblw tkn and processed; otherwise process pre-code below; 
EX:w:Wikipedia:WikiProject_History/CategoryExample; DATE:2014-04-14
diff --git a/400_xowa/src/gplx/xowa/parsers/paras/Xop_para_wkr_pre_tst.java 
b/400_xowa/src/gplx/xowa/parsers/paras/Xop_para_wkr_pre_tst.java
index 6ba1aa5..3e32ff8 100644
--- a/400_xowa/src/gplx/xowa/parsers/paras/Xop_para_wkr_pre_tst.java
+++ b/400_xowa/src/gplx/xowa/parsers/paras/Xop_para_wkr_pre_tst.java
@@ -244,4 +244,15 @@
                , "</p>"
                ));     
        }
+       @Test   public void False_match_xnde() {        // PURPOSE: "\s<trk>" 
being evaluted as "\s<tr>"; PAGE:de.v:Via_Jutlandica/Gpx DATE:2014-11-29
+               fxt.Init_para_y_();
+               fxt.Test_html_wiki_str(String_.Concat_lines_nl
+               ( ""
+               , " <trk>"
+               ), String_.Concat_lines_nl
+               ( ""
+               , "<pre>&lt;trk&gt;"
+               , "</pre>"
+               ));
+       }
 }
diff --git a/400_xowa/src/gplx/xowa/xtns/dynamicPageList/Dpl_xnde_tst.java 
b/400_xowa/src/gplx/xowa/xtns/dynamicPageList/Dpl_xnde_tst.java
index 274734f..7f2743f 100644
--- a/400_xowa/src/gplx/xowa/xtns/dynamicPageList/Dpl_xnde_tst.java
+++ b/400_xowa/src/gplx/xowa/xtns/dynamicPageList/Dpl_xnde_tst.java
@@ -167,6 +167,12 @@
                ,       "</DynamicPageList>"
                ), fxt.Ul(Itm_html_null, "B", "A"));
        }
+       @Test  public void Err_page_ns_doesnt_exist() {// PURPOSE: check that 
<dpl> is not enabled if wiki does not have Page / Index ns; 
PAGE:fr.w:Wikipedia:Le_Bistro/novembre_2006 DATE:2014-11-28
+               
fxt.Wiki().Ns_mgr_(Xow_ns_mgr_.default_(gplx.xowa.langs.cases.Xol_case_mgr_.Ascii()));
+               fxt.Wiki().Cfg_parser().Xtns().Itm_pages().Reset();     // must 
reset to clear cached valid ns_page from previous tests
+               
fxt.Fxt().Test_parse_page_wiki_str("<dynamicpagelist>category=a</dynamicpagelist>",
 "No pages meet these criteria.");
+               fxt.Wiki().Cfg_parser().Xtns().Itm_pages().Reset();     // must 
reset to clear cached invalid ns_page for next tests
+       }
        private static final String Itm_html_null = null;
 }
 class Dpl_page_mok {
@@ -185,8 +191,13 @@
                fxt.App().Usr_dlg().Ui_wkr().Clear();
                fxt.Wiki().Hive_mgr().Clear();
                fxt.Wiki().Db_mgr().Save_mgr().Clear(); // NOTE: must clear to 
reset next_id to 0; Ctg_create assumes clean slate from 0
+               fxt.Wiki().Xtn_mgr().Xtn_proofread().Enabled_y_();
+               fxt.Wiki().Db_mgr().Load_mgr().Clear(); // must clear; 
otherwise fails b/c files get deleted, but wiki.data_mgr caches the 
Xowd_regy_mgr (the .reg file) in memory;
+               fxt.Wiki().Ns_mgr().Add_new(Xowc_xtn_pages.Ns_page_id_default, 
"Page").Add_new(Xowc_xtn_pages.Ns_index_id_default, "Index").Init();
                Io_mgr._.InitEngine_mem();
        }
+       public Xow_wiki Wiki() {return fxt.Wiki();}
+       public Xop_fxt Fxt() {return fxt;}
        public void Warns(String... v) {warns = v;} private String[] warns;
        public void Page_create(String page) {fxt.Init_page_create(page);}
        public void Ctg_create(String ctg, String... ttls) {
diff --git 
a/400_xowa/src/gplx/xowa/xtns/scribunto/lib/Scrib_lib_wikibase_srl.java 
b/400_xowa/src/gplx/xowa/xtns/scribunto/lib/Scrib_lib_wikibase_srl.java
index 6c9a7c7..519c5cc 100644
--- a/400_xowa/src/gplx/xowa/xtns/scribunto/lib/Scrib_lib_wikibase_srl.java
+++ b/400_xowa/src/gplx/xowa/xtns/scribunto/lib/Scrib_lib_wikibase_srl.java
@@ -59,7 +59,7 @@
                }
                return rv;
        }
-       private static KeyVal Srl_sitelinks_badges(byte[][] badges, int 
base_adj) {
+       private static KeyVal Srl_sitelinks_badges(byte[][] badges, int 
base_adj) {     // DATE:2014-11-13
                if (badges == null) badges = Bry_.Ary_empty;    // null badges 
-> badges:[]
                int len = badges.length;
                KeyVal[] kvs = len == 0 ? KeyVal_.Ary_empty : new KeyVal[len];
diff --git a/400_xowa/src_060_utl/gplx/Gfo_usr_dlg_base.java 
b/400_xowa/src_060_utl/gplx/Gfo_usr_dlg_base.java
index b61cd7c..b5b97c5 100644
--- a/400_xowa/src_060_utl/gplx/Gfo_usr_dlg_base.java
+++ b/400_xowa/src_060_utl/gplx/Gfo_usr_dlg_base.java
@@ -17,6 +17,8 @@
 */
 package gplx;
 public class Gfo_usr_dlg_base implements Gfo_usr_dlg {
+       private Bry_fmtr tmp_fmtr = 
Bry_fmtr.tmp_().Fail_when_invalid_escapes_(false);  // do not fail b/c msgs may 
contain excerpt of random text; EX:[[User:A|~A~]] DATE:2014-11-28
+       private Bry_bfr tmp_bfr = Bry_bfr.new_();
        public Gfo_usr_dlg_ui Ui_wkr() {return ui_wkr;} public void 
Ui_wkr_(Gfo_usr_dlg_ui v) {ui_wkr = v;} Gfo_usr_dlg_ui ui_wkr = 
Gfo_usr_dlg_ui_.Null;
        public Gfo_log_wtr Log_wtr() {return log_wtr;} public void 
Log_wtr_(Gfo_log_wtr v) {log_wtr = v;} Gfo_log_wtr log_wtr;
        @gplx.Virtual public void Clear() {ui_wkr.Clear();}
@@ -41,15 +43,15 @@
                log_wtr.Log_err(Err_.Message_gplx(rv));
                return rv;
        }
-       String Bld_msg_many(String grp_key, String msg_key, String fmt, 
Object[] args) {
+       private String Bld_msg_many(String grp_key, String msg_key, String fmt, 
Object[] args) {
                tmp_fmtr.Fmt_(fmt).Bld_bfr_many(tmp_bfr, args);
                return tmp_bfr.Xto_str_and_clear();
-       }       private Bry_fmtr tmp_fmtr = Bry_fmtr.tmp_(); Bry_bfr tmp_bfr = 
Bry_bfr.new_();
-       String Bld_msg_one(String grp_key, String msg_key, String fmt, Object 
val) {
+       }
+       private String Bld_msg_one(String grp_key, String msg_key, String fmt, 
Object val) {
                tmp_fmtr.Fmt_(fmt).Bld_bfr_one(tmp_bfr, val);
                return tmp_bfr.Xto_str_and_clear();
        }
-       String Bld_msg_none(String grp_key, String msg_key, String fmt) {
+       private String Bld_msg_none(String grp_key, String msg_key, String fmt) 
{
                return fmt;
        }
        private void Ui_wkr_parse(String s) {
diff --git a/400_xowa/src_490_xnde/gplx/xowa/Xop_xnde_tkn.java 
b/400_xowa/src_490_xnde/gplx/xowa/Xop_xnde_tkn.java
index 6e6370d..712f598 100644
--- a/400_xowa/src_490_xnde/gplx/xowa/Xop_xnde_tkn.java
+++ b/400_xowa/src_490_xnde/gplx/xowa/Xop_xnde_tkn.java
@@ -105,7 +105,7 @@
                                        for (int i = 0; i < subs_len; i++)      
                        // always evaluate subs; handle <poem>{{{1}}}</poem>; 
DATE:2014-03-03
                                                
this.Subs_get(i).Tmpl_evaluate(ctx, src, caller, bfr);
                                        bfr.Add_mid(src, tag_close_bgn, 
tag_close_end); // write tag_end
-                                       if (tag_close_bgn == Int_.MinValue) {// 
xtn is unclosed; add a </xtn> else rest of page will be gobbled; DATE:2014-11-13
+                                       if (tag_close_bgn == Int_.MinValue) {// 
xtn is unclosed; add a </xtn> else rest of page will be gobbled; 
PAGE:en.w:Provinces_and_territories_of_Canada DATE:2014-11-13
                                                bfr.Add(tag.XtnEndTag());
                                                bfr.Add(Byte_ascii.Gt_bry);
                                        }
diff --git a/400_xowa/src_490_xnde/gplx/xowa/Xop_xnde_wkr.java 
b/400_xowa/src_490_xnde/gplx/xowa/Xop_xnde_wkr.java
index 26a4464..6c34a7e 100644
--- a/400_xowa/src_490_xnde/gplx/xowa/Xop_xnde_wkr.java
+++ b/400_xowa/src_490_xnde/gplx/xowa/Xop_xnde_wkr.java
@@ -105,7 +105,7 @@
                        if (ctx.Parse_tid() == Xop_parser_.Parse_tid_page_wiki) 
{
                                if (ctx_cur_tid_is_tblw_atr_owner)              
        // unknown_tag is occurring inside tblw element (EX: {| 
style='margin:1em<f'); just add to txt tkn
                                        return ctx.Lxr_make_txt_(cur_pos);
-                               else {                                          
                                // unknown_tag is occurring anyhwere else; 
escape < to &lt; and resume from character just after it;
+                               else {                                          
                                // unknown_tag is occurring anywhere else; 
escape < to &lt; and resume from character just after it;
                                        ctx.Subs_add(root, 
Make_bry_tkn(tkn_mkr, src, bgn_pos, cur_pos));
                                        return cur_pos;
                                }
@@ -634,19 +634,23 @@
                                        case Xop_xnde_tag_.Tid_imageMap:        
                        xnde_xtn = tkn_mkr.Xnde_imageMap(); break;
                                        case Xop_xnde_tag_.Tid_hiero:           
                        xnde_xtn = tkn_mkr.Xnde_hiero(); break;
                                        case Xop_xnde_tag_.Tid_inputBox:        
                        xnde_xtn = tkn_mkr.Xnde_inputbox(); break;
-                                       case Xop_xnde_tag_.Tid_pages:           
                        {
+                                       case Xop_xnde_tag_.Tid_dynamicPageList:
+                                       case Xop_xnde_tag_.Tid_pages: {
+                                               switch (tag_id) {
+                                                       case 
Xop_xnde_tag_.Tid_pages:                   xnde_xtn = tkn_mkr.Xnde_pages(); 
break;
+                                                       case 
Xop_xnde_tag_.Tid_dynamicPageList: xnde_xtn = tkn_mkr.Xnde_dynamicPageList(); 
break;
+                                               }
                                                boolean enabled = 
ctx.Wiki().Xtn_mgr().Xtn_proofread().Enabled();
-                                               if (enabled)
-                                                       xnde_xtn = 
tkn_mkr.Xnde_pages();
-                                               else
+                                               if (!enabled) { // if Page / 
Index ns does not exist, disable xtn and escape content; DATE:2014-11-28
                                                        escaped = true;
+                                                       xnde_xtn = null;
+                                               }
                                                break;
                                        }
                                        case Xop_xnde_tag_.Tid_pagequality:     
                        xnde_xtn = tkn_mkr.Xnde_pagequality(); break;
                                        case Xop_xnde_tag_.Tid_pagelist:        
                        xnde_xtn = tkn_mkr.Xnde_pagelist(); break;
                                        case Xop_xnde_tag_.Tid_section:         
                        xnde_xtn = tkn_mkr.Xnde_section(); break;
                                        case Xop_xnde_tag_.Tid_categoryList:    
                xnde_xtn = tkn_mkr.Xnde_categoryList(); break;
-                                       case Xop_xnde_tag_.Tid_dynamicPageList: 
                xnde_xtn = tkn_mkr.Xnde_dynamicPageList(); break;
                                        case Xop_xnde_tag_.Tid_syntaxHighlight: 
                xnde_xtn = tkn_mkr.Xnde_syntaxHighlight(); break;
                                        case Xop_xnde_tag_.Tid_score:           
                        xnde_xtn = tkn_mkr.Xnde_score(); break;
                                        case Xop_xnde_tag_.Tid_translate:       
                        xnde_xtn = tkn_mkr.Xnde_translate(); break;
diff --git 
a/400_xowa/src_490_xnde/gplx/xowa/Xop_xnde_wkr__err_dangling_tst.java 
b/400_xowa/src_490_xnde/gplx/xowa/Xop_xnde_wkr__err_dangling_tst.java
index 8b4f9ad..f7ecb13 100644
--- a/400_xowa/src_490_xnde/gplx/xowa/Xop_xnde_wkr__err_dangling_tst.java
+++ b/400_xowa/src_490_xnde/gplx/xowa/Xop_xnde_wkr__err_dangling_tst.java
@@ -181,4 +181,18 @@
        @Test  public void Underline() {        // PURPOSE: 2nd <u> should 
auto-close; 
PAGE:en.b:Textbook_of_Psychiatry/Alcoholism_and_Psychoactive_Substance_Use_Disorders
 DATE:2014-09-05
                fxt.Test_html_full_str("a<u>b<u>c", "a<u>b</u>c");
        }
+       @Test   public void Xtn_template() {    // PURPOSE: dangling xtns 
within templates should be auto-closed inside template, not in calling page; 
PAGE:en.w:Provinces_and_territories_of_Canada DATE:2014-11-13
+               fxt.Init_page_create("Template:A", "<poem>A");
+               fxt.Test_parse_page_all_str(String_.Concat_lines_nl_skip_last
+               ( "{{A}}"
+               , " b"          // poem should not extend to " b"
+               ), String_.Concat_lines_nl_skip_last
+               ( "<div class=\"poem\">"
+               , "<p>"
+               , "A"
+               , "</p>"
+               , "</div>"      // poem ends here
+               , " b"
+               ));
+       }
 }
diff --git 
a/tst/400_xowa/root/file/en.wikipedia.org/fsdb.user/fsdb.atr.00.sqlite3 
b/tst/400_xowa/root/file/en.wikipedia.org/fsdb.user/fsdb.atr.00.sqlite3
index 1b5fbeb..ef8dca8 100644
--- a/tst/400_xowa/root/file/en.wikipedia.org/fsdb.user/fsdb.atr.00.sqlite3
+++ b/tst/400_xowa/root/file/en.wikipedia.org/fsdb.user/fsdb.atr.00.sqlite3
Binary files differ
diff --git "a/tst/400_xowa/root/file/en.wikipedia.org/wiki.orig\04300.sqlite3" 
"b/tst/400_xowa/root/file/en.wikipedia.org/wiki.orig\04300.sqlite3"
index cc7c821..4f402f9 100644
--- "a/tst/400_xowa/root/file/en.wikipedia.org/wiki.orig\04300.sqlite3"
+++ "b/tst/400_xowa/root/file/en.wikipedia.org/wiki.orig\04300.sqlite3"
Binary files differ

-- 
To view, visit https://gerrit.wikimedia.org/r/176627
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: I7c232d090225cdab2af8b01070e297fba6355055
Gerrit-PatchSet: 1
Gerrit-Project: xowa
Gerrit-Branch: master
Gerrit-Owner: Gnosygnu <gnosy...@gmail.com>
Gerrit-Reviewer: Gnosygnu <gnosy...@gmail.com>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to