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) {