Рендеринг кликабельной математики на Android

Я пытаюсь создать приложение для Android для визуального управления алгеброй. Есть ли какая-нибудь библиотека, которую я мог бы использовать, чтобы сделать ее доступной для выбора, как в кликабельной алгебре? Идеальная библиотека потребует некоторой символической алгебры, например. в форме MathML, отображать его на экране и возвращать события onTouch или аналогичные, указывающие, какая часть отображаемой алгебры была затронута.

Например, в квадратичной формуле пользователь мог коснуться 4ac в квадратном корне, и эта библиотека сообщит мне, что 4ac в квадратном корне была затронута, поэтому я мог затем выделить 4ac, чтобы пользователь знал, что это было выбранный, и скопируйте его независимо от окружающей алгебры. Другим примером может быть выбор одного члена в уравнении, чтобы приложение могло затем изменить или заменить его.

Любой эквивалент подойдет; библиотека, которая могла бы вернуть графическое представление уравнения, а также определить, какая часть этого уравнения была затронута символически с учетом координат щелчка на графике, была бы в порядке. По сути, я ищу визуализатор MathML (или аналогичный), который точно знает, что представляет собой каждый бит его рендеринга.

Я просмотрел symja, sympy и MathJax и не нашел способа сделать это, хотя немного заблудился. Где-то это уже есть?

Заранее спасибо.


person dataduck    schedule 29.10.2013    source источник
comment
MathJax можно использовать для подобных вещей, хотя это требует некоторой работы. См. мой ответ на аналогичный вопрос пользователя MathJax. Форум.   -  person Davide Cervone    schedule 04.12.2013
comment
См. этот проект, чтобы получить некоторые идеи: github.com/Divedo/math-dragon или в Google играть: play.google.com/store/apps/details? id=org.teaminfty.math_dragon   -  person axelclk    schedule 24.07.2014


Ответы (1)


Самый прямой путь - добавить свойства onClick непосредственно в используемый вами MathML и использовать оттуда идентификаторы элементов и привязку методов Java/JavaScript. Однако, насколько мне известно, атрибут onClick (пока?) не поддерживается в MathML.

Что я сделал в качестве обходного пути, так это добавил ссылки к каждому из ваших кликабельных элементов MathML, а затем перегрузил метод shouldOverrideUrlLoading() WebViewClient для вашего WebView, чтобы поймать вызываемые ссылки. Затем, если вы добавите уникальные значения ID где-нибудь в свои ссылки, вы сможете определить, какой элемент был нажат.

Измените загруженный MathML

Если ваш исходный MathML выглядит так:

<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
        <msqrt>
          <msup><mi>b</mi><mn>2</mn></msup>
          <mo>−</mo>
          <mn>4</mn><mi>a</mi><mi>c</mi>
        </msqrt>
</math>

измените его на что-то вроде:

<math xmlns="http://www.w3.org/1998/Math/MathML" display="block">
        <msqrt href=id1>
          <msup><mi>b</mi><mn>2</mn></msup>
          <mo>−</mo>
          <mstyle href=id2><mn>4</mn><mi>a</mi><mi>c</mi></mstyle>
        </msqrt>
</math>

Обратите внимание на вложенные ссылки. При использовании вывода HTML-CSS для MathJax активно щелкают только самую нижнюю ссылку. Однако при использовании вывода SVG каждая ссылка вызывается в порядке от самого низкого уровня до самого высокого уровня. Итак, для того, что я предлагаю, вам придется использовать выходные данные HTML-CSS от MathJax. Если я найду способ заставить SVG работать, я внесу правку.

Перегрузка shouldOverrideUrlLoading()

Это описано в ряде вопросов StackOverflow по этому поводу, и вы можете обратиться к сайту Android Devs за подробностями (здесь), так что я не буду вдаваться в подробности. По сути, shouldOverrideUrlLoading() будет иметь строку URL-адреса со ссылкой, которую вы указали для элементов MathML, по которым только что щелкнули. Проанализируйте это значение идентификатора и отправьте его функции, которая может его использовать, и все готово.

Вот код, который я использовал в своем проекте.

public class MathmlLinksViewClient extends WebViewClient {

    //protected MainActivity activity;
    public MathmlLinksViewClient(MainActivity context) {
        activity = context;
    }
    
    @Override
    public boolean shouldOverrideUrlLoading(WebView view, String url) {
        // Reroutes id int value to MainActivity method
        activity.onMathmlClick(
                Integer.valueOf(
                            // Method I wrote to parse ID from URL
                            HtmlIdFormat.getIdFromString(url) ) );
        return true;
    }

}

Обратите внимание, что URL-адрес, который передается этой функции, не является точно ссылкой, которую вы включаете в свои элементы MathML. каждому из них предшествует ссылка на хост, указанная при использовании метода WebView.loadDataWithBaseUrl() для вашего WebView. (Я предполагаю, что вы следуете этому руководству. для визуализации MathML.)

Если ваше представление оперирует какими-либо другими HTML-ссылками, вам нужно добавить оператор if, чтобы разделить действия со ссылками на элементы MathML и ссылками на веб-сайты. Опять же, вы можете изучить, как эффективно использовать shouldOverrideUrlLoading().

Единственным недостатком является то, что он добавит синий цвет ссылки ко всем связанным объектам. Вы должны иметь возможность переопределить это в MathML, установив черный цвет всех элементов с помощью объявления mstyle, но в настоящее время у меня возникают проблемы с этим.

Я не охватила совсем все, но я надеюсь, что это поможет!

person CrepeGoat    schedule 22.06.2014