use of com.ichi2.libanki.template.Template in project AnkiChinaAndroid by ankichinateam.
the class Card method _getQA.
public HashMap<String, String> _getQA(boolean reload, boolean browser) {
if (mQA == null || reload) {
Note f = note(reload);
Model m = model();
JSONObject t = template();
long did = mODid != 0L ? mODid : mDid;
if (browser) {
String bqfmt = t.getString("bqfmt");
String bafmt = t.getString("bafmt");
mQA = mCol._renderQA(mId, m, did, mOrd, f.stringTags(), f.getFields(), mFlags, browser, bqfmt, bafmt);
} else {
mQA = mCol._renderQA(mId, m, did, mOrd, f.stringTags(), f.getFields(), mFlags);
}
}
return mQA;
}
use of com.ichi2.libanki.template.Template in project AnkiChinaAndroid by ankichinateam.
the class Finder method _findTemplate.
private String _findTemplate(String val) {
// were we given an ordinal number?
Integer num = null;
try {
num = Integer.parseInt(val) - 1;
} catch (NumberFormatException e) {
num = null;
}
if (num != null) {
return "c.ord = " + num;
}
// search for template names
List<String> lims = new ArrayList<>();
for (JSONObject m : mCol.getModels().all()) {
JSONArray tmpls = m.getJSONArray("tmpls");
for (int ti = 0; ti < tmpls.length(); ++ti) {
JSONObject t = tmpls.getJSONObject(ti);
String templateName = t.getString("name");
Normalizer.normalize(templateName, Normalizer.Form.NFC);
if (templateName.equalsIgnoreCase(val)) {
if (m.getInt("type") == Consts.MODEL_CLOZE) {
// if the user has asked for a cloze card, we want
// to give all ordinals, so we just limit to the
// model instead
lims.add("(n.mid = " + m.getLong("id") + ")");
} else {
lims.add("(n.mid = " + m.getLong("id") + " and c.ord = " + t.getInt("ord") + ")");
}
}
}
}
return TextUtils.join(" or ", lims.toArray(new String[lims.size()]));
}
use of com.ichi2.libanki.template.Template in project AnkiChinaAndroid by ankichinateam.
the class Models method _reqForTemplate.
// 'String f' is unused upstream as well
@SuppressWarnings("PMD.UnusedLocalVariable")
private Object[] _reqForTemplate(Model m, ArrayList<String> flds, JSONObject t) {
int nbFields = flds.size();
String[] a = new String[nbFields];
String[] b = new String[nbFields];
Arrays.fill(a, "ankiflag");
Arrays.fill(b, "");
int ord = t.getInt("ord");
String full = mCol._renderQA(1L, m, 1L, ord, "", a, 0).get("q");
String empty = mCol._renderQA(1L, m, 1L, ord, "", b, 0).get("q");
// if full and empty are the same, the template is invalid and there is no way to satisfy it
if (full.equals(empty)) {
return new Object[] { "none", new JSONArray(), new JSONArray() };
}
String type = "all";
JSONArray req = new JSONArray();
for (int i = 0; i < flds.size(); i++) {
a[i] = "";
// if no field content appeared, field is required
if (!mCol._renderQA(1L, m, 1L, ord, "", a, 0).get("q").contains("ankiflag")) {
req.put(i);
}
a[i] = "ankiflag";
}
if (req.length() > 0) {
return new Object[] { type, req };
}
// if there are no required fields, switch to any mode
type = "any";
req = new JSONArray();
for (int i = 0; i < flds.size(); i++) {
b[i] = "1";
// if not the same as empty, this field can make the card non-blank
if (!mCol._renderQA(1L, m, 1L, ord, "", b, 0).get("q").equals(empty)) {
req.put(i);
}
b[i] = "";
}
return new Object[] { type, req };
}
use of com.ichi2.libanki.template.Template in project AnkiChinaAndroid by ankichinateam.
the class Models method moveTemplate.
public void moveTemplate(Model m, JSONObject template, int idx) {
JSONArray tmpls = m.getJSONArray("tmpls");
int oldidx = -1;
ArrayList<JSONObject> l = new ArrayList<>();
HashMap<Integer, Integer> oldidxs = new HashMap<>();
for (int i = 0; i < tmpls.length(); ++i) {
if (tmpls.getJSONObject(i).equals(template)) {
oldidx = i;
if (idx == oldidx) {
return;
}
}
JSONObject t = tmpls.getJSONObject(i);
oldidxs.put(t.hashCode(), t.getInt("ord"));
l.add(t);
}
l.remove(oldidx);
l.add(idx, template);
m.put("tmpls", new JSONArray(l));
_updateTemplOrds(m);
// generate change map - We use StringBuilder
StringBuilder sb = new StringBuilder();
tmpls = m.getJSONArray("tmpls");
for (int i = 0; i < tmpls.length(); ++i) {
JSONObject t = tmpls.getJSONObject(i);
sb.append("when ord = ").append(oldidxs.get(t.hashCode())).append(" then ").append(t.getInt("ord"));
if (i != tmpls.length() - 1) {
sb.append(" ");
}
}
// apply
save(m);
mCol.getDb().execute("update cards set ord = (case " + sb.toString() + " end),usn=?,mod=? where nid in (select id from notes where mid = ?)", mCol.usn(), mCol.getTime().intTime(), m.getLong("id"));
}
use of com.ichi2.libanki.template.Template in project AnkiChinaAndroid by ankichinateam.
the class Collection method _renderQA.
public HashMap<String, String> _renderQA(long cid, Model model, long did, int ord, String tags, String[] flist, int flags, boolean browser, String qfmt, String afmt) {
// data is [cid, nid, mid, did, ord, tags, flds, cardFlags]
// unpack fields and create dict
Map<String, String> fields = new HashMap<>();
Map<String, Pair<Integer, JSONObject>> fmap = Models.fieldMap(model);
for (String name : fmap.keySet()) {
fields.put(name, flist[fmap.get(name).first]);
}
int cardNum = ord + 1;
fields.put("Tags", tags.trim());
fields.put("Type", model.getString("name"));
fields.put("Deck", mDecks.name(did));
String baseName = Decks.basename(fields.get("Deck"));
fields.put("Subdeck", baseName);
fields.put("CardFlag", _flagNameFromCardFlags(flags));
JSONObject template;
if (model.getInt("type") == Consts.MODEL_STD) {
template = model.getJSONArray("tmpls").getJSONObject(ord);
} else {
template = model.getJSONArray("tmpls").getJSONObject(0);
}
fields.put("Card", template.getString("name"));
fields.put(String.format(Locale.US, "c%d", cardNum), "1");
// render q & a
HashMap<String, String> d = new HashMap<>();
d.put("id", Long.toString(cid));
qfmt = TextUtils.isEmpty(qfmt) ? template.getString("qfmt") : qfmt;
afmt = TextUtils.isEmpty(afmt) ? template.getString("afmt") : afmt;
for (Pair<String, String> p : new Pair[] { new Pair<>("q", qfmt), new Pair<>("a", afmt) }) {
String type = p.first;
String format = p.second;
if ("q".equals(type)) {
format = fClozePatternQ.matcher(format).replaceAll(String.format(Locale.US, "{{$1cq-%d:", cardNum));
format = fClozeTagStart.matcher(format).replaceAll(String.format(Locale.US, "<%%cq:%d:", cardNum));
} else {
format = fClozePatternA.matcher(format).replaceAll(String.format(Locale.US, "{{$1ca-%d:", cardNum));
format = fClozeTagStart.matcher(format).replaceAll(String.format(Locale.US, "<%%ca:%d:", cardNum));
// the following line differs from libanki // TODO: why?
// fields.put("FrontSide", mMedia.stripAudio(d.get("q")));
fields.put("FrontSide", d.get("q"));
}
String html = new Template(format, fields).render();
html = ChessFilter.fenToChessboard(html, getContext());
if (!browser) {
// browser don't show image. So compiling LaTeX actually remove information.
html = LaTeX.mungeQA(html, this, model);
}
d.put(type, html);
// empty cloze?
if ("q".equals(type) && model.getInt("type") == Consts.MODEL_CLOZE) {
if (getModels()._availClozeOrds(model, flist, false).size() == 0) {
String link = String.format("<a href=%s#cloze>%s</a>", Consts.HELP_SITE, "help");
d.put("q", mContext.getString(R.string.empty_cloze_warning, link));
}
}
}
return d;
}
Aggregations