From a8f6fd0fb024776f76048d1168078992cabda9d3 Mon Sep 17 00:00:00 2001 From: gnosygnu Date: Fri, 12 Oct 2018 23:16:31 -0400 Subject: [PATCH] Template_styles: Add support for template styles --- 100_core/src/gplx/core/intls/Utf16__tst.java | 8 +- 100_core/src/gplx/core/tests/Gftest.java | 1 + 400_xowa/.classpath | 1 + .../src/gplx/langs/jsons/Json_doc_wtr.java | 8 +- .../gplx/langs/jsons/Json_doc_wtr_tst.java | 43 +++ .../src/gplx/langs/phps/Php_evaluator.java | 26 +- 400_xowa/src/gplx/langs/phps/Php_itm_kv.java | 14 +- 400_xowa/src/gplx/langs/phps/Php_lxr.java | 16 +- 400_xowa/src/gplx/langs/phps/Php_parser.java | 12 +- 400_xowa/src/gplx/langs/phps/Php_tkn.java | 47 ---- .../src/gplx/langs/phps/Php_tkn_base.java | 57 ++++ .../src/gplx/langs/phps/Php_tkn_comment.java | 46 ++++ 400_xowa/src/gplx/xowa/Xoa_app_.java | 4 +- 400_xowa/src/gplx/xowa/Xoa_app_fxt.java | 4 +- 400_xowa/src/gplx/xowa/Xoae_app.java | 4 +- .../mass_parses/parses/Xow_wiki_utl_.java | 6 +- 400_xowa/src/gplx/xowa/apps/Xoav_app.java | 4 +- .../src/gplx/xowa/apps/fsys/Xoa_fsys_mgr.java | 6 +- .../xowa/htmls/core/htmls/Xoh_html_wtr.java | 1 + .../src/gplx/xowa/langs/Xoa_lang_mgr.java | 12 +- .../src/gplx/xowa/langs/Xol_lang_itm.java | 3 + .../src/gplx/xowa/langs/Xol_lang_itm_.java | 4 +- .../lnki_trails/Xol_lnki_trail_mgr_tst.java | 3 +- .../src/gplx/xowa/langs/names/Strcpn.java | 60 +++++ .../src/gplx/xowa/langs/names/Strcpn_tst.java | 55 ++++ .../xowa/langs/names/Title_chars_regx.java | 52 ++++ .../gplx/xowa/langs/names/Xol_name_mgr.java | 246 ++++++++++++++++++ .../xowa/langs/names/Xol_name_mgr_tst.java | 115 ++++++++ .../xowa/langs/parsers/Xol_lang_srl_tst.java | 6 +- .../src/gplx/xowa/parsers/Xop_tkn_mkr.java | 1 + .../xowa/parsers/xndes/Xop_xnde_tag_.java | 4 +- .../gplx/xowa/parsers/xndes/Xop_xnde_wkr.java | 1 + .../src/gplx/xowa/wikis/Xoae_wiki_mgr.java | 4 +- 400_xowa/src/gplx/xowa/xtns/Xow_xtn_mgr.java | 1 + .../xowa/xtns/cldrs/Cldr_name_loader.java | 4 +- .../xowa/xtns/cldrs/Cldr_name_xtn_mgr.java | 24 ++ .../gplx/xowa/xtns/cldrs/Language_name.java | 31 +++ .../xowa/xtns/cldrs/Language_name_loader.java | 57 ++++ .../xtns/cldrs/Language_names_converter.java | 93 +++++++ .../cldrs/Language_names_converter_tst.java | 71 +++++ .../scribunto/Jscfg_scrib_lib_tst.java | 4 +- .../pfuncs/numbers/Pf_formatnum_es_tst.java | 4 +- .../pfuncs/numbers/Pf_formatnum_fa_tst.java | 7 +- .../pfuncs/strings/Pfunc_tag_kvp_wtr.java | 3 +- .../xtns/pfuncs/strings/Pfunc_tag_tst.java | 2 +- .../scribunto/libs/Scrib_lib_language.java | 6 + .../template_styles/Template_styles_nde.java | 76 ++++++ .../Template_styles_nde_tst.java | 71 +++++ .../title/XomwMediaWikiTitleCodecTest.java | 2 +- .../mediawiki/languages/XomwLanguageTest.java | 2 +- 50 files changed, 1219 insertions(+), 113 deletions(-) create mode 100644 400_xowa/src/gplx/langs/jsons/Json_doc_wtr_tst.java create mode 100644 400_xowa/src/gplx/langs/phps/Php_tkn_base.java create mode 100644 400_xowa/src/gplx/langs/phps/Php_tkn_comment.java create mode 100644 400_xowa/src/gplx/xowa/langs/names/Strcpn.java create mode 100644 400_xowa/src/gplx/xowa/langs/names/Strcpn_tst.java create mode 100644 400_xowa/src/gplx/xowa/langs/names/Title_chars_regx.java create mode 100644 400_xowa/src/gplx/xowa/langs/names/Xol_name_mgr.java create mode 100644 400_xowa/src/gplx/xowa/langs/names/Xol_name_mgr_tst.java create mode 100644 400_xowa/src/gplx/xowa/xtns/cldrs/Cldr_name_xtn_mgr.java create mode 100644 400_xowa/src/gplx/xowa/xtns/cldrs/Language_name.java create mode 100644 400_xowa/src/gplx/xowa/xtns/cldrs/Language_name_loader.java create mode 100644 400_xowa/src/gplx/xowa/xtns/cldrs/Language_names_converter.java create mode 100644 400_xowa/src/gplx/xowa/xtns/cldrs/Language_names_converter_tst.java create mode 100644 400_xowa/src/gplx/xowa/xtns/template_styles/Template_styles_nde.java create mode 100644 400_xowa/src/gplx/xowa/xtns/template_styles/Template_styles_nde_tst.java diff --git a/100_core/src/gplx/core/intls/Utf16__tst.java b/100_core/src/gplx/core/intls/Utf16__tst.java index 2ebb8799b..15a8fe573 100644 --- a/100_core/src/gplx/core/intls/Utf16__tst.java +++ b/100_core/src/gplx/core/intls/Utf16__tst.java @@ -18,10 +18,10 @@ import org.junit.*; import gplx.core.primitives.*; public class Utf16__tst { private Utf16__fxt fxt = new Utf16__fxt(); @Test public void Encode_decode() { -// fxt.Test_encode_decode(162, 194, 162); // cent -// fxt.Test_encode_decode(8364, 226, 130, 172); // euro - fxt.Test_encode_decode(150370, 240, 164, 173, 162); // example from [[UTF-8]]; should be encoded as two bytes - fxt.Test_encode_decode(143489, 240, 163, 130, 129); // EX: 駣𣂁脁 DATE:2017-04-22 + fxt.Test_encode_decode(162, 194, 162); // cent; ¢ + fxt.Test_encode_decode(8364, 226, 130, 172); // euro; € + fxt.Test_encode_decode(150370, 240, 164, 173, 162); // example from [[UTF-8]]; should be encoded as two bytes; 𤭢 + fxt.Test_encode_decode(143489, 240, 163, 130, 129); // EX: 駣𣂁脁 DATE:2017-04-22; 𣂁 } @Test public void Encode_as_bry_by_hex() { fxt.Test_Encode_hex_to_bry("00", 0); diff --git a/100_core/src/gplx/core/tests/Gftest.java b/100_core/src/gplx/core/tests/Gftest.java index 750dd7225..44f583d72 100644 --- a/100_core/src/gplx/core/tests/Gftest.java +++ b/100_core/src/gplx/core/tests/Gftest.java @@ -21,6 +21,7 @@ public class Gftest { public static void Eq__ary(int[] expd, int[] actl, String msg_fmt, Object... msg_args) {Eq__array(Type_ids_.Id__int, expd, actl, msg_fmt, msg_args);} public static void Eq__ary(long[] expd, long[] actl, String msg_fmt, Object... msg_args) {Eq__array(Type_ids_.Id__long, expd, actl, msg_fmt, msg_args);} public static void Eq__ary(byte[] expd, byte[] actl, String msg_fmt, Object... msg_args) {Eq__array(Type_ids_.Id__byte, expd, actl, msg_fmt, msg_args);} + public static void Eq__ary__lines(String expd, String actl) {Eq__ary__lines(expd, actl, "no_msg");} public static void Eq__ary__lines(String expd, byte[] actl) {Eq__ary__lines(expd, String_.new_u8(actl), "no_msg");} public static void Eq__ary__lines(String expd, byte[] actl, String msg_fmt, Object... msg_args) {Eq__ary__lines(expd, String_.new_u8(actl), msg_fmt, msg_args);} public static void Eq__ary__lines(String expd, String actl, String msg_fmt, Object... msg_args) {Eq__array(Type_ids_.Id__bry, Bry_split_.Split_lines(Bry_.new_u8_safe(expd)), Bry_split_.Split_lines(Bry_.new_u8_safe(actl)), msg_fmt, msg_args);} diff --git a/400_xowa/.classpath b/400_xowa/.classpath index 51d3ee90a..c662061de 100644 --- a/400_xowa/.classpath +++ b/400_xowa/.classpath @@ -10,5 +10,6 @@ + diff --git a/400_xowa/src/gplx/langs/jsons/Json_doc_wtr.java b/400_xowa/src/gplx/langs/jsons/Json_doc_wtr.java index 458e04d14..b2793ce6a 100644 --- a/400_xowa/src/gplx/langs/jsons/Json_doc_wtr.java +++ b/400_xowa/src/gplx/langs/jsons/Json_doc_wtr.java @@ -29,8 +29,11 @@ public class Json_doc_wtr { public Json_doc_wtr Str(byte[] v) { if (v == null) bfr.Add(Object_.Bry__null); - else - bfr.Add_byte(Byte_ascii.Quote).Add(v).Add_byte(Byte_ascii.Quote); + else { + bfr.Add_byte(Byte_ascii.Quote); + bfr.Add_bry_escape(Byte_ascii.Quote, Escaped__quote, v, 0, v.length); + bfr.Add_byte(Byte_ascii.Quote); + } return this; } public Json_doc_wtr Int(int v) {bfr.Add_int_variable(v); return this;} @@ -94,4 +97,5 @@ public class Json_doc_wtr { } public byte[] Bld() {return bfr.To_bry_and_clear();} public String Bld_as_str() {return bfr.To_str_and_clear();} + private static final byte[] Escaped__quote = Bry_.new_a7("\\\""); } diff --git a/400_xowa/src/gplx/langs/jsons/Json_doc_wtr_tst.java b/400_xowa/src/gplx/langs/jsons/Json_doc_wtr_tst.java new file mode 100644 index 000000000..daa663e40 --- /dev/null +++ b/400_xowa/src/gplx/langs/jsons/Json_doc_wtr_tst.java @@ -0,0 +1,43 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012-2017 gnosygnu@gmail.com + +XOWA is licensed under the terms of the General Public License (GPL) Version 3, +or alternatively under the terms of the Apache License Version 2.0. + +You may use XOWA according to either of these licenses as is most appropriate +for your project on a case-by-case basis. + +The terms of each license can be found in the source code repository: + +GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt +Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt +*/ +package gplx.langs.jsons; import gplx.*; import gplx.langs.*; +import org.junit.*; import gplx.core.tests.*; +public class Json_doc_wtr_tst { + private final Json_doc_wtr_fxt fxt = new Json_doc_wtr_fxt(); + @Test public void Basic() { + fxt.Test__Bld_as_str + ( fxt.Exec__Kv_simple("k1", "v\"1") + , fxt.Exec__Concat_apos + ( "{" + , " 'k1':'v\\\"1'" + , "}")); + } +} +class Json_doc_wtr_fxt { + public Json_doc_wtr Exec__Kv_simple(String key, String val) { + Json_doc_wtr doc_wtr = new Json_doc_wtr(); + doc_wtr.Nde_bgn(); + doc_wtr.Kv(Bool_.N, Bry_.new_u8(key), Bry_.new_u8(val)); + doc_wtr.Nde_end(); + return doc_wtr; + } + public void Test__Bld_as_str(Json_doc_wtr doc_wtr, String expd) { + Gftest.Eq__ary__lines(expd, doc_wtr.Bld_as_str()); + } + public String Exec__Concat_apos(String... ary) { + return Json_doc.Make_str_by_apos(ary); + } +} diff --git a/400_xowa/src/gplx/langs/phps/Php_evaluator.java b/400_xowa/src/gplx/langs/phps/Php_evaluator.java index 27edc6d65..a1738b83b 100644 --- a/400_xowa/src/gplx/langs/phps/Php_evaluator.java +++ b/400_xowa/src/gplx/langs/phps/Php_evaluator.java @@ -22,13 +22,15 @@ NOTE: naive implementation of PHP parser; intended only for parsing Messages**.p - no functions are supported: EX: strlen('a') fails */ public class Php_evaluator implements Php_tkn_wkr { - byte mode = Mode_key_bgn, next_tid = 0, next_mode = 0; - Php_line_assign cur_line; Php_itm_ary cur_ary; Php_key cur_kv_key; - List_adp frame_stack = List_adp_.New(); - public Php_evaluator(Gfo_msg_log msg_log) {this.msg_log = msg_log;} Gfo_msg_log msg_log; + private byte mode = Mode_key_bgn, next_tid = 0, next_mode = 0; + private Php_line_assign cur_line; private Php_itm_ary cur_ary; private Php_key cur_kv_key; + private final List_adp frame_stack = List_adp_.New(); + public Php_evaluator(Gfo_msg_log msg_log) {this.msg_log = msg_log;} private Gfo_msg_log msg_log; public void Init(Php_ctx ctx) {src = ctx.Src(); frame_stack.Clear();} private byte[] src; - public List_adp List() {return lines;} List_adp lines = List_adp_.New(); + public List_adp List() {return lines;} private final List_adp lines = List_adp_.New(); public Gfo_msg_log Msg_log() {return msg_log;} + + public boolean Comments_for_kv() {return comments_for_kv;} public Php_evaluator Comments_for_kv_() {comments_for_kv = true; return this;} private boolean comments_for_kv; public void Clear() { lines.Clear(); msg_log.Clear(); cur_line = null; @@ -40,7 +42,19 @@ public class Php_evaluator implements Php_tkn_wkr { public void Process(Php_tkn tkn) { byte tkn_tid = tkn.Tkn_tid(); switch (tkn_tid) { - case Php_tkn_.Tid_declaration: case Php_tkn_.Tid_comment: case Php_tkn_.Tid_ws: // always discard, regardless of mode + case Php_tkn_.Tid_comment: + // ASSUME: comment is end-line comment for the last kv; EX: " a => b, // comment" + if (comments_for_kv && cur_ary != null) { + int subs_len = cur_ary.Subs_len(); + if (subs_len > 0) { + Php_itm_kv kv = (Php_itm_kv)cur_ary.Subs_get(subs_len - 1); // get last itm + kv.Comments__add(tkn); + } + } + else + return; + break; + case Php_tkn_.Tid_declaration: case Php_tkn_.Tid_ws: // always discard, regardless of mode return; } switch (mode) { diff --git a/400_xowa/src/gplx/langs/phps/Php_itm_kv.java b/400_xowa/src/gplx/langs/phps/Php_itm_kv.java index 4c6a800eb..402578eac 100644 --- a/400_xowa/src/gplx/langs/phps/Php_itm_kv.java +++ b/400_xowa/src/gplx/langs/phps/Php_itm_kv.java @@ -17,6 +17,16 @@ package gplx.langs.phps; import gplx.*; import gplx.langs.*; public class Php_itm_kv implements Php_itm, Php_itm_sub { public byte Itm_tid() {return Php_itm_.Tid_kv;} public byte[] Val_obj_bry() {return null;} - public Php_key Key() {return key;} public Php_itm_kv Key_(Php_key v) {this.key = v; return this;} Php_key key; - public Php_itm Val() {return val;} public Php_itm_kv Val_(Php_itm v) {this.val = v; return this;} Php_itm val; + public Php_key Key() {return key;} public Php_itm_kv Key_(Php_key v) {this.key = v; return this;} private Php_key key; + public Php_itm Val() {return val;} public Php_itm_kv Val_(Php_itm v) {this.val = v; return this;} private Php_itm val; + + private List_adp comments; + public int Comments__len() {return comments == null ? 0 : comments.Len();} + public Php_tkn_comment Comments__get_at__or_null(int i) {return comments == null ? null : (Php_tkn_comment)comments.Get_at(0);} + public void Comments__add(Php_tkn comment) { + if (comments == null) { + comments = List_adp_.New(); + } + comments.Add(comment); + } } diff --git a/400_xowa/src/gplx/langs/phps/Php_lxr.java b/400_xowa/src/gplx/langs/phps/Php_lxr.java index c15d1638e..b580df315 100644 --- a/400_xowa/src/gplx/langs/phps/Php_lxr.java +++ b/400_xowa/src/gplx/langs/phps/Php_lxr.java @@ -22,7 +22,7 @@ interface Php_lxr { int Lxr_make(Php_ctx ctx, int bgn, int cur); } class Php_lxr_ { - public static final byte Tid_declaration = 1, Tid_ws = 2, Tid_comment = 3, Tid_var = 4, Tid_sym = 5, Tid_keyword = 6, Tid_num = 7, Tid_quote = 8; + public static final byte Tid_declaration = 1, Tid_ws = 2, Tid_comment = 3, Tid_var = 4, Tid_sym = 5, Tid_keyword = 6, Tid_num = 7, Tid_quote = 8; } abstract class Php_lxr_base implements Php_lxr { protected byte[] src; protected int src_len; protected Php_tkn_wkr tkn_wkr; protected Php_tkn_factory tkn_factory; @@ -57,7 +57,7 @@ class Php_lxr_declaration extends Php_lxr_base { tkn_wkr.Process(tkn_factory.Declaration(bgn, cur)); return cur; } - private static final byte[] Bry_declaration = Bry_.new_a7(" Causes problems with HTML escaping, don't use +* - % Enabled by default, minor problems with path to query rewrite rules, see below +* - + Enabled by default, but doesn't work with path to query rewrite rules, +* corrupted by apache +* - ? Enabled by default, but doesn't work with path to PATH_INFO rewrites +* +* All three of these punctuation problems can be avoided by using an alias, +* instead of a rewrite rule of either variety. +* +* The problem with % is that when using a path to query rewrite rule, URLs are +* double-unescaped: once by Apache's path conversion code, and again by PHP. So +* %253F, for example, becomes "?". Our code does not double-escape to compensate +* for this, indeed double escaping would break if the double-escaped title was +* passed in the query String rather than the path. This is a minor security issue +* because articles can be created such that they are hard to view or edit. +* +* In some rare cases you may wish to remove + for compatibility with old links. +* +* Theoretically 0x80-0x9F of ISO 8859-1 should be disallowed, but +* this breaks interlanguage links +*/ +// REF.MW: /includes/DefaultSettings.php +class Title_chars_regx { + public boolean Matches(byte[] bry) { + return false; + } +} +// $wgLegalTitleChars = " %!\"$&'()*,\\-.\\/0-9:;=?@A-Z\\\\^_`a-z~\\x80-\\xFF+"; /* + +// */ diff --git a/400_xowa/src/gplx/xowa/langs/names/Xol_name_mgr.java b/400_xowa/src/gplx/xowa/langs/names/Xol_name_mgr.java new file mode 100644 index 000000000..09fa7b7a3 --- /dev/null +++ b/400_xowa/src/gplx/xowa/langs/names/Xol_name_mgr.java @@ -0,0 +1,246 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012-2017 gnosygnu@gmail.com + +XOWA is licensed under the terms of the General Public License (GPL) Version 3, +or alternatively under the terms of the Apache License Version 2.0. + +You may use XOWA according to either of these licenses as is most appropriate +for your project on a case-by-case basis. + +The terms of each license can be found in the source code repository: + +GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt +Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt +*/ +package gplx.xowa.langs.names; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*; +import gplx.core.primitives.*; +import gplx.xowa.xtns.cldrs.*; + +public class Xol_name_mgr { + private final Cldr_name_loader cldr_loader; + private final Language_name_loader name_loader; + private final Io_url root_dir; +// private Ordered_hash hash; +// private Keyval[] kvs; + + public Xol_name_mgr(Cldr_name_loader cldr_loader, Language_name_loader name_loader, Io_url root_dir) { + this.cldr_loader = cldr_loader; + this.name_loader = name_loader; + this.root_dir = root_dir; + } + /** + * @param String $code The code of the language for which to get the name + * @param null|String $inLanguage Code of language in which to return the name (null for autonyms) + * @param String $include 'all', 'mw' or 'mwfile'; see fetchLanguageNames() + * @return String Language name or empty + * @since 1.20 + */ + public String fetchLanguageName(String code, byte[] inLanguage, byte[] include_bry) { + code = String_.Lower(code); + if (include_bry == null) include_bry = fetchLanguageNamesUncached__all__key; + Ordered_hash array = fetchLanguageNames(inLanguage, include_bry); + Keyval rv = (Keyval)array.Get_by(code); + return rv == null ? "" : rv.Val_to_str_or_null(); + } + /** + * Get an array of language names, indexed by code. + * @param null|String $inLanguage Code of language in which to return the names + * Use null for autonyms (native names) + * @param String $include One of: + * 'all' all available languages + * 'mw' only if the language is defined in MediaWiki or wgExtraLanguageNames (default) + * 'mwfile' only if the language is in 'mw' *and* has a message file + * @return array Language code => language name + * @since 1.20 + */ + // = 'mw + private Ordered_hash languageNameCache; + private Ordered_hash lang_names_cached; + private Ordered_hash lang_files_cached; + + private static final byte[] Null_bry = Bry_.new_a7("null"); + public Ordered_hash fetchLanguageNames(byte[] inLanguage, byte[] include_bry) { + byte[] cacheKey = inLanguage == null ? Null_bry : inLanguage; + cacheKey = Bry_.Add(cacheKey, Byte_ascii.Colon_bry, include_bry); + if (languageNameCache == null) + languageNameCache = Ordered_hash_.New_bry(); + Ordered_hash ret = (Ordered_hash)languageNameCache.Get_by(cacheKey); + if (ret == null) { + Byte_obj_val include_byte = (Byte_obj_val)fetchLanguageNamesUncachedEnum.Get_by(include_bry); + byte include = include_byte == null ? fetchLanguageNamesUncached__all : include_byte.Val(); + + Cldr_name_file cldr_file = cldr_loader.Load(String_.new_u8(inLanguage)); + + if (lang_names_cached == null) + lang_names_cached = name_loader.Load_as_hash(); + + if (lang_files_cached == null) { + lang_files_cached = Ordered_hash_.New(); + Io_url[] urls = Io_mgr.Instance.QueryDir_fils(root_dir.GenSubDir_nest("bin", "any", "xowa", "cfg", "lang", "core")); + for (Io_url url : urls) { + String code = url.NameOnly(); + lang_files_cached.Add(code, Keyval_.new_(code, code)); + } + } + + ret = fetchLanguageNamesUncached(inLanguage, include, cldr_file.Language_names(), lang_names_cached, lang_files_cached); + languageNameCache.Add(cacheKey, ret); + } + return ret; + /* + $ret = self::$languageNameCache->get( $cacheKey ); + if ( !$ret ) { + $ret = self::fetchLanguageNamesUncached( $inLanguage, $include ); + self::$languageNameCache->set( $cacheKey, $ret ); + } + return $ret; + */ + } +// public Keyval Get_by_or_null(String code) { +// if (hash == null) Init(); +// return (Keyval)hash.Get_by(code); +// } +// public Keyval[] Get_all() { +// if (hash == null) Init(); +// return kvs; +// } + /* + private static final Hash_adp isValidCode_cache = Hash_adp_bry.cs(); + private static final Strcpn isValidCode_strcpn = Strcpn.New_by_concatenated_ascii(":/\\\000&<>'\""); + private boolean isValidCode(byte[] code) { + Bool_obj_val rv = (Bool_obj_val)isValidCode_cache.Get_by(code); + if (rv == null) { + // People think language codes are html safe, so enforce it. + // Ideally we should only allow a-zA-Z0-9- + // but, .+ and other chars are often used for {{int:}} hacks + // see bugs T39564, T39587, T38938 + rv = + // Protect against path traversal + ( isValidCode_strcpn.Exec(code) == code.length + // && !preg_match( MediaWikiTitleCodec::getTitleInvalidRegex(), $code ); + ) + ? Bool_obj_val.True + : Bool_obj_val.False; + isValidCode_cache.Add(code, rv); + } + return rv.Val(); + } + */ + +// private void Init() { +// Cldr_name_file file = cldr_loader.Load(String_.new_u8(host_lang)); +// Ordered_hash cldr_names = file.Language_names(); +// Ordered_hash lang_names = name_loader.Load_as_hash(); +// +// Ordered_hash lang_files = Ordered_hash_.New(); +// Io_url[] urls = Io_mgr.Instance.QueryDir_fils(root_dir.GenSubDir_nest("bin", "any", "xowa", "cfg", "lang", "core")); +// foreach (Io_url url in urls) { +// String code = url.NameOnly(); +// lang_files.Add(code, Keyval_.new_(code, code)); +// } +// +// hash = fetchLanguageNamesUncached(host_lang, fetchLanguageNamesUncached__mw, cldr_names, lang_names, lang_files); +// kvs = (Keyval[])hash.To_ary(typeof(Keyval)); +// } + + public static final byte + fetchLanguageNamesUncached__mw = 0 // cldr + Names.php + *.json|*.php + , fetchLanguageNamesUncached__all = 1 // cldr + Names.php + , fetchLanguageNamesUncached__mwFile = 2 // *.json|*.php + ; + private static final byte[] fetchLanguageNamesUncached__all__key = Bry_.new_a7("all"); + private static final Hash_adp_bry fetchLanguageNamesUncachedEnum = Hash_adp_bry.cs() + .Add_str_byte("mw", fetchLanguageNamesUncached__mw) + .Add_str_byte("all", fetchLanguageNamesUncached__all) + .Add_str_byte("mwFile", fetchLanguageNamesUncached__mwFile) + ; + public static Ordered_hash fetchLanguageNamesUncached + ( byte[] inLanguage, byte include + , Ordered_hash cldr_names + , Ordered_hash lang_names + , Ordered_hash lang_files + ) { + // XOWA: skip this for now + // If passed an invalid language code to use, fallback to en + // if ( $inLanguage !== null && !Language::isValidCode( $inLanguage ) ) { + // $inLanguage = 'en'; + Ordered_hash names = Ordered_hash_.New(); + + // XOWA: 'LanguageGetTranslatedLanguageNames' is only hooked by cldr_names + // if ( $inLanguage ) { + // # TODO: also include when $inLanguage is null, when this code is more efficient + // Hooks::run( 'LanguageGetTranslatedLanguageNames', [ &$names, $inLanguage ] ); + // } + int cldr_names_len = cldr_names.Len(); + for (int i = 0; i < cldr_names_len; i++) { + Keyval kv = (Keyval)cldr_names.Get_at(i); + names.Add(kv.Key(), kv); + } + + // REF.MW: /includes/DefaultSettings.php + // global $wgExtraLanguageNames; + + // REF.MW: /languages/data/Names.php + // $mwNames = $wgExtraLanguageNames + MediaWiki\Languages\Data\Names::$names; + Ordered_hash mwNames = lang_names; + int mwNames_len = mwNames.Len(); + String inLanguageStr = String_.new_u8(inLanguage); + for (int i = 0; i < mwNames_len; i++) { + Keyval mw_name = (Keyval)mwNames.Get_at(i); + // # - Prefer own MediaWiki native name when not using the hook + // # - For other mwNames just add if not added through the hook + String code = mw_name.Key(); + if (String_.Eq(code, inLanguageStr) || !names.Has(code)) { + names.Add_if_dupe_use_nth(code, Keyval_.new_(code, mw_name.Val_to_str_or_empty())); + } + } + + if (include == fetchLanguageNamesUncached__all) { + names.Sort_by(Hash_kv_sorter.Instance); + return names; + } + + Ordered_hash returnMw = Ordered_hash_.New(); + mwNames_len = mwNames.Len(); + for (int i = 0; i < mwNames_len; i++) { + Keyval coreName = (Keyval)mwNames.Get_at(i); + String code = coreName.Key(); + returnMw.Add(code, (Keyval)names.Get_by(code)); + } + + // REF.MW: /languages/classes/i18n/*.json + // REF.MW: /languages/classes/messages/Messages*.php + if (include == fetchLanguageNamesUncached__mwFile) { + Ordered_hash namesMwFile = Ordered_hash_.New(); + // # We do this using a foreach over the codes instead of a directory + // # loop so that messages files in extensions will work correctly. + int returnMwLen = returnMw.Len(); + for (int i = 0; i < returnMwLen; i++) { + Keyval kv = (Keyval)returnMw.Get_at(i); + String code = kv.Key(); + if (lang_files.Has(code)) { + namesMwFile.Add(code, (Keyval)names.Get_by(code)); + } + } + + namesMwFile.Sort_by(Hash_kv_sorter.Instance); + return namesMwFile; + } + + returnMw .Sort_by(Hash_kv_sorter.Instance); + // # 'mw' option; default if it's not one of the other two options (all/mwfile) + return returnMw; + } + public static Xol_name_mgr New(Io_url root_dir) { + return new Xol_name_mgr(new Cldr_name_loader(root_dir), new Language_name_loader(root_dir), root_dir); + } +} +class Hash_kv_sorter implements gplx.core.lists.ComparerAble { + public int compare(Object lhsObj, Object rhsObj) { + Keyval lhs = (Keyval)lhsObj; + Keyval rhs = (Keyval)rhsObj; + return String_.Compare(lhs.Key(), rhs.Key()); + } + public static final Hash_kv_sorter Instance = new Hash_kv_sorter(); Hash_kv_sorter() {} +} diff --git a/400_xowa/src/gplx/xowa/langs/names/Xol_name_mgr_tst.java b/400_xowa/src/gplx/xowa/langs/names/Xol_name_mgr_tst.java new file mode 100644 index 000000000..b384f302e --- /dev/null +++ b/400_xowa/src/gplx/xowa/langs/names/Xol_name_mgr_tst.java @@ -0,0 +1,115 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012-2017 gnosygnu@gmail.com + +XOWA is licensed under the terms of the General Public License (GPL) Version 3, +or alternatively under the terms of the Apache License Version 2.0. + +You may use XOWA according to either of these licenses as is most appropriate +for your project on a case-by-case basis. + +The terms of each license can be found in the source code repository: + +GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt +Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt +*/ +package gplx.xowa.langs.names; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*; +import org.junit.*; +import gplx.core.tests.*; +import gplx.xowa.xtns.cldrs.*; +public class Xol_name_mgr_tst { + private final Xol_name_mgr_fxt fxt = new Xol_name_mgr_fxt(); + + @Test public void Cldr_only() { + fxt.Test__fetchLanguageNamesUncached + ( "en", Xol_name_mgr.fetchLanguageNamesUncached__all + , fxt.Make__cldr_names("en", "de") + , fxt.Make__lang_names() + , fxt.Make__lang_files() + , fxt.Make__expd_langs + ( "de|de_cldr" + , "en|en_cldr" + )); + } + @Test public void Lang_name__langs() { + fxt.Test__fetchLanguageNamesUncached + ( "en", Xol_name_mgr.fetchLanguageNamesUncached__all + , fxt.Make__cldr_names("en", "de", "es") + , fxt.Make__lang_names("en", "de", "fr") + , fxt.Make__lang_files() + , fxt.Make__expd_langs + ( "de|de_cldr" // do not use de_lange + , "en|en_lang" // use en_lang b/c of "if (String_.Eq(code, inLanguage)" + , "es|es_cldr" // make sure es_lang is still there + , "fr|fr_lang" // add fr_lang + )); + } + @Test public void mwFile() { + fxt.Test__fetchLanguageNamesUncached + ( "en", Xol_name_mgr.fetchLanguageNamesUncached__mwFile + , fxt.Make__cldr_names("en", "de") + , fxt.Make__lang_names("en", "de", "fr") + , fxt.Make__lang_files("en", "de", "es") + , fxt.Make__expd_langs + ( "de|de_cldr" + , "en|en_lang" + )); + } + @Test public void mw() { + fxt.Test__fetchLanguageNamesUncached + ( "en", Xol_name_mgr.fetchLanguageNamesUncached__mw + , fxt.Make__cldr_names("en", "de") + , fxt.Make__lang_names("en", "de", "fr") + , fxt.Make__lang_files("en", "de", "es") + , fxt.Make__expd_langs + ( "de|de_cldr" + , "en|en_lang" + , "fr|fr_lang" + )); + } +} +class Xol_name_mgr_fxt { + public Ordered_hash Make__cldr_names(String... vals) {return Fill(Add_suffix(vals, "_cldr"));} + public Ordered_hash Make__lang_names(String... vals) {return Fill(Add_suffix(vals, "_lang"));} + public Ordered_hash Make__lang_files(String... vals) {return Fill(Add_suffix(vals, "_file"));} + public Ordered_hash Make__expd_langs(String... vals) {return Fill(vals);} + public void Test__fetchLanguageNamesUncached + ( String inLanguage, byte include + , Ordered_hash cldr_names + , Ordered_hash lang_names + , Ordered_hash lang_files + , Ordered_hash expd_langs) { + Ordered_hash actl_langs = Xol_name_mgr.fetchLanguageNamesUncached(Bry_.new_u8(inLanguage), include, cldr_names, lang_names, lang_files); + Gftest.Eq__ary(To_str_ary(expd_langs), To_str_ary(actl_langs)); + } + private static String[] Add_suffix(String[] ary, String val_suffix) { + int len = ary.length; + for (int i = 0; i < len; i++) { + String itm = ary[i]; + ary[i] = itm + "|" + itm + val_suffix; + } + return ary; + } + private static String[] To_str_ary(Ordered_hash hash) { + int len = hash.Len(); + String[] rv = new String[len]; + for (int i = 0; i < len; i++) { + Keyval kv = (Keyval)hash.Get_at(i); + rv[i] = kv.Key() + "|" + kv.Val(); + } + return rv; + } + private static Ordered_hash Fill(String... ary) { + Ordered_hash hash = Ordered_hash_.New(); + int len = ary.length; + for (int i = 0; i < len; i++) { + Keyval kv = Split(ary[i]); + hash.Add(kv.Key(), kv); + } + return hash; + } + private static Keyval Split(String str) { + String[] ary = String_.Split(str, "|"); + return Keyval_.new_(ary[0], ary.length == 1 ? ary[0] : ary[1]); + } +} diff --git a/400_xowa/src/gplx/xowa/langs/parsers/Xol_lang_srl_tst.java b/400_xowa/src/gplx/xowa/langs/parsers/Xol_lang_srl_tst.java index 915140a18..b303bf2f0 100644 --- a/400_xowa/src/gplx/xowa/langs/parsers/Xol_lang_srl_tst.java +++ b/400_xowa/src/gplx/xowa/langs/parsers/Xol_lang_srl_tst.java @@ -17,7 +17,7 @@ package gplx.xowa.langs.parsers; import gplx.*; import gplx.xowa.*; import gplx. import org.junit.*; import gplx.core.strings.*; import gplx.core.intls.*; import gplx.xowa.apps.gfs.*; -import gplx.xowa.langs.numbers.*; import gplx.xowa.langs.msgs.*; import gplx.xowa.langs.kwds.*; import gplx.xowa.langs.bldrs.*; import gplx.xowa.langs.specials.*; +import gplx.xowa.langs.numbers.*; import gplx.xowa.langs.msgs.*; import gplx.xowa.langs.kwds.*; import gplx.xowa.langs.bldrs.*; import gplx.xowa.langs.specials.*; import gplx.xowa.langs.names.*; import gplx.xowa.wikis.nss.*; public class Xol_lang_srl_tst { private Xol_lang_srl_fxt fxt = new Xol_lang_srl_fxt(); @@ -165,7 +165,7 @@ public class Xol_lang_srl_tst { @Test public void Fallback_circular() { // PURPOSE: pt and pt-br cite each other as fallback in Messages*.php; DATE:2013-02-18 Io_mgr.Instance.SaveFilStr(Xol_lang_itm_.xo_lang_fil_(fxt.App().Fsys_mgr(), "pt") , "fallback_load('pt-br');"); Io_mgr.Instance.SaveFilStr(Xol_lang_itm_.xo_lang_fil_(fxt.App().Fsys_mgr(), "pt-br") , "fallback_load('pt');"); - Xol_lang_itm lang = new Xol_lang_itm(fxt.App().Lang_mgr(), Bry_.new_a7("pt")); + Xol_lang_itm lang = Xol_lang_itm.New(fxt.App().Lang_mgr(), Bry_.new_a7("pt")); lang.Init_by_load(); } @Test public void Num_fmt() { @@ -201,7 +201,7 @@ public class Xol_lang_srl_tst { class Xol_lang_srl_fxt { public void Clear() { app = Xoa_app_fxt.Make__app__edit(); - lang = new Xol_lang_itm(app.Lang_mgr(), Bry_.new_a7("fr")); + lang = Xol_lang_itm.New(app.Lang_mgr(), Bry_.new_a7("fr")); Xoa_gfs_mgr.Msg_parser_init(); // required by fallback_load } GfsCtx ctx = GfsCtx.new_(); Xoa_gfs_bldr bldr = new Xoa_gfs_bldr(); //Bry_bfr tmp_bfr = Bry_bfr_.Reset(255); public Xoae_app App() {return app;} private Xoae_app app; diff --git a/400_xowa/src/gplx/xowa/parsers/Xop_tkn_mkr.java b/400_xowa/src/gplx/xowa/parsers/Xop_tkn_mkr.java index 8400445cb..a4b566b26 100644 --- a/400_xowa/src/gplx/xowa/parsers/Xop_tkn_mkr.java +++ b/400_xowa/src/gplx/xowa/parsers/Xop_tkn_mkr.java @@ -93,6 +93,7 @@ public class Xop_tkn_mkr { public gplx.xowa.xtns.wikias.Random_selection_xnde Xnde__random_selection() {return new gplx.xowa.xtns.wikias.Random_selection_xnde();} public gplx.xowa.xtns.wikias.Tabber_xnde Xnde__tabber() {return new gplx.xowa.xtns.wikias.Tabber_xnde();} public gplx.xowa.xtns.wikias.Tabview_xnde Xnde__tabview() {return new gplx.xowa.xtns.wikias.Tabview_xnde();} + public gplx.xowa.xtns.template_styles.Template_styles_nde Xnde__template_styles() {return new gplx.xowa.xtns.template_styles.Template_styles_nde();} public gplx.xowa.xtns.translates.Xop_tvar_tkn Tvar(int tkn_bgn, int tkn_end, int key_bgn, int key_end, int txt_bgn, int txt_end, byte[] wikitext) {return new gplx.xowa.xtns.translates.Xop_tvar_tkn(tkn_bgn, tkn_end, key_bgn, key_end, txt_bgn, txt_end, wikitext);} // public void Clear() { diff --git a/400_xowa/src/gplx/xowa/parsers/xndes/Xop_xnde_tag_.java b/400_xowa/src/gplx/xowa/parsers/xndes/Xop_xnde_tag_.java index b9738b3df..047f600f9 100644 --- a/400_xowa/src/gplx/xowa/parsers/xndes/Xop_xnde_tag_.java +++ b/400_xowa/src/gplx/xowa/parsers/xndes/Xop_xnde_tag_.java @@ -145,8 +145,9 @@ public class Xop_xnde_tag_ { , Tid__maplink = 120 , Tid__meta = 121 , Tid__link = 122 +, Tid__template_styles = 123 ; - public static final int Tid__len = 123; + public static final int Tid__len = 124; public static final Xop_xnde_tag[] Ary = new Xop_xnde_tag[Tid__len]; private static Xop_xnde_tag New(int id, String name) { Xop_xnde_tag rv = new Xop_xnde_tag(id, name); @@ -277,5 +278,6 @@ public class Xop_xnde_tag_ { , Tag__maplink = New(Tid__maplink, "maplink").Xtn_mw_() , Tag__meta = New(Tid__meta, "meta") , Tag__link = New(Tid__link, "link") +, Tag__template_styles = New(Tid__template_styles, "templatestyles").Xtn_() ; } diff --git a/400_xowa/src/gplx/xowa/parsers/xndes/Xop_xnde_wkr.java b/400_xowa/src/gplx/xowa/parsers/xndes/Xop_xnde_wkr.java index c7d88e77d..6a94b1933 100644 --- a/400_xowa/src/gplx/xowa/parsers/xndes/Xop_xnde_wkr.java +++ b/400_xowa/src/gplx/xowa/parsers/xndes/Xop_xnde_wkr.java @@ -653,6 +653,7 @@ public class Xop_xnde_wkr implements Xop_ctx_wkr { case Xop_xnde_tag_.Tid__random_selection: xnde_xtn = tkn_mkr.Xnde__random_selection(); break; case Xop_xnde_tag_.Tid__tabber: xnde_xtn = tkn_mkr.Xnde__tabber(); break; case Xop_xnde_tag_.Tid__tabview: xnde_xtn = tkn_mkr.Xnde__tabview(); break; + case Xop_xnde_tag_.Tid__template_styles: xnde_xtn = tkn_mkr.Xnde__template_styles(); break; case Xop_xnde_tag_.Tid__listing_buy: case Xop_xnde_tag_.Tid__listing_do: case Xop_xnde_tag_.Tid__listing_drink: diff --git a/400_xowa/src/gplx/xowa/wikis/Xoae_wiki_mgr.java b/400_xowa/src/gplx/xowa/wikis/Xoae_wiki_mgr.java index fc43f2ef3..2582afa0c 100644 --- a/400_xowa/src/gplx/xowa/wikis/Xoae_wiki_mgr.java +++ b/400_xowa/src/gplx/xowa/wikis/Xoae_wiki_mgr.java @@ -15,7 +15,7 @@ Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt */ package gplx.xowa.wikis; import gplx.*; import gplx.xowa.*; import gplx.xowa.langs.*; import gplx.xowa.xtns.wbases.*; -import gplx.xowa.wikis.domains.*; import gplx.xowa.wikis.domains.crts.*; import gplx.xowa.wikis.nss.*; import gplx.xowa.wikis.metas.*; +import gplx.xowa.wikis.domains.*; import gplx.xowa.wikis.domains.crts.*; import gplx.xowa.wikis.nss.*; import gplx.xowa.wikis.metas.*; import gplx.xowa.langs.names.*; import gplx.xowa.addons.wikis.directorys.dbs.*; public class Xoae_wiki_mgr implements Xoa_wiki_mgr, Gfo_invk { private final Xoae_app app; @@ -87,7 +87,7 @@ public class Xoae_wiki_mgr implements Xoa_wiki_mgr, Gfo_invk { if (lang_key == Xol_lang_stub_.Key__unknown) lang_key = Xol_lang_itm_.Key_en; // unknown langs default to english; note that this makes nonwmf english by default Xol_lang_itm lang = app.Lang_mgr().Get_by_or_new(lang_key); if (domain_itm.Domain_type_id() == Xow_domain_tid_.Tid__other) { - lang = new Xol_lang_itm(app.Lang_mgr(), Xol_lang_itm_.Key_en).Kwd_mgr__strx_(true); // create a new english lang, but enable strx functions; DATE:2015-08-23 + lang = Xol_lang_itm.New(app.Lang_mgr(), Xol_lang_itm_.Key_en).Kwd_mgr__strx_(true); // create a new english lang, but enable strx functions; DATE:2015-08-23 Xol_lang_itm_.Lang_init(lang); } diff --git a/400_xowa/src/gplx/xowa/xtns/Xow_xtn_mgr.java b/400_xowa/src/gplx/xowa/xtns/Xow_xtn_mgr.java index 3724b33e4..ca1917221 100644 --- a/400_xowa/src/gplx/xowa/xtns/Xow_xtn_mgr.java +++ b/400_xowa/src/gplx/xowa/xtns/Xow_xtn_mgr.java @@ -47,6 +47,7 @@ public class Xow_xtn_mgr implements Gfo_invk { Add(app, new gplx.xowa.xtns.pfuncs.scribunto.Pfunc_xtn_mgr()); Add(app, new gplx.xowa.xtns.flaggedRevs.Flagged_revs_xtn_mgr()); Add(app, new gplx.xowa.xtns.jsonConfigs.scribunto.Jscfg_xtn_mgr()); + Add(app, new gplx.xowa.xtns.cldrs.Cldr_name_xtn_mgr()); return this; } public Xow_xtn_mgr Ctor_by_wiki(Xowe_wiki wiki) { diff --git a/400_xowa/src/gplx/xowa/xtns/cldrs/Cldr_name_loader.java b/400_xowa/src/gplx/xowa/xtns/cldrs/Cldr_name_loader.java index 6170f5e43..a5d4d7bc6 100644 --- a/400_xowa/src/gplx/xowa/xtns/cldrs/Cldr_name_loader.java +++ b/400_xowa/src/gplx/xowa/xtns/cldrs/Cldr_name_loader.java @@ -20,8 +20,8 @@ public class Cldr_name_loader { private final Io_url cldr_dir; private final Hash_adp hash = Hash_adp_.New(); - public Cldr_name_loader(Io_url xowa_xtn_dir) { - cldr_dir = xowa_xtn_dir.GenSubDir_nest("cldr", "CldrNames"); + public Cldr_name_loader(Io_url root_dir) { + cldr_dir = root_dir.GenSubDir_nest("bin", "any", "xowa", "xtns", "cldr", "CldrNames"); } public Cldr_name_file Load(String lang_key) { diff --git a/400_xowa/src/gplx/xowa/xtns/cldrs/Cldr_name_xtn_mgr.java b/400_xowa/src/gplx/xowa/xtns/cldrs/Cldr_name_xtn_mgr.java new file mode 100644 index 000000000..027443065 --- /dev/null +++ b/400_xowa/src/gplx/xowa/xtns/cldrs/Cldr_name_xtn_mgr.java @@ -0,0 +1,24 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012-2017 gnosygnu@gmail.com + +XOWA is licensed under the terms of the General Public License (GPL) Version 3, +or alternatively under the terms of the Apache License Version 2.0. + +You may use XOWA according to either of these licenses as is most appropriate +for your project on a case-by-case basis. + +The terms of each license can be found in the source code repository: + +GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt +Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt +*/ +package gplx.xowa.xtns.cldrs; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; +public class Cldr_name_xtn_mgr extends Xox_mgr_base { +// private Cldr_name_loader loader; + @Override public byte[] Xtn_key() {return XTN_KEY;} public static final byte[] XTN_KEY = Bry_.new_a7("CldrNames"); + @Override public Xox_mgr Xtn_clone_new() {return new Cldr_name_xtn_mgr();} + @Override public void Xtn_init_by_wiki(Xowe_wiki wiki) { +// loader = new Cldr_name_loader(wiki.App().Fsys_mgr().Bin_xtns_dir()); + } +} diff --git a/400_xowa/src/gplx/xowa/xtns/cldrs/Language_name.java b/400_xowa/src/gplx/xowa/xtns/cldrs/Language_name.java new file mode 100644 index 000000000..e528ea96e --- /dev/null +++ b/400_xowa/src/gplx/xowa/xtns/cldrs/Language_name.java @@ -0,0 +1,31 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012-2017 gnosygnu@gmail.com + +XOWA is licensed under the terms of the General Public License (GPL) Version 3, +or alternatively under the terms of the Apache License Version 2.0. + +You may use XOWA according to either of these licenses as is most appropriate +for your project on a case-by-case basis. + +The terms of each license can be found in the source code repository: + +GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt +Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt +*/ +package gplx.xowa.xtns.cldrs; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; +public class Language_name implements gplx.core.brys.Bry_bfr_able { + public Language_name(byte[] code, byte[] name, byte[] note) { + this.code = code; + this.name = name; + this.note = note; + } + public byte[] Code() {return code;} private final byte[] code; + public byte[] Name() {return name;} private final byte[] name; + public byte[] Note() {return note;} private final byte[] note; + public void To_bfr(Bry_bfr bfr) { + bfr.Add(code).Add_byte_pipe(); + bfr.Add(name).Add_byte_pipe(); + bfr.Add(note); + } +} diff --git a/400_xowa/src/gplx/xowa/xtns/cldrs/Language_name_loader.java b/400_xowa/src/gplx/xowa/xtns/cldrs/Language_name_loader.java new file mode 100644 index 000000000..5e89bcb41 --- /dev/null +++ b/400_xowa/src/gplx/xowa/xtns/cldrs/Language_name_loader.java @@ -0,0 +1,57 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012-2017 gnosygnu@gmail.com + +XOWA is licensed under the terms of the General Public License (GPL) Version 3, +or alternatively under the terms of the Apache License Version 2.0. + +You may use XOWA according to either of these licenses as is most appropriate +for your project on a case-by-case basis. + +The terms of each license can be found in the source code repository: + +GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt +Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt +*/ +package gplx.xowa.xtns.cldrs; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; +import gplx.langs.jsons.*; +public class Language_name_loader { + private final Json_parser parser = new Json_parser(); + private final Io_url names_url; + + public Language_name_loader(Io_url root_dir) { + names_url = root_dir.GenSubFil_nest("bin", "any", "xowa", "cfg", "lang", "data", "names.json"); + } + public Ordered_hash Load_as_hash() { + byte[] json = Io_mgr.Instance.LoadFilBry(names_url); + if (json == null) { + Gfo_usr_dlg_.Instance.Warn_many("", "", "no names file exists"); + return Ordered_hash_.New(); + } + Language_name[] ary = Load(json); + + // convert + Ordered_hash rv = Ordered_hash_.New(); + int len = ary.length; + for (int i = 0; i < len; i++) { + Language_name itm = ary[i]; + rv.Add(itm.Code(), Keyval_.new_(String_.new_u8(itm.Code()), itm.Name())); + } + return rv; + } + public Language_name[] Load(byte[] json) { + List_adp list = List_adp_.New(); + + Json_doc jdoc = parser.Parse(json); + Json_ary root = jdoc.Root_ary(); + int len = root.Len(); + for (int i = 0; i < len; i++) { + Json_nde node = root.Get_as_nde(i); + byte[] code = node.Get_as_bry("code"); + byte[] name = node.Get_as_bry("name"); + Language_name itm = new Language_name(code, name, null); + list.Add(itm); + } + return (Language_name[])list.To_ary_and_clear(Language_name.class); + } +} diff --git a/400_xowa/src/gplx/xowa/xtns/cldrs/Language_names_converter.java b/400_xowa/src/gplx/xowa/xtns/cldrs/Language_names_converter.java new file mode 100644 index 000000000..8d552e8a0 --- /dev/null +++ b/400_xowa/src/gplx/xowa/xtns/cldrs/Language_names_converter.java @@ -0,0 +1,93 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012-2017 gnosygnu@gmail.com + +XOWA is licensed under the terms of the General Public License (GPL) Version 3, +or alternatively under the terms of the Apache License Version 2.0. + +You may use XOWA according to either of these licenses as is most appropriate +for your project on a case-by-case basis. + +The terms of each license can be found in the source code repository: + +GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt +Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt +*/ +package gplx.xowa.xtns.cldrs; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; +import gplx.core.primitives.*; +import gplx.langs.phps.*; +import gplx.langs.jsons.*; + +// REF.MW: /languages/data/Names.php +class Language_names_converter { + private final Php_parser parser = new Php_parser(); + private final Php_evaluator eval = new Php_evaluator(new gplx.core.log_msgs.Gfo_msg_log("test")).Comments_for_kv_(); + private final Php_text_itm_parser text_itm_parser = new Php_text_itm_parser().Quote_is_single_(true); + private final List_adp tmp_list = List_adp_.New(); + private final Byte_obj_ref tmp_result = Byte_obj_ref.zero_(); + private final Bry_bfr tmp_bfr = Bry_bfr_.New(); + + public Language_name[] Parse_fil(Io_url url) { + byte[] src = Io_mgr.Instance.LoadFilBry(url); + int bgn = Bry_find_.Find_fwd(src, Bry_.new_a7("$names")); + int end = Bry_find_.Find_bwd(src, Bry_.new_a7("];"), src.length); + return Parse(Bry_.Mid(src, bgn, end)); + } + public Language_name[] Parse(byte[] src) { + parser.Parse_tkns(src, eval); + Php_line[] lines = (Php_line[])eval.List().To_ary(Php_line.class); + + List_adp rv = List_adp_.New(); + int lines_len = lines.length; + for (int i = 0; i < lines_len; i++) { + Php_line line = lines[i]; + Php_line_assign assign_line = (Php_line_assign)line; + + byte[][][] ary = Parse_ary_kvs(src, assign_line); + for (byte[][] itm : ary) { + rv.Add(new Language_name(itm[0], itm[1], itm[2])); + } + } + eval.Clear(); + return (Language_name[])rv.To_ary_and_clear(Language_name.class); + } + private byte[][][] Parse_ary_kvs(byte[] src, Php_line_assign assign) { + List_adp list = List_adp_.New(); + Php_itm_ary ary = (Php_itm_ary)assign.Val(); + int ary_len = ary.Subs_len(); + for (int i = 0; i < ary_len; i++) { + Php_itm_kv kv = (Php_itm_kv)ary.Subs_get(i); + byte[] key = kv.Key().Val_obj_bry(); + byte[] val = text_itm_parser.Parse_as_bry(tmp_list, kv.Val().Val_obj_bry(), tmp_result, tmp_bfr); + + int comments_len = kv.Comments__len(); + for (int j = 0; j < comments_len; j++) { + if (j != 0) tmp_bfr.Add_byte_space(); + Php_tkn_comment tkn = kv.Comments__get_at__or_null(j); + tkn.To_bfr(tmp_bfr, src, true); + } + byte[] comm = tmp_bfr.To_bry_and_clear(); + list.Add(new byte[][] {key, val, comm}); + } + return (byte[][][])list.To_ary_and_clear(byte[][].class); + } + public String To_json(Language_name[] ary) { + Json_doc_wtr doc_wtr = new Json_doc_wtr(); + doc_wtr.Ary_bgn(); + int len = ary.length; + byte[] key_code = Bry_.new_a7("code"); + byte[] key_name = Bry_.new_a7("name"); + byte[] key_note = Bry_.new_a7("note"); + for (int i = 0; i < len; i++) { + if (i != 0) doc_wtr.Comma(); + doc_wtr.Nde_bgn(); + Language_name itm = ary[i]; + doc_wtr.Kv(Bool_.N, key_code, itm.Code()); + doc_wtr.Kv(Bool_.Y, key_name, itm.Name()); + doc_wtr.Kv(Bool_.Y, key_note, itm.Note()); + doc_wtr.Nde_end(); + } + doc_wtr.Ary_end(); + return doc_wtr.Bld_as_str(); + } +} diff --git a/400_xowa/src/gplx/xowa/xtns/cldrs/Language_names_converter_tst.java b/400_xowa/src/gplx/xowa/xtns/cldrs/Language_names_converter_tst.java new file mode 100644 index 000000000..5a960c731 --- /dev/null +++ b/400_xowa/src/gplx/xowa/xtns/cldrs/Language_names_converter_tst.java @@ -0,0 +1,71 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012-2017 gnosygnu@gmail.com + +XOWA is licensed under the terms of the General Public License (GPL) Version 3, +or alternatively under the terms of the Apache License Version 2.0. + +You may use XOWA according to either of these licenses as is most appropriate +for your project on a case-by-case basis. + +The terms of each license can be found in the source code repository: + +GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt +Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt +*/ +package gplx.xowa.xtns.cldrs; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; +import org.junit.*; import gplx.core.tests.*; +import gplx.langs.phps.*; +import gplx.langs.jsons.*; +public class Language_names_converter_tst { + private final Language_names_converter_fxt fxt = new Language_names_converter_fxt(); + @Test public void Parse_fil() { + fxt.Exec__Parse(String_.Concat_lines_nl + ( "/*ignore_bgn*/ $names = [" + , " 'aa' => 'Afar', # comment_a " + , " 'mic' => 'Mikmaq', # comment_m " + , " 'zza' => 'Zaza', # comment_z " + , "]; /*ignore_end*/" + ) + , new Language_name[] + { fxt.Make__language_name("aa", "Afar", "comment_a") + , fxt.Make__language_name("mic", "Mikmaq", "comment_m") + , fxt.Make__language_name("zza", "Zaza", "comment_z") + }, Json_doc.Make_str_by_apos + ( "[" + , " {" + , " 'code':'aa'" + , " , 'name':'Afar'" + , " , 'note':'comment_a'" + , " }" + , "," + , " {" + , " 'code':'mic'" + , " , 'name':'Mikmaq'" + , " , 'note':'comment_m'" + , " }" + , "," + , " {" + , " 'code':'zza'" + , " , 'name':'Zaza'" + , " , 'note':'comment_z'" + , " }" + , "]" + )); + } + @Test public void Convert() { + Language_names_converter converter = new Language_names_converter(); + Language_name[] names = converter.Parse_fil(Io_url_.new_dir_("C:\\000\\100_bin\\200_server\\200_http\\100_apache\\100_v2.4\\htdocs\\mediawiki\\v1.29.1\\languages\\data\\Names.php")); + String json = converter.To_json(names); + Io_mgr.Instance.SaveFilStr(Io_url_.new_fil_("C:\\xowa\\bin\\any\\xowa\\cfg\\lang\\data\\names.json"), json); + } +} +class Language_names_converter_fxt { + private final Language_names_converter converter = new Language_names_converter(); + public Language_name Make__language_name(String code, String name, String note) {return new Language_name(Bry_.new_u8(code), Bry_.new_u8(name), Bry_.new_u8(note));} + public void Exec__Parse(String src, Language_name[] expd_names, String expd_json) { + Language_name[] actl = converter.Parse(Bry_.new_u8(src)); + Gftest.Eq__ary(expd_names, actl); + Gftest.Eq__ary__lines(expd_json, converter.To_json(actl)); + } +} diff --git a/400_xowa/src/gplx/xowa/xtns/jsonConfigs/scribunto/Jscfg_scrib_lib_tst.java b/400_xowa/src/gplx/xowa/xtns/jsonConfigs/scribunto/Jscfg_scrib_lib_tst.java index 557c708d8..0a4a24aa4 100644 --- a/400_xowa/src/gplx/xowa/xtns/jsonConfigs/scribunto/Jscfg_scrib_lib_tst.java +++ b/400_xowa/src/gplx/xowa/xtns/jsonConfigs/scribunto/Jscfg_scrib_lib_tst.java @@ -16,7 +16,7 @@ Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt package gplx.xowa.xtns.jsonConfigs.scribunto; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.jsonConfigs.*; import org.junit.*; import gplx.core.tests.*; import gplx.xowa.xtns.scribunto.*; import gplx.xowa.xtns.scribunto.libs.*; -import gplx.xowa.langs.*; +import gplx.xowa.langs.*; import gplx.xowa.langs.names.*; import gplx.langs.jsons.*; public class Jscfg_scrib_lib_tst { private final Jscfg_scrib_lib_fxt fxt = new Jscfg_scrib_lib_fxt(); @@ -150,7 +150,7 @@ class Jscfg_scrib_lib_fxt { fxt.Parser_fxt().Init_page_create(commons_wiki, page, text); } public Xol_lang_itm Init__lang(String key, String fallbacks) { - Xol_lang_itm lang = new Xol_lang_itm(fxt.Core().App().Lang_mgr(), Bry_.new_u8(key)); + Xol_lang_itm lang = Xol_lang_itm.New(fxt.Core().App().Lang_mgr(), Bry_.new_u8(key)); lang.Fallback_bry_(Bry_.new_a7(fallbacks)); return lang; } diff --git a/400_xowa/src/gplx/xowa/xtns/pfuncs/numbers/Pf_formatnum_es_tst.java b/400_xowa/src/gplx/xowa/xtns/pfuncs/numbers/Pf_formatnum_es_tst.java index b26058c0d..ddcbe0592 100644 --- a/400_xowa/src/gplx/xowa/xtns/pfuncs/numbers/Pf_formatnum_es_tst.java +++ b/400_xowa/src/gplx/xowa/xtns/pfuncs/numbers/Pf_formatnum_es_tst.java @@ -15,12 +15,12 @@ Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt */ package gplx.xowa.xtns.pfuncs.numbers; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*; import org.junit.*; import gplx.xowa.langs.*; -import gplx.core.intls.*; import gplx.xowa.langs.numbers.*; +import gplx.core.intls.*; import gplx.xowa.langs.numbers.*; import gplx.xowa.langs.names.*; public class Pf_formatnum_es_tst { private Xop_fxt fxt; @Before public void init() { Xoae_app app = Xoa_app_fxt.Make__app__edit(); - Xol_lang_itm lang = new Xol_lang_itm(app.Lang_mgr(), Bry_.new_a7("es")).Init_by_load_assert(); + Xol_lang_itm lang = Xol_lang_itm.New(app.Lang_mgr(), Bry_.new_a7("es")).Init_by_load_assert(); Xowe_wiki wiki = Xoa_app_fxt.Make__wiki__edit(app, "es.wikipedia.org", lang); fxt = new Xop_fxt(app, wiki); } diff --git a/400_xowa/src/gplx/xowa/xtns/pfuncs/numbers/Pf_formatnum_fa_tst.java b/400_xowa/src/gplx/xowa/xtns/pfuncs/numbers/Pf_formatnum_fa_tst.java index f7208b651..8b8241326 100644 --- a/400_xowa/src/gplx/xowa/xtns/pfuncs/numbers/Pf_formatnum_fa_tst.java +++ b/400_xowa/src/gplx/xowa/xtns/pfuncs/numbers/Pf_formatnum_fa_tst.java @@ -15,12 +15,13 @@ Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt */ package gplx.xowa.xtns.pfuncs.numbers; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*; import org.junit.*; -import gplx.core.intls.*; import gplx.xowa.langs.*; import gplx.xowa.langs.numbers.*; +import gplx.core.intls.*; +import gplx.xowa.langs.*; import gplx.xowa.langs.numbers.*; import gplx.xowa.langs.names.*; public class Pf_formatnum_fa_tst { private Xop_fxt fxt; @Before public void init() { Xoae_app app = Xoa_app_fxt.Make__app__edit(); - Xol_lang_itm lang = new Xol_lang_itm(app.Lang_mgr(), Bry_.new_a7("fa")).Init_by_load_assert(); + Xol_lang_itm lang = Xol_lang_itm.New(app.Lang_mgr(), Bry_.new_a7("fa")).Init_by_load_assert(); app.Gfs_mgr().Run_str_for(lang, Persian_numbers_gfs); Xowe_wiki wiki = Xoa_app_fxt.Make__wiki__edit(app, "fa.wikipedia.org", lang); fxt = new Xop_fxt(app, wiki); @@ -31,7 +32,7 @@ public class Pf_formatnum_fa_tst { @Test public void English() { // PURPOSE: make sure regular numbers are still read; DATE:2015-07-18 fxt.Test_parse_tmpl_str_test("{{formatnum:150|R}}" , "{{test}}", "150"); } - public static final String Persian_numbers_gfs = String_.Concat_lines_nl + public static final String Persian_numbers_gfs = String_.Concat_lines_nl ( "numbers {" , " digits {" , " clear;" diff --git a/400_xowa/src/gplx/xowa/xtns/pfuncs/strings/Pfunc_tag_kvp_wtr.java b/400_xowa/src/gplx/xowa/xtns/pfuncs/strings/Pfunc_tag_kvp_wtr.java index 3e64cd514..78c6fb344 100644 --- a/400_xowa/src/gplx/xowa/xtns/pfuncs/strings/Pfunc_tag_kvp_wtr.java +++ b/400_xowa/src/gplx/xowa/xtns/pfuncs/strings/Pfunc_tag_kvp_wtr.java @@ -28,7 +28,8 @@ class Pfunc_tag_kvp_wtr { if (key_bgn != -1) tmp.Add_byte(Byte_ascii.Eq); tmp.Add_byte(Byte_ascii.Quote); - gplx.langs.htmls.encoders.Gfo_url_encoder_.Id.Encode(tmp, kvp_bry, val_bgn, val_end);// PURPOSE: escape html in atrs; PAGE:fr.v:France; DATE:2017-06-01 + // gplx.langs.htmls.encoders.Gfo_url_encoder_.Id.Encode(tmp, kvp_bry, val_bgn, val_end);// PURPOSE: escape html in atrs; PAGE:fr.w:France; DATE:2017-06-01 + gplx.langs.htmls.Gfh_utl.Escape_html_to_bfr(tmp, kvp_bry, val_bgn, val_end, true, true, true, true, true); tmp.Add_byte(Byte_ascii.Quote); } } diff --git a/400_xowa/src/gplx/xowa/xtns/pfuncs/strings/Pfunc_tag_tst.java b/400_xowa/src/gplx/xowa/xtns/pfuncs/strings/Pfunc_tag_tst.java index 85857e4b7..a3960d2a4 100644 --- a/400_xowa/src/gplx/xowa/xtns/pfuncs/strings/Pfunc_tag_tst.java +++ b/400_xowa/src/gplx/xowa/xtns/pfuncs/strings/Pfunc_tag_tst.java @@ -27,7 +27,7 @@ public class Pfunc_tag_tst { @Test public void Ws_all() {fxt.Test_html_full_str("{{#tag:pre|a| id = b }}" , "
a
");} @Test public void Ws_quoted() {fxt.Test_html_full_str("{{#tag:pre|a| id = ' b ' }}" , "
a
");} @Test public void Err_bad_key() {fxt.Test_html_full_str("{{#tag:pre|a|id=val|b}}" , "
a
");} // PURPOSE: b was failing b/c id was larger and key_end set to 4 (whereas b was len=1) - @Test public void Html_is_escaped() {fxt.Test_html_full_str("{{#tag:pre|a|id='
'}}" , "
a
");} // PURPOSE: escape html in atrs; PAGE:fr.v:France; DATE:2017-06-01 + @Test public void Html_is_escaped() {fxt.Test_html_full_str("{{#tag:pre|a|id='
'}}" , "
a
");} // PURPOSE: escape html in atrs; PAGE:fr.w:France; DATE:2017-06-01 // @Test public void Missing_val() {fxt.ini_Msg(Mwl_tag_rsc.Instance.Invalid).Test_parse_tmpl_str_test("{{#tag:pre|a|id=}}" , "{{test}}" , "");} // see {{Reflist|colwidth=30em}} -> a{{#tag:references||group=}} -> "" // @Test public void Err() { // fxt.Test_parse_tmpl_str_test("{{#tag:ref|George Robertson announced in January 2003 that he would be stepping down in December. {{cite news|title =NATO Secretary General to Leave His Post in December After 4 Years |first = Craig | last = Smith | work = The New York Times | date = January 23, 2003| url = http://www.nytimes.com/2003/01/23/world/nato-secretary-general-to-leave-his-post-in-december-after-4-years.html?scp=2&sq=lord+robertson&st=nyt|accessdate = 2009-03-29}} Jaap de Hoop Scheffer was selected as his successor, but could not assume the office until January 2004 because of his commitment in the Dutch Parliament. {{cite news|title = Jaap de Hoop Scheffer | work = Newsmakers | issue = 1 | publisher = Thomson Gale | date = January 1, 2005}} Robertson was asked to extend his term until Scheffer was ready, but declined, so Minuto-Rizzo, the Deputy Secretary General, took over in the interim. |group=N|}}" diff --git a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_language.java b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_language.java index e602c7481..c35b30597 100644 --- a/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_language.java +++ b/400_xowa/src/gplx/xowa/xtns/scribunto/libs/Scrib_lib_language.java @@ -130,6 +130,11 @@ public class Scrib_lib_language implements Scrib_lib { return rslt.Init_obj(valid); } public boolean FetchLanguageName(Scrib_proc_args args, Scrib_proc_rslt rslt) { + String lang_code = args.Pull_str(0); + byte[] inLanguage = args.Pull_bry(1); + String rv = core.App().Lang_mgr().Name_mgr().fetchLanguageName(lang_code, inLanguage, null); + return rslt.Init_obj(rv); + /* byte[] lang_code = args.Pull_bry(0); // byte[] trans_code = args.Get_bry_or_null(1); // TODO_OLD: FetchLanguageName("en", "fr") -> Anglais; WHEN: needs global database of languages; cldr Xol_lang_stub lang_itm = Xol_lang_stub_.Get_by_key_or_null(lang_code); @@ -137,6 +142,7 @@ public class Scrib_lib_language implements Scrib_lib { ? "" // unknown -> return ""; PAGE:en.w:United_States_Strategic_Bombing_Survey; DATE:2018-07-01 : String_.new_u8(lang_itm.Canonical_name()); // known -> return canonical name return rslt.Init_obj(rv); + */ } public boolean FetchLanguageNames(Scrib_proc_args args, Scrib_proc_rslt rslt) { // byte[] lang_code = args.Cast_bry_or_null(0); diff --git a/400_xowa/src/gplx/xowa/xtns/template_styles/Template_styles_nde.java b/400_xowa/src/gplx/xowa/xtns/template_styles/Template_styles_nde.java new file mode 100644 index 000000000..2669fd9b5 --- /dev/null +++ b/400_xowa/src/gplx/xowa/xtns/template_styles/Template_styles_nde.java @@ -0,0 +1,76 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012-2017 gnosygnu@gmail.com + +XOWA is licensed under the terms of the General Public License (GPL) Version 3, +or alternatively under the terms of the Apache License Version 2.0. + +You may use XOWA according to either of these licenses as is most appropriate +for your project on a case-by-case basis. + +The terms of each license can be found in the source code repository: + +GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt +Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt +*/ +package gplx.xowa.xtns.template_styles; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; +import gplx.xowa.wikis.caches.*; +import gplx.xowa.htmls.core.htmls.*; import gplx.xowa.parsers.htmls.*; +import gplx.xowa.parsers.*; import gplx.xowa.parsers.xndes.*; +import gplx.xowa.wikis.nss.*; +public class Template_styles_nde implements Xox_xnde, Mwh_atr_itm_owner2 { + private byte[] css_ttl_bry; + private byte[] css_src; + private Xoa_ttl css_ttl; + public void Xatr__set(Xowe_wiki wiki, byte[] src, Mwh_atr_itm xatr, byte xatr_id) { + switch (xatr_id) { + case Xatr__src: css_ttl_bry = xatr.Val_as_bry(); break; + } + } + public void Xtn_parse(Xowe_wiki wiki, Xop_ctx ctx, Xop_root_tkn root, byte[] src, Xop_xnde_tkn xnde) { + ctx.Para().Process_block__xnde(xnde.Tag(), Xop_xnde_tag.Block_bgn); + Xox_xnde_.Parse_xatrs(wiki, this, xatrs_hash, src, xnde); + + // get css_ttl + css_ttl = wiki.Ttl_parse(css_ttl_bry); + if (css_ttl == null) { + Gfo_usr_dlg_.Instance.Warn_many("", "", "Template_styles_nde.invalid_ttl: wiki=~{0} page=~{1} css_ttl=~{2}", wiki.Domain_bry(), ctx.Page().Url_bry_safe(), css_ttl_bry); + return; + } + + // assume "Template:" if no explicit ns and no ":" + if (!css_ttl.ForceLiteralLink() // no initial ":" + && css_ttl.Ns().Id_is_main()) { + css_ttl = wiki.Ttl_parse(Bry_.Add(Xow_ns_.Bry__template_w_colon, css_ttl_bry)); + } + + // get page + Xow_page_cache_itm page_itm = wiki.Cache_mgr().Page_cache().Get_or_load_as_itm_2(css_ttl); + css_src = page_itm == null ? null : page_itm.Wtxt__direct(); + if (css_src == null) { + Gfo_usr_dlg_.Instance.Warn_many("", "", "Template_styles_nde.page_not_found: wiki=~{0} page=~{1} css_ttl=~{2}", wiki.Domain_bry(), ctx.Page().Url_bry_safe(), css_ttl_bry); + } + } + public void Xtn_write(Bry_bfr bfr, Xoae_app app, Xop_ctx ctx, Xoh_html_wtr html_wtr, Xoh_wtr_ctx hctx, Xoae_page wpg, Xop_xnde_tkn xnde, byte[] src) { + if (css_ttl == null) { + bfr.Add_str_a7(formatTagError("Invalid title for TemplateStyles src attribute.")); + } + else if (css_src == null) { + bfr.Add_str_a7(formatTagError("Page " + String_.new_u8(css_ttl_bry) + " has no content.")); + } + else { + bfr.Add_str_a7(""); + } + } + private static String formatTagError(String msg) { + // $parser->addTrackingCategory( 'templatestyles-page-error-category' ); + return "" + // + call_user_func_array( 'wfMessage', $msg )->inContentLanguage()->parse() + + msg + + ""; + } + public static final byte Xatr__src = 0; + private static final Hash_adp_bry xatrs_hash = Hash_adp_bry.ci_a7().Add_str_byte("src", Xatr__src); +} diff --git a/400_xowa/src/gplx/xowa/xtns/template_styles/Template_styles_nde_tst.java b/400_xowa/src/gplx/xowa/xtns/template_styles/Template_styles_nde_tst.java new file mode 100644 index 000000000..6dcfea95c --- /dev/null +++ b/400_xowa/src/gplx/xowa/xtns/template_styles/Template_styles_nde_tst.java @@ -0,0 +1,71 @@ +/* +XOWA: the XOWA Offline Wiki Application +Copyright (C) 2012-2017 gnosygnu@gmail.com + +XOWA is licensed under the terms of the General Public License (GPL) Version 3, +or alternatively under the terms of the Apache License Version 2.0. + +You may use XOWA according to either of these licenses as is most appropriate +for your project on a case-by-case basis. + +The terms of each license can be found in the source code repository: + +GPLv3 License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-GPLv3.txt +Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt +*/ +package gplx.xowa.xtns.template_styles; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; +import org.junit.*; +public class Template_styles_nde_tst { + private final Template_styles_nde_fxt fxt = new Template_styles_nde_fxt(); + @Before public void init() { + fxt.Reset(); + } + private static final String Css_red = ".red{color:red;}"; + private static final String Style_red = ""; + @Test public void Implicit_template() { // PURPOSE: default to template + fxt.Init__page("Template:Test.css", Css_red); + fxt.Test__parse + ( "" + , Style_red + ); + } + @Test public void Force_main() { // PURPOSE: ":" forces main + fxt.Init__page("Test.css", Css_red); + fxt.Test__parse + ( "" + , Style_red + ); + } + @Test public void Explicit() { // PURPOSE: explicit ns + fxt.Init__page("Module:Test.css", Css_red); + fxt.Test__parse + ( "" + , Style_red + ); + } + @Test public void Error__invalid_title() { + fxt.Test__parse + ( "" + , "Invalid title for TemplateStyles src attribute." + ); + } + @Test public void Error__missing_page() { + fxt.Test__parse + ( "" + , "Page Missing.css has no content." + ); + } +} +class Template_styles_nde_fxt { + private final Xop_fxt parser_fxt = new Xop_fxt(); + public void Reset() { + parser_fxt.Reset(); + parser_fxt.Wiki().Xtn_mgr().Init_by_wiki(parser_fxt.Wiki()); + } + public void Init__page(String page, String text) { + parser_fxt.Init_page_create(page, text); + } + public void Test__parse(String src, String expd) { + parser_fxt.Test__parse__tmpl_to_html(src, expd); + } +} diff --git a/gplx.xowa.mediawiki/src/gplx/xowa/mediawiki/includes/title/XomwMediaWikiTitleCodecTest.java b/gplx.xowa.mediawiki/src/gplx/xowa/mediawiki/includes/title/XomwMediaWikiTitleCodecTest.java index ab77f35df..702e64cec 100644 --- a/gplx.xowa.mediawiki/src/gplx/xowa/mediawiki/includes/title/XomwMediaWikiTitleCodecTest.java +++ b/gplx.xowa.mediawiki/src/gplx/xowa/mediawiki/includes/title/XomwMediaWikiTitleCodecTest.java @@ -50,7 +50,7 @@ class XomwMediaWikiTitleCodecFxt { } public XomwLanguage Make_lang() { Xoae_app app = Xoa_app_fxt.Make__app__edit(); - Xol_lang_itm lang = new Xol_lang_itm(app.Lang_mgr(), Xol_lang_itm_.Key_en); + Xol_lang_itm lang = Xol_lang_itm.New(app.Lang_mgr(), Xol_lang_itm_.Key_en); return new XomwLanguage(lang); } public void Test_splitTitleString(XomwMediaWikiTitleCodec codec, String src, XomwMediaWikiTitleCodecParts expd) { diff --git a/gplx.xowa.mediawiki/src/gplx/xowa/mediawiki/languages/XomwLanguageTest.java b/gplx.xowa.mediawiki/src/gplx/xowa/mediawiki/languages/XomwLanguageTest.java index b994a9c2b..579a72ebe 100644 --- a/gplx.xowa.mediawiki/src/gplx/xowa/mediawiki/languages/XomwLanguageTest.java +++ b/gplx.xowa.mediawiki/src/gplx/xowa/mediawiki/languages/XomwLanguageTest.java @@ -117,7 +117,7 @@ class XomwLanguageFxt { private final XomwLanguage lang; public XomwLanguageFxt() { Xoae_app app = Xoa_app_fxt.Make__app__edit(); - Xol_lang_itm xoLang = new Xol_lang_itm(app.Lang_mgr(), Bry_.new_a7("en")); + Xol_lang_itm xoLang = Xol_lang_itm.New(app.Lang_mgr(), Bry_.new_a7("en")); this.lang = new XomwLanguage(xoLang); } public void Init_digitGroupingPattern(String digitGroupingPattern) {