Kaydet (Commit) fe43c922 authored tarafından Takeshi Abe's avatar Takeshi Abe Kaydeden (comit) Caolán McNamara

starmath: render the selected subexpression of MathML's <maction>

... specified by the selection attribute.
For its expected behavior, see the section <maction> in MathML 1.01:
<http://www.w3.org/TR/REC-MathML/chap3_6.html#sec3.6.1>

Change-Id: I70c1b2cfe1afec730f3e67ba0938bbaf8ada8e23
Reviewed-on: https://gerrit.libreoffice.org/14600Reviewed-by: 's avatarCaolán McNamara <caolanm@redhat.com>
Tested-by: 's avatarCaolán McNamara <caolanm@redhat.com>
üst 543b432f
<?xml version="1.0" encoding="UTF-8" ?>
<math xmlns="http://www.w3.org/1998/Math/MathML">
<mrow>
<mtable>
<mtr><maction actiontype="toggle"><mn>1</mn><mn>0</mn><mn>0</mn></maction></mtr>
<mtr><maction actiontype="toggle" selection="2"><mn>0</mn><mn>2</mn><mn>0</mn></maction></mtr>
<mtr><maction actiontype="toggle" selection="3"><mn>0</mn><mn>0</mn><mn>3</mn></maction></mtr>
</mtable>
</mrow>
</math>
...@@ -30,9 +30,11 @@ public: ...@@ -30,9 +30,11 @@ public:
virtual void tearDown() SAL_OVERRIDE; virtual void tearDown() SAL_OVERRIDE;
void testSimple(); void testSimple();
void testMaction();
CPPUNIT_TEST_SUITE(Test); CPPUNIT_TEST_SUITE(Test);
CPPUNIT_TEST(testSimple); CPPUNIT_TEST(testSimple);
CPPUNIT_TEST(testMaction);
CPPUNIT_TEST_SUITE_END(); CPPUNIT_TEST_SUITE_END();
private: private:
...@@ -83,6 +85,13 @@ void Test::testSimple() ...@@ -83,6 +85,13 @@ void Test::testSimple()
loadURL(getURLFromSrc("starmath/qa/extras/data/simple.mml")); loadURL(getURLFromSrc("starmath/qa/extras/data/simple.mml"));
} }
void Test::testMaction()
{
loadURL(getURLFromSrc("starmath/qa/extras/data/maction.mml"));
OUString sExpected("matrix {italic \"1\" ## italic \"2\" ## italic \"3\"}");
CPPUNIT_ASSERT_EQUAL_MESSAGE("loaded text", sExpected, mxDocShell->GetText());
}
CPPUNIT_TEST_SUITE_REGISTRATION(Test); CPPUNIT_TEST_SUITE_REGISTRATION(Test);
} }
......
...@@ -1756,12 +1756,16 @@ public: ...@@ -1756,12 +1756,16 @@ public:
class SmXMLActionContext_Impl : public SmXMLRowContext_Impl class SmXMLActionContext_Impl : public SmXMLRowContext_Impl
{ {
size_t mnSelection; // 1-based
public: public:
SmXMLActionContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix, SmXMLActionContext_Impl(SmXMLImport &rImport,sal_uInt16 nPrefix,
const OUString& rLName) : const OUString& rLName) :
SmXMLRowContext_Impl(rImport,nPrefix,rLName) SmXMLRowContext_Impl(rImport,nPrefix,rLName)
, mnSelection(1)
{} {}
void StartElement(const uno::Reference<xml::sax::XAttributeList> &xAttrList) SAL_OVERRIDE;
void EndElement() SAL_OVERRIDE; void EndElement() SAL_OVERRIDE;
}; };
...@@ -1957,6 +1961,13 @@ static const SvXMLTokenMapEntry aColorTokenMap[] = ...@@ -1957,6 +1961,13 @@ static const SvXMLTokenMapEntry aColorTokenMap[] =
XML_TOKEN_MAP_END XML_TOKEN_MAP_END
}; };
static const SvXMLTokenMapEntry aActionAttrTokenMap[] =
{
{ XML_NAMESPACE_MATH, XML_SELECTION, XML_TOK_SELECTION },
XML_TOKEN_MAP_END
};
const SvXMLTokenMap& SmXMLImport::GetPresLayoutElemTokenMap() const SvXMLTokenMap& SmXMLImport::GetPresLayoutElemTokenMap()
{ {
if (!pPresLayoutElemTokenMap) if (!pPresLayoutElemTokenMap)
...@@ -2022,6 +2033,12 @@ const SvXMLTokenMap& SmXMLImport::GetColorTokenMap() ...@@ -2022,6 +2033,12 @@ const SvXMLTokenMap& SmXMLImport::GetColorTokenMap()
return *pColorTokenMap; return *pColorTokenMap;
} }
const SvXMLTokenMap& SmXMLImport::GetActionAttrTokenMap()
{
if (!pActionAttrTokenMap)
pActionAttrTokenMap = new SvXMLTokenMap(aActionAttrTokenMap);
return *pActionAttrTokenMap;
}
SvXMLImportContext *SmXMLDocContext_Impl::CreateChildContext( SvXMLImportContext *SmXMLDocContext_Impl::CreateChildContext(
...@@ -2589,18 +2606,58 @@ void SmXMLMultiScriptsContext_Impl::EndElement() ...@@ -2589,18 +2606,58 @@ void SmXMLMultiScriptsContext_Impl::EndElement()
ProcessSubSupPairs(bHasPrescripts); ProcessSubSupPairs(bHasPrescripts);
} }
void SmXMLActionContext_Impl::EndElement() void SmXMLActionContext_Impl::StartElement(const uno::Reference<xml::sax::XAttributeList> & xAttrList)
{ {
/*For now we will just assume that the sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
selected attribute is one, and then just display for (sal_Int16 i=0;i<nAttrCount;i++)
that expression alone, i.e. remove all expect the {
first pushed one*/ OUString sAttrName = xAttrList->getNameByIndex(i);
OUString aLocalName;
sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
GetKeyByAttrName(sAttrName,&aLocalName);
OUString sValue = xAttrList->getValueByIndex(i);
const SvXMLTokenMap &rAttrTokenMap =
GetSmImport().GetActionAttrTokenMap();
switch(rAttrTokenMap.Get(nPrefix,aLocalName))
{
case XML_TOK_SELECTION:
{
sal_uInt32 n = sValue.toUInt32();
if (n > 0) mnSelection = static_cast<size_t>(n);
}
break;
default:
break;
}
}
}
void SmXMLActionContext_Impl::EndElement()
{
SmNodeStack &rNodeStack = GetSmImport().GetNodeStack(); SmNodeStack &rNodeStack = GetSmImport().GetNodeStack();
for (auto i=rNodeStack.size()-nElementCount;i > 1;i--) auto nSize = rNodeStack.size();
if (nSize <= nElementCount) {
// not compliant to maction's specification, e.g., no subexpressions
return;
}
assert(mnSelection > 0);
if (nSize < nElementCount + mnSelection) {
// No selected subexpression exists, which is a MathML error;
// fallback to selecting the first
mnSelection = 1;
}
assert(nSize >= nElementCount + mnSelection);
for (auto i=nSize-(nElementCount+mnSelection); i > 0; i--)
{
rNodeStack.pop_front();
}
auto pSelected = rNodeStack.pop_front();
for (auto i=rNodeStack.size()-nElementCount; i > 0; i--)
{ {
rNodeStack.pop_front(); rNodeStack.pop_front();
} }
rNodeStack.push_front(pSelected.release());
} }
SvXMLImportContext *SmXMLImport::CreateContext(sal_uInt16 nPrefix, SvXMLImportContext *SmXMLImport::CreateContext(sal_uInt16 nPrefix,
...@@ -2858,6 +2915,7 @@ SmXMLImport::~SmXMLImport() throw () ...@@ -2858,6 +2915,7 @@ SmXMLImport::~SmXMLImport() throw ()
delete pColorTokenMap; delete pColorTokenMap;
delete pOperatorAttrTokenMap; delete pOperatorAttrTokenMap;
delete pAnnotationAttrTokenMap; delete pAnnotationAttrTokenMap;
delete pActionAttrTokenMap;
} }
void SmXMLImport::SetViewSettings(const Sequence<PropertyValue>& aViewProps) void SmXMLImport::SetViewSettings(const Sequence<PropertyValue>& aViewProps)
......
...@@ -80,6 +80,7 @@ class SmXMLImport : public SvXMLImport ...@@ -80,6 +80,7 @@ class SmXMLImport : public SvXMLImport
SvXMLTokenMap *pPresScriptEmptyElemTokenMap; SvXMLTokenMap *pPresScriptEmptyElemTokenMap;
SvXMLTokenMap *pPresTableElemTokenMap; SvXMLTokenMap *pPresTableElemTokenMap;
SvXMLTokenMap *pColorTokenMap; SvXMLTokenMap *pColorTokenMap;
SvXMLTokenMap *pActionAttrTokenMap;
SmNodeStack aNodeStack; SmNodeStack aNodeStack;
bool bSuccess; bool bSuccess;
...@@ -241,6 +242,7 @@ public: ...@@ -241,6 +242,7 @@ public:
const SvXMLTokenMap &GetPresScriptEmptyElemTokenMap(); const SvXMLTokenMap &GetPresScriptEmptyElemTokenMap();
const SvXMLTokenMap &GetPresTableElemTokenMap(); const SvXMLTokenMap &GetPresTableElemTokenMap();
const SvXMLTokenMap &GetColorTokenMap(); const SvXMLTokenMap &GetColorTokenMap();
const SvXMLTokenMap &GetActionAttrTokenMap();
SmNodeStack & GetNodeStack() { return aNodeStack; } SmNodeStack & GetNodeStack() { return aNodeStack; }
SmNode *GetTree() SmNode *GetTree()
...@@ -339,6 +341,10 @@ enum SmXMLAnnotationAttrTokenMap ...@@ -339,6 +341,10 @@ enum SmXMLAnnotationAttrTokenMap
XML_TOK_ENCODING XML_TOK_ENCODING
}; };
enum SmXMLActionAttrTokenMap
{
XML_TOK_SELECTION
};
#endif #endif
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment