better dictionary visualization in the Android App

This commit is contained in:
kr.angelov
2013-11-27 22:16:05 +00:00
parent eea636966d
commit f5ec987c5d
9 changed files with 1309 additions and 1077 deletions

View File

@@ -212,6 +212,25 @@ Java_org_grammaticalframework_pgf_PGF_getStartCat(JNIEnv* env, jobject self)
return gu2j_string(env, pgf_start_cat(get_ref(env, self)));
}
JNIEXPORT jobject JNICALL
Java_org_grammaticalframework_pgf_PGF_getFunctionType(JNIEnv* env, jobject self, jstring jid)
{
PgfPGF* pgf = get_ref(env, self);
GuPool* tmp_pool = gu_new_pool();
PgfCId id = j2gu_string(env, jid, tmp_pool);
PgfType* tp = pgf_function_type(pgf, id);
gu_pool_free(tmp_pool);
if (tp == NULL)
return NULL;
jclass type_class = (*env)->FindClass(env, "org/grammaticalframework/pgf/Type");
jmethodID constrId = (*env)->GetMethodID(env, type_class, "<init>", "(Lorg/grammaticalframework/pgf/PGF;J)V");
jobject jtype = (*env)->NewObject(env, type_class, constrId, self, p2l(tp));
return jtype;
}
typedef struct {
GuMapItor fn;
JNIEnv *env;
@@ -535,6 +554,13 @@ Java_org_grammaticalframework_pgf_Expr_readExpr(JNIEnv* env, jclass clazz, jstri
return (*env)->NewObject(env, clazz, constrId, jpool, NULL, p2l(gu_variant_to_ptr(e)));
}
JNIEXPORT jstring JNICALL
Java_org_grammaticalframework_pgf_Type_getCategory(JNIEnv* env, jobject self)
{
PgfType* tp = get_ref(env, self);
return gu2j_string(env, tp->cid);
}
JNIEXPORT jobject JNICALL
Java_org_grammaticalframework_pgf_Generator_generateAll(JNIEnv* env, jclass clazz, jobject jpgf, jstring jstartCat)
{

View File

@@ -0,0 +1,7 @@
package org.grammaticalframework.pgf;
public class Hypo {
public native boolean getBindType();
public native String getVariable();
public native Type getType();
}

View File

@@ -1,4 +1,18 @@
package org.grammaticalframework.pgf;
public class Type {
public native String getCategory();
public native Expr[] getExprs();
public native Hypo[] getHypos();
//////////////////////////////////////////////////////////////////
// private stuff
private PGF gr;
private long ref;
private Type(PGF gr, long ref) {
this.gr = gr;
this.ref = ref;
}
}

View File

@@ -1,6 +1,10 @@
<inflection_temlate>
<noun>
<h1>Съществително</h1>
<inflection_template>
<inflection>
<cat>N</cat>
<cat>N2</cat>
<tag>същ</tag>
<template>
<h1>Съществително <lin>Feat<cat/>(<lemma/>)</lin></h1>
<table class="forms-table" rules="all">
<tr>
@@ -79,8 +83,13 @@
<td><form>rel (APl Def)</form></td>
</tr>
</table>
</noun>
<adjective>
</template>
</inflection>
<inflection>
<cat>A</cat>
<cat>A2</cat>
<tag>пр</tag>
<template>
<h1>Прилагателно</h1>
<table class="forms-table" rules="all">
<tr>
@@ -128,16 +137,33 @@
<h1>Наречие</h1>
<p><form>adv</form></p>
</adjective>
<adverb>
</template>
</inflection>
<inflection>
<cat>Adv</cat>
<tag>нар</tag>
<template>
<h1>Наречие</h1>
<p><form>s</form></p>
</adverb>
<prep>
</template>
</inflection>
<inflection>
<cat>Prep</cat>
<tag>пр</tag>
<template>
<h1>Предлог</h1>
<p><form>s</form></p>
</prep>
<verb>
</template>
</inflection>
<inflection>
<cat>V</cat>
<cat>V2</cat>
<cat>V3</cat>
<cat>V2V</cat>
<cat>VV</cat>
<cat>VS</cat>
<tag>гл</tag>
<template>
<h1>Глагол от несвършен вид</h1>
<h2>Изявително наклонение</h2>
@@ -611,5 +637,6 @@
<td><form>s Imperf (VNoun (NF Pl Def))</form></td>
</tr>
</table>
</verb>
</inflection_temlate>
</template>
</inflection>
</inflection_template>

View File

@@ -1,5 +1,9 @@
<inflection_temlate>
<noun>
<inflection_template>
<inflection>
<cat>N</cat>
<cat>N2</cat>
<tag>n</tag>
<template>
<h1>Noun</h1>
<table class="forms-table" rules="all">
@@ -12,8 +16,13 @@
<td><form>c</form></td>
</tr>
</table>
</noun>
<adjective>
</template>
</inflection>
<inflection>
<cat>A</cat>
<cat>A2</cat>
<tag>a</tag>
<template>
<h1>Adjective</h1>
<table class="forms-table" rules="all">
@@ -22,16 +31,33 @@
<td><form>s</form></td>
</tr>
</table>
</adjective>
<adverb>
</template>
</inflection>
<inflection>
<cat>Adv</cat>
<tag>adv</tag>
<template>
<h1>Adverb</h1>
<p><form>s</form></p>
</adverb>
<prep>
</template>
</inflection>
<inflection>
<cat>Prep</cat>
<tag>prep</tag>
<template>
<h1>Preposition</h1>
<p><form>prepPre</form> - <form>prepPost</form></p>
</prep>
<verb>
</template>
</inflection>
<inflection>
<cat>V</cat>
<cat>V2</cat>
<cat>V3</cat>
<cat>V2V</cat>
<cat>VV</cat>
<cat>VS</cat>
<tag>v</tag>
<template>
<h1>Verb</h1>
<table class="forms-table" rules="all">
<tr>
@@ -63,5 +89,6 @@
<td><form>sn</form></td>
</tr>
</table>
</verb>
</inflection_temlate>
</template>
</inflection>
</inflection_template>

View File

@@ -1,5 +1,9 @@
<inflection_temlate>
<noun>
<inflection_template>
<inflection>
<cat>N</cat>
<cat>N2</cat>
<tag>n</tag>
<template>
<h1>Noun</h1>
<table class="forms-table" rules="all">
@@ -19,8 +23,13 @@
<td><form>s Pl Gen</form></td>
</tr>
</table>
</noun>
<adjective>
</template>
</inflection>
<inflection>
<cat>A</cat>
<cat>A2</cat>
<tag>a</tag>
<template>
<h1>Adjective</h1>
<table class="forms-table" rules="all">
@@ -47,16 +56,33 @@
</table>
<h1>Adverb</h1>
<p><form>s AAdv</form></p>
</adjective>
<adverb>
</template>
</inflection>
<inflection>
<cat>Adv</cat>
<tag>adv</tag>
<template>
<h1>Adverb</h1>
<p><form>s</form></p>
</adverb>
<prep>
</template>
</inflection>
<inflection>
<cat>Prep</cat>
<tag>prep</tag>
<template>
<h1>Preposition</h1>
<p><form>s</form></p>
</prep>
<verb>
</template>
</inflection>
<inflection>
<cat>V</cat>
<cat>V2</cat>
<cat>V3</cat>
<cat>V2V</cat>
<cat>VV</cat>
<cat>VS</cat>
<tag>v</tag>
<template>
<h1>Verb</h1>
<table class="forms-table" rules="all">
<tr>
@@ -80,5 +106,6 @@
<td><form>s VPresPart</form></td>
</tr>
</table>
</verb>
</inflection_temlate>
</template>
</inflection>
</inflection_template>

View File

@@ -1,6 +1,10 @@
<inflection_temlate>
<noun>
<h1>Substantiv</h1>
<inflection_template>
<inflection>
<cat>N</cat>
<cat>N2</cat>
<tag>s</tag>
<template>
<h1>Substantiv <lin>Feat<cat/>(<lemma/>)</lin></h1>
<table class="forms-table" rules="all">
<tr>
@@ -32,8 +36,13 @@
<td><form>s Pl Def Gen</form></td>
</tr>
</table>
</noun>
<adjective>
</template>
</inflection>
<inflection>
<cat>A</cat>
<cat>A2</cat>
<tag>a</tag>
<template>
<h1>Adjektiv</h1>
<table class="forms-table" rules="all">
@@ -100,16 +109,33 @@
<td><form>s (AF (APosit (Weak Pl)) Gen)</form></td>
</tr>
</table>
</adjective>
<adverb>
</template>
</inflection>
<inflection>
<cat>Adv</cat>
<tag>adv</tag>
<template>
<h1>Adverb</h1>
<p><form>s</form></p>
</adverb>
<prep>
</template>
</inflection>
<inflection>
<cat>Prep</cat>
<tag>prep</tag>
<template>
<h1>Preposition</h1>
<p><form>s</form></p>
</prep>
<verb>
</template>
</inflection>
<inflection>
<cat>V</cat>
<cat>V2</cat>
<cat>V3</cat>
<cat>V2V</cat>
<cat>VV</cat>
<cat>VS</cat>
<tag>v</tag>
<template>
<h1>Verb</h1>
<table class="forms-table" rules="all">
<tr>
@@ -211,5 +237,6 @@
<td><form>s (VI (VPtPret (Weak Pl) Gen))</form></td>
</tr>
</table>
</verb>
</inflection_temlate>
</template>
</inflection>
</inflection_template>

View File

@@ -1,14 +1,11 @@
package org.grammaticalframework.ui.android;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import android.app.Activity;
import android.app.ListActivity;
import android.content.Context;
import android.content.res.XmlResourceParser;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
@@ -23,7 +20,6 @@ import android.widget.TextView;
import org.grammaticalframework.pgf.*;
import org.grammaticalframework.ui.android.LanguageSelector.OnLanguageSelectedListener;
import org.xmlpull.v1.XmlPullParserException;
public class LexicalEntryActivity extends ListActivity {
@@ -93,27 +89,6 @@ public class LexicalEntryActivity extends ListActivity {
}
private void expand(View view, String lemma) {
String tag = null;
if (lemma.endsWith("_N") || lemma.endsWith("_N2"))
tag = "noun";
else if (lemma.endsWith("_V") || lemma.endsWith("_V2") ||
lemma.endsWith("_V3") || lemma.endsWith("_V2V") ||
lemma.endsWith("_VV") || lemma.endsWith("_VS"))
tag = "verb";
else if (lemma.endsWith("_A") || lemma.endsWith("_A2"))
tag = "adjective";
else if (lemma.endsWith("_Prep"))
tag = "prep";
else if (lemma.endsWith("_Adv"))
tag = "adverb";
if (tag == null)
return;
int res = mTranslator.getTargetLanguage().getInflectionResource();
if (res == 0)
return;
ImageView arrow = (ImageView) view.findViewById(R.id.arrow);
arrow.setImageResource(R.drawable.close_arrow);
@@ -127,69 +102,8 @@ public class LexicalEntryActivity extends ListActivity {
((RelativeLayout) view).addView(inflectionView, params);
}
Expr expr = Expr.readExpr(lemma);
Map<String,String> lins = mTranslator.tabularLinearize(expr);
XmlResourceParser parser = getResources().getXml(res);
StringBuilder builder = new StringBuilder();
builder.append("<html><head><meta charset=\"UTF-8\"/></head><body>");
try {
boolean emit = false;
boolean form = false;
int event = parser.next();
while (event != XmlResourceParser.END_DOCUMENT) {
switch (event) {
case XmlResourceParser.START_TAG:
if (tag.equals(parser.getName())) {
emit = true;
} if ("form".equals(parser.getName())) {
form = true;
} else if (emit) {
builder.append("<"+parser.getName());
int n_attrs = parser.getAttributeCount();
for (int i = 0; i < n_attrs; i++) {
builder.append(' ');
builder.append(parser.getAttributeName(i));
builder.append("=\"");
builder.append(parser.getAttributeValue(i));
builder.append("\"");
}
builder.append(">");
}
break;
case XmlResourceParser.END_TAG:
if (tag.equals(parser.getName())) {
emit = false;
} else if ("form".equals(parser.getName())) {
form = false;
} else if (emit) {
builder.append("</"+parser.getName()+">");
}
break;
case XmlResourceParser.TEXT:
if (emit) {
if (form) {
String s = lins.get(parser.getText());
if (s != null)
builder.append(s);
} else {
builder.append(parser.getText());
}
}
break;
}
event = parser.next();
}
} catch (IOException e) {
e.printStackTrace();
} catch (XmlPullParserException e) {
e.printStackTrace();
} finally {
parser.close();
}
builder.append("</body>");
inflectionView.loadData(builder.toString(), "text/html; charset=UTF-8", null);
String html = mTranslator.getInflectionTable(lemma);
inflectionView.loadData(html, "text/html; charset=UTF-8", null);
expandedView = view;
}
@@ -211,7 +125,7 @@ public class LexicalEntryActivity extends ListActivity {
TextView descView =
(TextView) convertView.findViewById(R.id.lexical_desc);
String phrase = mTranslator.generateTranslationEntry(lemma);
String phrase = mTranslator.generateLexiconEntry(lemma);
descView.setText(phrase);
convertView.setOnClickListener(new OnClickListener() {

View File

@@ -2,6 +2,7 @@ package org.grammaticalframework.ui.android;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.XmlResourceParser;
import android.util.Log;
import org.grammaticalframework.pgf.Concr;
@@ -9,6 +10,7 @@ import org.grammaticalframework.pgf.Expr;
import org.grammaticalframework.pgf.MorphoAnalysis;
import org.grammaticalframework.pgf.PGF;
import org.grammaticalframework.pgf.ParseError;
import org.xmlpull.v1.XmlPullParserException;
import java.io.FileNotFoundException;
import java.io.IOException;
@@ -38,6 +40,8 @@ public class Translator {
new Language("sv-SE", "Swedish", "ParseSwe", R.xml.inflection_sv, R.xml.qwerty),
};
private Context mContext;
private Language mSourceLanguage;
private Language mTargetLanguage;
@@ -69,7 +73,9 @@ public class Translator {
}
public Translator(Context context) {
mGrammarLoader = new GrammarLoader(context);
mContext = context;
mGrammarLoader = new GrammarLoader();
mGrammarLoader.start();
mSharedPref = context.getSharedPreferences(
@@ -131,19 +137,182 @@ public class Translator {
}
}
public String generateTranslationEntry(String lemma) {
private String getLemmaTag(String lemma) {
String cat = getGrammar().getFunctionType(lemma).getCategory();
int res = getTargetLanguage().getInflectionResource();
if (res == 0)
return "";
XmlResourceParser parser = mContext.getResources().getXml(res);
try {
int state = 0;
int event = parser.next();
String tag = null;
boolean found = false;
while (event != XmlResourceParser.END_DOCUMENT) {
switch (event) {
case XmlResourceParser.START_TAG:
if (state == 0 && "inflection".equals(parser.getName())) {
state = 1;
tag = null;
found = false;
} else if (state == 1 && "cat".equals(parser.getName())) {
state = 2;
} else if (state == 1 && "tag".equals(parser.getName())) {
state = 3;
} else if (state == 1 && "template".equals(parser.getName())) {
state = 4;
}
break;
case XmlResourceParser.END_TAG:
if (state == 1 && "inflection".equals(parser.getName())) {
state = 0;
if (found)
return tag+".";
} else if (state == 2 && "cat".equals(parser.getName())) {
state = 1;
} else if (state == 3 && "tag".equals(parser.getName())) {
state = 1;
} else if (state == 4 && "template".equals(parser.getName())) {
state = 1;
}
break;
case XmlResourceParser.TEXT:
if (state == 2) {
if (cat.equals(parser.getText())) {
found = true;
}
} else if (state == 3) {
tag = parser.getText();
}
break;
}
event = parser.next();
}
} catch (IOException e) {
Log.e(TAG, "getLemmaTag", e);
} catch (XmlPullParserException e) {
Log.e(TAG, "getLemmaTag", e);
} finally {
parser.close();
}
return "";
}
public String generateLexiconEntry(String lemma) {
Expr e = Expr.readExpr(lemma);
Concr sourceLang = getConcr(getSourceLanguage().getConcrete());
Concr targetLang = getConcr(getTargetLanguage().getConcrete());
if (targetLang.hasLinearization(lemma))
return sourceLang.linearize(e) + " - " + targetLang.linearize(e);
return sourceLang.linearize(e) + " - " + getLemmaTag(lemma) + " " + targetLang.linearize(e);
else
return sourceLang.linearize(e);
return sourceLang.linearize(e) + " " + getLemmaTag(lemma);
}
public Map<String,String> tabularLinearize(Expr e) {
public String getInflectionTable(String lemma) {
String cat = getGrammar().getFunctionType(lemma).getCategory();
int res = getTargetLanguage().getInflectionResource();
if (res == 0)
return "";
Expr expr = Expr.readExpr(lemma);
Concr targetLang = getConcr(getTargetLanguage().getConcrete());
return targetLang.tabularLinearize(e);
Map<String,String> lins = targetLang.tabularLinearize(expr);
XmlResourceParser parser = mContext.getResources().getXml(res);
StringBuilder builder = new StringBuilder();
builder.append("<html><head><meta charset=\"UTF-8\"/></head><body>");
try {
int state = 0;
int event = parser.next();
boolean emit = false;
boolean form = false;
boolean lin = false;
StringBuilder abstrBuilder = null;
while (event != XmlResourceParser.END_DOCUMENT) {
switch (event) {
case XmlResourceParser.START_TAG:
if (state == 0 && "inflection".equals(parser.getName())) {
state = 1;
} else if (state == 1 && "cat".equals(parser.getName())) {
state = 2;
} else if (state == 1 && "template".equals(parser.getName())) {
state = 4;
} else if (state == 4 && "form".equals(parser.getName())) {
form = true;
} else if (state == 4 && emit && "lin".equals(parser.getName())) {
lin = true;
emit = false;
abstrBuilder = new StringBuilder();
} else if (state == 4 && lin && "cat".equals(parser.getName())) {
abstrBuilder.append(cat);
} else if (state == 4 && lin && "lemma".equals(parser.getName())) {
abstrBuilder.append(lemma);
} else if (state == 4 && emit) {
builder.append("<"+parser.getName());
int n_attrs = parser.getAttributeCount();
for (int i = 0; i < n_attrs; i++) {
builder.append(' ');
builder.append(parser.getAttributeName(i));
builder.append("=\"");
builder.append(parser.getAttributeValue(i));
builder.append("\"");
}
builder.append(">");
}
break;
case XmlResourceParser.END_TAG:
if (state == 1 && "inflection".equals(parser.getName())) {
state = 0;
} else if (state == 2 && "cat".equals(parser.getName())) {
state = 1;
} else if (state == 4 && "template".equals(parser.getName())) {
state = 1;
emit = false;
} else if (state == 4 && "form".equals(parser.getName())) {
form = false;
} else if (state == 4 && lin && "lin".equals(parser.getName())) {
Expr expr2 = Expr.readExpr(abstrBuilder.toString());
builder.append(targetLang.linearize(expr2));
emit = true;
} else if (state == 4 && emit) {
builder.append("</"+parser.getName()+">");
}
break;
case XmlResourceParser.TEXT:
if (state == 2) {
if (cat.equals(parser.getText()))
emit = true;
} else if (state == 4 && emit) {
if (form) {
String s = lins.get(parser.getText());
if (s != null)
builder.append(s);
} else {
builder.append(parser.getText());
}
} else if (state == 4 && lin) {
abstrBuilder.append(parser.getText());
}
break;
}
event = parser.next();
}
} catch (IOException e) {
e.printStackTrace();
} catch (XmlPullParserException e) {
e.printStackTrace();
} finally {
parser.close();
}
builder.append("</body>");
return builder.toString();
}
public List<MorphoAnalysis> lookupMorpho(String sentence) {
@@ -164,12 +333,6 @@ public class Translator {
}
private class GrammarLoader extends Thread {
private final Context mContext;
public GrammarLoader(Context context) {
mContext = context;
}
public void run() {
InputStream in = null;