Search in sources :

Example 1 with TemplateError

use of com.ichi2.libanki.template.TemplateError in project Anki-Android by ankidroid.

the class Collection method _renderQA.

@RustCleanup("#8951 - Remove FrontSide added to the front")
@NonNull
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, Pair<Integer, JSONObject>> fmap = Models.fieldMap(model);
    Set<Map.Entry<String, Pair<Integer, JSONObject>>> maps = fmap.entrySet();
    Map<String, String> fields = HashUtil.HashMapInit(maps.size() + 8);
    for (Map.Entry<String, Pair<Integer, JSONObject>> entry : maps) {
        fields.put(entry.getKey(), flist[entry.getValue().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.isStd()) {
        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 = HashUtil.HashMapInit(2);
    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));
            fields.put("FrontSide", "");
        } 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;
        try {
            html = ParsedNode.parse_inner(format).render(fields, "q".equals(type), getContext());
        } catch (TemplateError er) {
            Timber.w(er);
            html = er.message(getContext());
        }
        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.isCloze()) {
            if (Models._availClozeOrds(model, flist, false).isEmpty()) {
                String link = String.format("<a href=\"%s\">%s</a>", mContext.getResources().getString(R.string.link_ankiweb_docs_cloze_deletion), "help");
                System.out.println(link);
                d.put("q", mContext.getString(R.string.empty_cloze_warning, link));
            }
        }
    }
    return d;
}
Also used : SuppressLint(android.annotation.SuppressLint) JSONObject(com.ichi2.utils.JSONObject) TemplateError(com.ichi2.libanki.template.TemplateError) Map(java.util.Map) HashMap(java.util.HashMap) Pair(android.util.Pair) RustCleanup(net.ankiweb.rsdroid.RustCleanup) NonNull(androidx.annotation.NonNull)

Example 2 with TemplateError

use of com.ichi2.libanki.template.TemplateError in project Anki-Android by ankidroid.

the class Model method parsedNodes.

/**
 * @return A list of parsed nodes for each template's question. null in case of exception
 */
public List<ParsedNode> parsedNodes() {
    JSONArray tmpls = getJSONArray("tmpls");
    List<ParsedNode> nodes = new ArrayList<>(tmpls.length());
    for (JSONObject tmpl : tmpls.jsonObjectIterable()) {
        String format_question = tmpl.getString("qfmt");
        ParsedNode node = null;
        try {
            node = ParsedNode.parse_inner(format_question);
        } catch (TemplateError er) {
            Timber.w(er);
        }
        nodes.add(node);
    }
    return nodes;
}
Also used : ParsedNode(com.ichi2.libanki.template.ParsedNode) JSONObject(com.ichi2.utils.JSONObject) JSONArray(com.ichi2.utils.JSONArray) ArrayList(java.util.ArrayList) TemplateError(com.ichi2.libanki.template.TemplateError)

Example 3 with TemplateError

use of com.ichi2.libanki.template.TemplateError in project Anki-Android by Ramblurr.

the class Collection method _renderQA.

