Added DeepL html support

This commit is contained in:
M66B 2022-04-06 19:35:53 +02:00
parent 74711292fa
commit 229111377a
5 changed files with 74 additions and 17 deletions

View File

@ -8155,7 +8155,7 @@ public class AdapterMessage extends RecyclerView.Adapter<AdapterMessage.ViewHold
protected DeepL.Translation onExecute(Context context, Bundle args) throws Throwable {
String text = args.getString("text");
String target = args.getString("target");
return DeepL.translate(text, target, context);
return DeepL.translate(text, false, target, context);
}
@Override

View File

@ -28,7 +28,10 @@ import android.graphics.Paint;
import android.net.Uri;
import android.os.Bundle;
import android.text.Editable;
import android.text.SpannableStringBuilder;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.RelativeSizeSpan;
import android.util.Pair;
import android.view.LayoutInflater;
import android.view.View;
@ -45,6 +48,7 @@ import androidx.preference.PreferenceManager;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.jsoup.nodes.Document;
import java.io.FileNotFoundException;
import java.io.IOException;
@ -190,21 +194,41 @@ public class DeepL {
return null;
}
public static Translation translate(String text, String target, Context context) throws IOException, JSONException {
public static Translation translate(CharSequence text, boolean html, String target, Context context) throws IOException, JSONException {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean formality = prefs.getBoolean("deepl_formal", true);
return translate(text, target, formality, context);
boolean deepl_formal = prefs.getBoolean("deepl_formal", true);
boolean deepl_html = prefs.getBoolean("deepl_html", false);
return translate(text, html && deepl_html, target, deepl_formal, context);
}
public static Translation translate(String text, String target, boolean formality, Context context) throws IOException, JSONException {
public static Translation translate(CharSequence text, boolean html, String target, boolean formality, Context context) throws IOException, JSONException {
if (!ConnectionHelper.getNetworkState(context).isConnected())
throw new IllegalArgumentException(context.getString(R.string.title_no_internet));
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
boolean small = prefs.getBoolean("deepl_small", false);
String key = prefs.getString("deepl_key", null);
String input;
if (html) {
SpannableStringBuilder ssb = new SpannableStringBuilderEx(text);
if (small)
for (RelativeSizeSpan span : ssb.getSpans(0, ssb.length(), RelativeSizeSpan.class))
if (span.getSizeChange() == HtmlHelper.FONT_SMALL)
ssb.removeSpan(span);
input = HtmlHelper.toHtml(ssb, context);
} else
input = text.toString();
// https://www.deepl.com/docs-api/translating-text/request/
String request =
"text=" + URLEncoder.encode(text, StandardCharsets.UTF_8.name()) +
"text=" + URLEncoder.encode(input, StandardCharsets.UTF_8.name()) +
"&target_lang=" + URLEncoder.encode(target, StandardCharsets.UTF_8.name());
// https://www.deepl.com/docs-api/handling-html-(beta)/
if (html)
request += "&tag_handling=html";
ensureLanguages(context);
for (int i = 0; i < jlanguages.length(); i++) {
JSONObject jlanguage = jlanguages.getJSONObject(i);
@ -216,9 +240,6 @@ public class DeepL {
}
}
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
String key = prefs.getString("deepl_key", null);
URL url = new URL(getBaseUri(context) + "translate?auth_key=" + key);
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setRequestMethod("POST");
@ -258,7 +279,15 @@ public class DeepL {
Translation result = new Translation();
result.target_language = target;
result.detected_language = jtranslation.getString("detected_source_language");
result.translated_text = jtranslation.getString("text");
String output = jtranslation.getString("text");
if (html) {
Document document = HtmlHelper.sanitizeCompose(context, output, false);
result.translated_text = HtmlHelper.fromDocument(context, document, null, null);
} else
result.translated_text = output;
return result;
} finally {
connection.disconnect();
@ -335,7 +364,7 @@ public class DeepL {
public static class Translation {
public String detected_language;
public String target_language;
public String translated_text;
public CharSequence translated_text;
}
public static class FragmentDialogDeepL extends FragmentDialogBase {
@ -348,6 +377,7 @@ public class DeepL {
boolean pro = prefs.getBoolean("deepl_pro", false);
boolean formal = prefs.getBoolean("deepl_formal", true);
boolean small = prefs.getBoolean("deepl_small", false);
boolean html = prefs.getBoolean("deepl_html", false);
int subscription = prefs.getInt("deepl_subscription", BuildConfig.DEBUG ? 17 : 0);
View view = LayoutInflater.from(context).inflate(R.layout.dialog_deepl, null);
@ -357,6 +387,7 @@ public class DeepL {
final CheckBox cbFormal = view.findViewById(R.id.cbFormal);
final TextView tvFormal = view.findViewById(R.id.tvFormal);
final CheckBox cbSmall = view.findViewById(R.id.cbSmall);
final CheckBox cbHtml = view.findViewById(R.id.cbHtml);
final TextView tvUsage = view.findViewById(R.id.tvUsage);
final TextView tvPrivacy = view.findViewById(R.id.tvPrivacy);
@ -398,6 +429,7 @@ public class DeepL {
}
cbSmall.setChecked(small);
cbHtml.setChecked(html);
tvUsage.setVisibility(View.GONE);
@ -460,6 +492,7 @@ public class DeepL {
editor.putBoolean("deepl_pro", cbPro.isChecked());
editor.putBoolean("deepl_formal", cbFormal.isChecked());
editor.putBoolean("deepl_small", cbSmall.isChecked());
editor.putBoolean("deepl_html", cbHtml.isChecked());
editor.apply();
}
})

View File

@ -2141,12 +2141,14 @@ public class FragmentCompose extends FragmentBase {
if (paragraph == null)
return;
etBody.clearComposingText();
Editable edit = etBody.getText();
String text = edit.subSequence(paragraph.first, paragraph.second).toString();
CharSequence text = edit.subSequence(paragraph.first, paragraph.second);
Bundle args = new Bundle();
args.putString("target", target);
args.putString("text", text);
args.putCharSequence("text", text);
new SimpleTask<DeepL.Translation>() {
private Object highlightSpan;
@ -2169,8 +2171,8 @@ public class FragmentCompose extends FragmentBase {
@Override
protected DeepL.Translation onExecute(Context context, Bundle args) throws Throwable {
String target = args.getString("target");
String text = args.getString("text");
return DeepL.translate(text, target, context);
CharSequence text = args.getCharSequence("text");
return DeepL.translate(text, true, target, context);
}
@Override
@ -2206,7 +2208,8 @@ public class FragmentCompose extends FragmentBase {
at android.text.SpannableStringBuilder.insert(SpannableStringBuilder.java:38)
*/
int len = 2 + translation.translated_text.length();
edit.insert(paragraph.second, "\n\n" + translation.translated_text);
edit.insert(paragraph.second, translation.translated_text);
edit.insert(paragraph.second, "\n\n");
StyleHelper.markAsTranslated(edit, paragraph.second, paragraph.second + len);
etBody.setSelection(paragraph.second + len);

View File

@ -90,6 +90,25 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvFormal" />
<CheckBox
android:id="@+id/cbHtml"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:text="@string/title_translate_html"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cbSmall" />
<eu.faircode.email.FixedTextView
android:id="@+id/tvHtml"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:text="@string/title_translate_html_hint"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cbHtml" />
<eu.faircode.email.FixedTextView
android:id="@+id/tvUsage"
android:layout_width="wrap_content"
@ -98,7 +117,7 @@
android:text="Usage"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/cbSmall" />
app:layout_constraintTop_toBottomOf="@id/tvHtml" />
<eu.faircode.email.FixedTextView
android:id="@+id/tvPrivacy"

View File

@ -1368,6 +1368,8 @@
<string name="title_translating">Translating &#8230;</string>
<string name="title_translate_formal">Use formal form</string>
<string name="title_translate_small">Use a small font for the source text</string>
<string name="title_translate_html">Preserve formatting</string>
<string name="title_translate_html_hint">This will consume more characters</string>
<string name="title_translate_usage">Usage: %1$s / %2$s (%3$d %%)</string>
<string name="title_translate_tap">Tap the text to be translated</string>
<string name="title_edit_plain_text">Edit as plain text</string>