mirror of
https://github.com/gnosygnu/xowa.git
synced 2026-03-02 03:49:30 +00:00
Lang: Support explicit plural indexes and rules in other languages [#633]
This commit is contained in:
@@ -63,6 +63,7 @@ public class Char_ {
|
||||
default: return or;
|
||||
}
|
||||
}
|
||||
public static int To_int(char c) {return (int)c;}
|
||||
public static String To_str(char[] ary, int pos, int length) {return new String(ary, pos, length);}
|
||||
public static String To_str(int b) {return To_str((char)b);}
|
||||
public static String To_str(char c) {return String.valueOf(c);}
|
||||
|
||||
@@ -20,6 +20,7 @@ import java.math.RoundingMode;
|
||||
import java.text.DecimalFormat;
|
||||
public class Decimal_adp implements CompareAble {
|
||||
public int compareTo(Object obj) {Decimal_adp comp = (Decimal_adp)obj; return under.compareTo(comp.under);}
|
||||
public Decimal_adp Floor() {return Decimal_adp_.int_(this.To_int());}
|
||||
protected Decimal_adp(BigDecimal v) {this.under = v;} private final BigDecimal under;
|
||||
protected Decimal_adp(int v) {this.under = new BigDecimal(v);}
|
||||
public Object Under() {return under;}
|
||||
|
||||
@@ -21,6 +21,7 @@ public interface Hash_adp extends gplx.core.lists.EnumerAble {
|
||||
Object Get_by_or_fail(Object key);
|
||||
void Add(Object key, Object val);
|
||||
Hash_adp Add_and_more(Object key, Object val);
|
||||
Hash_adp Add_many_as_key_and_val(Object... ary);
|
||||
void Add_as_key_and_val(Object val);
|
||||
boolean Add_if_dupe_use_1st(Object key, Object val);
|
||||
void Add_if_dupe_use_nth(Object key, Object val);
|
||||
|
||||
@@ -27,6 +27,7 @@ class Hash_adp_noop implements Hash_adp {
|
||||
public Object Get_by_or_fail(Object key) {throw Err_.new_missing_key(Object_.Xto_str_strict_or_null_mark(key));}
|
||||
public void Add(Object key, Object val) {}
|
||||
public Hash_adp Add_and_more(Object key, Object val) {return this;}
|
||||
public Hash_adp Add_many_as_key_and_val(Object... ary) {return this;}
|
||||
public void Add_as_key_and_val(Object val) {}
|
||||
public void Add_if_dupe_use_nth(Object key, Object val) {}
|
||||
public boolean Add_if_dupe_use_1st(Object key, Object val) {return false;}
|
||||
|
||||
@@ -16,6 +16,7 @@ Apache License: https://github.com/gnosygnu/xowa/blob/master/LICENSE-APACHE2.txt
|
||||
package gplx;
|
||||
public class Math_ {
|
||||
public static double Pow(double val, double exponent) {return java.lang.Math.pow(val, exponent);}
|
||||
public static int Pow_int(int val, int exponent) {return (int)java.lang.Math.pow(val, exponent);}
|
||||
public static double Pi = java.lang.Math.PI;
|
||||
public static double E = java.lang.Math.E;
|
||||
public static int Ceil_as_int(double v) {return (int)Ceil(v);}
|
||||
|
||||
@@ -20,6 +20,11 @@ public abstract class Hash_adp_base implements Hash_adp {
|
||||
public Object Get_by_or_fail(Object key) {return Get_by_or_fail_base(key);}
|
||||
public void Add(Object key, Object val) {Add_base(key, val);}
|
||||
public Hash_adp Add_and_more(Object key, Object val) {Add_base(key, val); return this;}
|
||||
public Hash_adp Add_many_as_key_and_val(Object... ary) {
|
||||
for (Object itm : ary)
|
||||
Add_base(itm, itm);
|
||||
return this;
|
||||
}
|
||||
public void Add_as_key_and_val(Object val) {Add_base(val, val);}
|
||||
public void Add_if_dupe_use_nth(Object key, Object val) {
|
||||
Object existing = Fetch_base(key); if (existing != null) Del(key); // overwrite if exists
|
||||
|
||||
@@ -22,6 +22,11 @@ public class Sorted_hash implements Hash_adp {
|
||||
public Object Get_by_or_fail(Object key) {return Get_by_or_fail_base(key);}
|
||||
public void Add(Object key, Object val) {Add_base(key, val);}
|
||||
public Hash_adp Add_and_more(Object key, Object val) {Add_base(key, val); return this;}
|
||||
public Hash_adp Add_many_as_key_and_val(Object... ary) {
|
||||
for (Object itm : ary)
|
||||
Add_base(itm, itm);
|
||||
return this;
|
||||
}
|
||||
public void Add_as_key_and_val(Object val) {Add_base(val, val);}
|
||||
public void Add_if_dupe_use_nth(Object key, Object val) {
|
||||
Object existing = Fetch_base(key); if (existing != null) Del(key); // overwrite if exists
|
||||
|
||||
@@ -38,6 +38,7 @@ public interface String_bldr {
|
||||
String_bldr Add(int i);
|
||||
String_bldr Add_obj(Object o);
|
||||
String_bldr Add_mid(char[] ary, int bgn, int count);
|
||||
String_bldr Add_mid(String str, int bgn, int count);
|
||||
String_bldr Add_at(int idx, String s);
|
||||
String_bldr Del(int bgn, int len);
|
||||
}
|
||||
@@ -83,6 +84,7 @@ abstract class String_bldr_base implements String_bldr {
|
||||
public abstract String_bldr Add(char c);
|
||||
public abstract String_bldr Add(int i);
|
||||
public abstract String_bldr Add_mid(char[] ary, int bgn, int count);
|
||||
public abstract String_bldr Add_mid(String str, int bgn, int count);
|
||||
public abstract String_bldr Add_obj(Object o);
|
||||
public abstract String_bldr Del(int bgn, int len);
|
||||
}
|
||||
@@ -96,6 +98,7 @@ class String_bldr_thread_single extends String_bldr_base {
|
||||
@Override public String_bldr Add(char c) {sb.append(c); return this;}
|
||||
@Override public String_bldr Add(int i) {sb.append(i); return this;}
|
||||
@Override public String_bldr Add_mid(char[] ary, int bgn, int count) {sb.append(ary, bgn, count); return this;}
|
||||
@Override public String_bldr Add_mid(String str, int bgn, int count) {sb.append(str, bgn, count); return this;}
|
||||
@Override public String_bldr Add_obj(Object o) {sb.append(o); return this;}
|
||||
@Override public String_bldr Del(int bgn, int len) {sb.delete(bgn, len); return this;}
|
||||
}
|
||||
@@ -109,6 +112,7 @@ class String_bldr_thread_multiple extends String_bldr_base {
|
||||
@Override public String_bldr Add(char c) {sb.append(c); return this;}
|
||||
@Override public String_bldr Add(int i) {sb.append(i); return this;}
|
||||
@Override public String_bldr Add_mid(char[] ary, int bgn, int count) {sb.append(ary, bgn, count); return this;}
|
||||
@Override public String_bldr Add_mid(String str, int bgn, int count) {sb.append(str, bgn, count); return this;}
|
||||
@Override public String_bldr Add_obj(Object o) {sb.append(o); return this;}
|
||||
@Override public String_bldr Del(int bgn, int len) {sb.delete(bgn, len); return this;}
|
||||
}
|
||||
|
||||
@@ -56,9 +56,13 @@ public class Regx_adp {
|
||||
Regx_group[] ary = Regx_group.Ary_empty;
|
||||
int groups_len = match.groupCount();
|
||||
if (success && groups_len > 0) {
|
||||
// NOTE: by convention, there are n groups, but groups.count is n - 1 and groups[0] is entire match (not 1st group); see TEST: DATE:2019-12-28
|
||||
groups_len++;
|
||||
ary = new Regx_group[groups_len];
|
||||
for (int i = 0; i < groups_len; i++)
|
||||
ary[i] = new Regx_group(true, match.start(i + 1), match.end(i + 1), match.group(i + 1));
|
||||
for (int i = 0; i < groups_len; i++) {
|
||||
int match_start = match.start(i);
|
||||
ary[i] = new Regx_group(match_start != -1, match_start, match.end(i), match.group(i));
|
||||
}
|
||||
}
|
||||
return new Regx_match(success, match_bgn, match_end, ary);
|
||||
}
|
||||
|
||||
@@ -49,7 +49,9 @@ public class Regx_adp__tst implements TfdsEqListItmStr {
|
||||
tst_Matches("b", "a b c b a b b", matches_(2, 6, 10, 12)); // BUGFIX: multiple entries did not work b/c of += instead of +
|
||||
}
|
||||
@Test public void Groups() {
|
||||
tst_Groups("abc def ghi dz", "(d\\p{L}+)", "def", "dz");
|
||||
tst_Groups("abc def ghi dz", "(d\\p{L}+)", "def", "def", "dz", "dz");
|
||||
tst_Groups("abc def", "(de)(g?)", "de", "de", ""); // NOTE: (g?) doesn't capture anything, but still add a group for it; DATE:2019-12-28
|
||||
tst_Groups("-123.456", "^-?(([0-9]+)(?:\\.([0-9]+))?)", "-123.456", "123.456", "123", "456"); // NOTE: -123.456 captured even though it's not part of a group; DATE:2019-12-28
|
||||
}
|
||||
Regx_match[] matches_(int... bgnAry) {
|
||||
int aryLen = Array_.Len(bgnAry);
|
||||
|
||||
@@ -22,6 +22,11 @@ public class XmlAtrList {
|
||||
Node xatr = list.getNamedItem(key);
|
||||
return (xatr == null) ? or : xatr.getNodeValue();
|
||||
}
|
||||
public XmlAtr Get_by(String key) {
|
||||
Node xatr = list.getNamedItem(key);
|
||||
if (xatr == null) throw Err_.new_missing_key(key);
|
||||
return new XmlAtr(xatr);
|
||||
}
|
||||
public XmlAtr Fetch(String key) {
|
||||
Node xatr = list.getNamedItem(key); if (xatr == null) throw Err_.new_missing_key(key);
|
||||
return new XmlAtr(xatr);
|
||||
|
||||
@@ -29,23 +29,52 @@ import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NodeList;
|
||||
import org.xml.sax.EntityResolver;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
public class XmlDoc_ {
|
||||
public static XmlDoc parse(String raw) {return new XmlDoc(doc_(raw));}
|
||||
public static XmlNdeList Select_tags(XmlNde cur, String tag) {
|
||||
XmlNdeList_cls_list rv = new XmlNdeList_cls_list(4); // NOTE: pass in an initial amount; do not pass 0
|
||||
Select_tags(rv, cur, tag);
|
||||
return rv;
|
||||
}
|
||||
private static void Select_tags(XmlNdeList_cls_list rv, XmlNde cur, String tag) {
|
||||
if (String_.Eq(cur.Name(), tag)) {
|
||||
rv.Add(cur);
|
||||
}
|
||||
XmlNdeList sub_ndes = cur.SubNdes();
|
||||
int sub_ndes_len = sub_ndes.Count();
|
||||
for (int i = 0; i < sub_ndes_len; i++) {
|
||||
XmlNde sub_nde = sub_ndes.Get_at(i);
|
||||
Select_tags(rv, sub_nde, tag);
|
||||
}
|
||||
}
|
||||
public static XmlDoc parse(String raw) {return new XmlDoc(doc_(raw));}
|
||||
static Document doc_(String raw) {
|
||||
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder bldr = null;
|
||||
try {bldr = factory.newDocumentBuilder();}
|
||||
catch (ParserConfigurationException e) {throw Err_.new_exc(e, "xml", "failed to create newDocumentBuilder");}
|
||||
try {
|
||||
// NOTE: disable DTD validation else errors for "ldmlSupplemental.dtd" in plurals.xml; DATE:2020-01-01
|
||||
// REF:https://stackoverflow.com/questions/24744175/non-validating-documentbuilder-trying-to-read-dtd-file
|
||||
// REF:https://stackoverflow.com/questions/6204827/xml-parsing-too-slow
|
||||
factory.setNamespaceAware(false);
|
||||
factory.setValidating(false);
|
||||
factory.setFeature("http://xml.org/sax/features/namespaces", false);
|
||||
factory.setFeature("http://xml.org/sax/features/validation", false);
|
||||
factory.setFeature("http://apache.org/xml/features/nonvalidating/load-dtd-grammar", false);
|
||||
factory.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false);
|
||||
bldr = factory.newDocumentBuilder();
|
||||
}
|
||||
catch (ParserConfigurationException e) {
|
||||
throw Err_.new_exc(e, "xml", "failed to create newDocumentBuilder");
|
||||
}
|
||||
StringReader reader = new StringReader(raw);
|
||||
InputSource source = new InputSource(reader);
|
||||
Document doc = null;
|
||||
try {doc = bldr.parse(source);}
|
||||
catch (SAXException e) {throw Err_.new_exc(e, "xml", "failed to parse xml", "raw", raw);}
|
||||
catch (IOException e) {throw Err_.new_exc(e, "xml", "failed to parse xml", "raw", raw);}
|
||||
return doc;
|
||||
return doc;
|
||||
}
|
||||
public static final String Err_XmlException = "gplx.xmls.XmlException";
|
||||
}
|
||||
//#}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user