public HashMap<String, String> _renderQA(Object[] data, List<String> args) {
    // data is [cid, nid, mid, did, ord, tags, flds]
    // unpack fields and create dict
    String[] flist = Utils.splitFields((String) data[6]);
    Map<String, String> fields = new HashMap<String, String>();
    long modelId = (Long) data[2];
    JSONObject model = mModels.get(modelId);
    Map<String, Pair<Integer, JSONObject>> fmap = mModels.fieldMap(model);
    for (String fname : fmap.keySet()) {
        fields.put(fname, flist[fmap.get(fname).first]);
    }
    fields.put("Tags", ((String) data[5]).trim());
    try {
        fields.put("Type", (String) model.get("name"));
        fields.put("Deck", mDecks.name((Long) data[3]));
        JSONObject template;
        if (model.getInt("type") == Sched.MODEL_STD) {
            template = model.getJSONArray("tmpls").getJSONObject((Integer) data[4]);
        } else {
            template = model.getJSONArray("tmpls").getJSONObject(0);
        }
        fields.put("Card", template.getString("name"));
        fields.put("c" + (((Integer) data[4]) + 1), "1");
        // render q & a
        HashMap<String, String> d = new HashMap<String, String>();
        try {
            d.put("id", Long.toString((Long) data[0]));
            String qfmt = template.getString("qfmt");
            String afmt = template.getString("afmt");
            String html;
            String format;
            // runFilter mungeFields for type "q"
            Models.fieldParser fparser = new Models.fieldParser(fields);
            Matcher m = fClozePattern.matcher(qfmt);
            format = m.replaceFirst(String.format(Locale.US, "{{cq:%d:", ((Integer) data[4]) + 1));
            m = fAltClozePattern.matcher(format);
            format = m.replaceFirst(String.format(Locale.US, "<%%cq:%d:", ((Integer) data[4]) + 1));
            html = mModels.getCmpldTemplate(format).execute(fparser);
            html = (String) AnkiDroidApp.getHooks().runFilter("mungeQA", html, "q", fields, model, data, this);
            d.put("q", html);
            // empty cloze?
            if (model.getInt("type") == Sched.MODEL_CLOZE) {
                if (getModels()._availClozeOrds(model, (String) data[6], false).size() == 0) {
                    d.put("q", "Please edit this note and add some cloze deletions.");
                }
            }
            fields.put("FrontSide", mMedia.stripAudio(d.get("q")));
            // runFilter mungeFields for type "a"
            fparser = new Models.fieldParser(fields);
            m = fClozePattern.matcher(afmt);
            format = m.replaceFirst(String.format(Locale.US, "{{ca:%d:", ((Integer) data[4]) + 1));
            m = fAltClozePattern.matcher(format);
            format = m.replaceFirst(String.format(Locale.US, "<%%ca:%d:", ((Integer) data[4]) + 1));
            html = mModels.getCmpldTemplate(format).execute(fparser);
            html = (String) AnkiDroidApp.getHooks().runFilter("mungeQA", html, "a", fields, model, data, this);
            d.put("a", html);
            // empty cloze?
            if (model.getInt("type") == Sched.MODEL_CLOZE) {
                if (getModels()._availClozeOrds(model, (String) data[6], false).size() == 0) {
                    d.put("q", AnkiDroidApp.getAppResources().getString(com.ichi2.anki.R.string.empty_cloze_warning, "<a href=" + HELP_SITE + "#cloze>" + AnkiDroidApp.getAppResources().getString(com.ichi2.anki.R.string.help_cloze) + "</a>"));
                }
            }
        } catch (MustacheException e) {
            Resources res = AnkiDroidApp.getAppResources();
            String templateError = String.format(TEMPLATE_ERROR, res.getString(R.string.template_error), res.getString(R.string.template_error_detail), e.getMessage(), res.getString(R.string.note_type), model.getString("name"), res.getString(R.string.card_type), template.getString("name"), res.getString(R.string.template_error_fix));
            d.put("q", templateError);
            d.put("a", templateError);
        }
        return d;
    } catch (JSONException e) {
        throw new RuntimeException(e);
    }
}
Also used : HashMap(java.util.HashMap) Matcher(java.util.regex.Matcher) MustacheException(com.samskivert.mustache.MustacheException) JSONException(org.json.JSONException) JSONObject(org.json.JSONObject) Resources(android.content.res.Resources) Pair(com.ichi2.anki.Pair)

Aggregations

TemplateError (com.ichi2.libanki.template.TemplateError)2 JSONObject (com.ichi2.utils.JSONObject)2 HashMap (java.util.HashMap)2 SuppressLint (android.annotation.SuppressLint)1 Resources (android.content.res.Resources)1 Pair (android.util.Pair)1 NonNull (androidx.annotation.NonNull)1 Pair (com.ichi2.anki.Pair)1 ParsedNode (com.ichi2.libanki.template.ParsedNode)1 JSONArray (com.ichi2.utils.JSONArray)1 MustacheException (com.samskivert.mustache.MustacheException)1 ArrayList (java.util.ArrayList)1 Map (java.util.Map)1 Matcher (java.util.regex.Matcher)1 RustCleanup (net.ankiweb.rsdroid.RustCleanup)1 JSONException (org.json.JSONException)1 JSONObject (org.json.JSONObject)1