\n", m_iCards).utf8_str());
m_bInSection = true;
}
}
void s_WML_Listener::_closeBlock(void)
{
_closeAnchor();
_closeHyperlink();
if(!m_bInBlock)
{
return;
}
if(!m_bInTable)
{
m_pie->write("\n");
}
m_bInBlock = false;
return;
}
void s_WML_Listener::_openParagraph(PT_AttrPropIndex api)
{
xxx_UT_DEBUGMSG(("WML Export: OpenParagraph called!\n"));
const PP_AttrProp * pAP = NULL;
bool bHaveProp = m_pDocument->getAttrProp(api,&pAP);
if(!m_bInSection)
_openSection(api);
if (m_bInTable) // tags aren't allowed inside of table-related tags
{
m_bInBlock = true;
return;
}
if (bHaveProp && pAP)
{
const XML_Char * szValue;
m_pie->write("
getProperty("text-align", szValue))
{
if (!UT_strcmp(szValue, "center"))
m_pie->write(" align=\"center\"");
else if (!UT_strcmp(szValue, "right"))
m_pie->write(" align=\"right\"");
else //left or block-justify
m_pie->write(" align=\"left\"");
}
m_pie->write(">");
}
else
{
//
with no style attribute, and no properties either
m_pie->write("
");
}
m_bInBlock = true;
}
/*****************************************************************/
/*****************************************************************/
bool s_WML_Listener::populate(PL_StruxFmtHandle /*sfh*/,
const PX_ChangeRecord * pcr)
{
switch (pcr->getType())
{
case PX_ChangeRecord::PXT_InsertSpan:
{
const PX_ChangeRecord_Span * pcrs = static_cast (pcr);
PT_AttrPropIndex api = pcr->getIndexAP();
if (api)
{
_openSpan(api);
}
PT_BufIndex bi = pcrs->getBufIndex();
_outputData(m_pDocument->getPointer(bi),pcrs->getLength());
if (api)
_closeSpan();
return true;
}
case PX_ChangeRecord::PXT_InsertObject:
{
const PX_ChangeRecord_Object * pcro = static_cast (pcr);
PT_AttrPropIndex api = pcr->getIndexAP();
switch (pcro->getObjectType())
{
case PTO_Image:
{
_handleImage(api);
return true;
}
case PTO_Field:
{
_handleField(pcro, api);
return true;
}
case PTO_Hyperlink:
{
_handleHyperlink(api);
return true;
}
case PTO_Bookmark:
{
_handleBookmark(api);
return true;
}
case PTO_Embed:
{
_handleEmbedded(api);
return true;
}
case PTO_Math:
{
_handleMath(api);
return true;
}
default:
UT_ASSERT(UT_TODO);
return true;
}
}
case PX_ChangeRecord::PXT_InsertFmtMark:
return true;
default:
UT_ASSERT(UT_TODO);
return true;
}
}
bool s_WML_Listener::populateStrux(PL_StruxDocHandle sdh,
const PX_ChangeRecord * pcr,
PL_StruxFmtHandle * psfh)
{
UT_ASSERT(pcr->getType() == PX_ChangeRecord::PXT_InsertStrux);
const PX_ChangeRecord_Strux * pcrx = static_cast (pcr);
*psfh = 0; // we don't need it.
switch (pcrx->getStruxType())
{
case PTX_Section:
case PTX_SectionFrame:
case PTX_SectionHdrFtr:
{
if(!m_bInTable)
{
_closeSection();
_openSection(pcr->getIndexAP());
}
return true;
}
case PTX_Block:
{
_closeSpan();
_closeBlock();
_openParagraph(pcr->getIndexAP());
return true;
}
case PTX_SectionTable:
{
m_iTableDepth++;
if(m_iTableDepth == 1)
{
_closeSpan();
_closeBlock();
mTableHelper.OpenTable(sdh,pcr->getIndexAP());
_openTable(pcr->getIndexAP());
}
return true;
}
case PTX_EndTable:
{
m_iTableDepth--;
if(m_iTableDepth == 0)
{
_closeBlock();
_closeTable();
mTableHelper.CloseTable();
}
return true;
}
case PTX_SectionCell:
{
if(m_iTableDepth == 1)
{
mTableHelper.OpenCell(pcr->getIndexAP()) ;
_closeSpan();
_closeBlock();
_openCell();
}
return true;
}
case PTX_EndCell:
{
if(m_iTableDepth == 1)
{
_closeBlock();
_closeCell();
mTableHelper.CloseCell();
}
return true;
}
case PTX_EndFrame:
{
if(!m_bInTable)
{
_closeSection();
}
return true;
}
case PTX_EndEndnote:
case PTX_EndFootnote:
case PTX_EndTOC:
case PTX_SectionEndnote:
case PTX_SectionFootnote:
case PTX_SectionTOC:
{
return true;
}
case PTX_EndMarginnote:
case PTX_SectionMarginnote:
default:
UT_ASSERT(UT_TODO);
return true;
}
}
bool s_WML_Listener::change(PL_StruxFmtHandle /*sfh*/,
const PX_ChangeRecord * /*pcr*/)
{
UT_ASSERT(0); // this function is not used.
return false;
}
bool s_WML_Listener::insertStrux(PL_StruxFmtHandle /*sfh*/,
const PX_ChangeRecord * /*pcr*/,
PL_StruxDocHandle /*sdh*/,
PL_ListenerId /* lid */,
void (* /*pfnBindHandles*/)(PL_StruxDocHandle /* sdhNew */,
PL_ListenerId /* lid */,
PL_StruxFmtHandle /* sfhNew */))
{
UT_ASSERT(0); // this function is not used.
return false;
}
bool s_WML_Listener::signal(UT_uint32 /* iSignal */)
{
UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
return false;
}
/*****************************************************************/
/*****************************************************************/
void s_WML_Listener::_handleMetaData()
{
UT_UTF8String metaProp("");
m_pie->write("\n");
#define WRITEMETA(name)\
metaProp.escapeXML();\
if(metaProp.length())\
m_pie->write(UT_UTF8String_sprintf("\n", name, metaProp.utf8_str()).utf8_str());\
if (m_pDocument->getMetaDataProp (PD_META_KEY_TITLE, metaProp) && metaProp.size())
{
WRITEMETA("title");
}
if (m_pDocument->getMetaDataProp (PD_META_KEY_CREATOR, metaProp) && metaProp.size())
{
WRITEMETA("author");
}
if (m_pDocument->getMetaDataProp (PD_META_KEY_SUBJECT, metaProp) && metaProp.size())
{
WRITEMETA("subject");
}
if (m_pDocument->getMetaDataProp (PD_META_KEY_DESCRIPTION, metaProp) && metaProp.size())
{
WRITEMETA("description");
}
if (m_pDocument->getMetaDataProp (PD_META_KEY_PUBLISHER, metaProp) && metaProp.size())
{
WRITEMETA("publisher");
}
if (m_pDocument->getMetaDataProp (PD_META_KEY_CONTRIBUTOR, metaProp) && metaProp.size())
{
WRITEMETA("contributor");
}
if (m_pDocument->getMetaDataProp (PD_META_KEY_DATE, metaProp) && metaProp.size())
{
WRITEMETA("date");
}
if (m_pDocument->getMetaDataProp (PD_META_KEY_SOURCE, metaProp) && metaProp.size())
{
WRITEMETA("source");
}
if (m_pDocument->getMetaDataProp (PD_META_KEY_RELATION, metaProp) && metaProp.size())
{
WRITEMETA("relation");
}
if (m_pDocument->getMetaDataProp (PD_META_KEY_COVERAGE, metaProp) && metaProp.size())
{
WRITEMETA("coverage");
}
if (m_pDocument->getMetaDataProp (PD_META_KEY_RIGHTS, metaProp) && metaProp.size())
{
WRITEMETA("rights");
}
if (m_pDocument->getMetaDataProp (PD_META_KEY_KEYWORDS, metaProp) && metaProp.size())
{
WRITEMETA("keywords");
}
#undef WRITEMETA
m_pie->write("\n");
}
/*****************************************************************/
/*****************************************************************/
void s_WML_Listener::_handleEmbedded(PT_AttrPropIndex api)
{
//this should never happen, but it doesn't hurt to make sure
if((m_bInTable && (!m_bInRow || !m_bInCell)))
{
UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
return;
}
const XML_Char* szValue = 0;
const PP_AttrProp * pAP = NULL;
bool bHaveProp = m_pDocument->getAttrProp(api,&pAP);
UT_return_if_fail(bHaveProp && pAP && pAP->getAttribute("dataid", szValue))
UT_UTF8String buf = "snapshot-png-";
buf += szValue;
char* dataid = UT_strdup(buf.utf8_str());
m_utvDataIDs.push_back(dataid);
buf += ".png";
m_pie->write("
write(UT_basename(m_pie->getFileName()));
m_pie->write("_data/");
m_pie->write(buf.utf8_str());
m_pie->write("\"");
UT_LocaleTransactor t(LC_NUMERIC, "C");
if(pAP->getProperty("height", szValue))
{
buf.clear();
UT_UTF8String_sprintf(buf, "%f", UT_convertToDimension(szValue, DIM_PX));
m_pie->write(" height=\"");
m_pie->write(buf.utf8_str());
m_pie->write("\"");
}
if(pAP->getProperty("width", szValue))
{
buf.clear();
UT_UTF8String_sprintf(buf, "%f", UT_convertToDimension(szValue, DIM_PX));
m_pie->write(" width=\"");
m_pie->write(buf.utf8_str());
m_pie->write("\"");
}
if(pAP->getProperty("lang", szValue))
{
m_pie->write(" xml:lang=\"");
m_pie->write(szValue);
m_pie->write("\"");
}
m_pie->write("/>");
}
/*****************************************************************/
/*****************************************************************/
void s_WML_Listener::_handleField(const PX_ChangeRecord_Object * pcro, PT_AttrPropIndex api)
{
//this can happen with certain .doc files
if((m_bInTable && (!m_bInRow || !m_bInCell)))
{
UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
return;
}
const PP_AttrProp * pAP = NULL;
const XML_Char* szValue = NULL;
bool bHaveProp = m_pDocument->getAttrProp(api,&pAP);
UT_return_if_fail(bHaveProp && pAP && pAP->getAttribute("type", szValue));
UT_UTF8String buf;
fd_Field * field = pcro->getField();
if(UT_strcmp(szValue, "list_label") != 0)
{
buf = field->getValue(); //retrieve the field text
buf.escapeXML();
if(buf.length())
{
m_pie->write(buf.utf8_str());
}
}
}
/*****************************************************************/
/*****************************************************************/
void s_WML_Listener::_handleBookmark(PT_AttrPropIndex api)
{
//this can happen with certain .doc files
if((m_bInTable && (!m_bInRow || !m_bInCell)))
{
UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
return;
}
const PP_AttrProp * pAP = NULL;
const XML_Char* szValue = NULL;
bool bHaveProp = m_pDocument->getAttrProp(api,&pAP);
UT_UTF8String buf;
if(bHaveProp && pAP && pAP->getAttribute("type", szValue))
{
_closeAnchor(); //nested anchors are not allowed
if(UT_strcmp(szValue, "start") == 0 && (m_bInHyperlink == 0) && pAP->getAttribute("name", szValue))
{
buf = szValue;
buf.escapeXML();
if(buf.length())
{
m_pie->write("write(buf.utf8_str());
m_pie->write("\">");
m_bInAnchor = true;
}
}
}
}
/*****************************************************************/
/*****************************************************************/
void s_WML_Listener::_handleHyperlink(PT_AttrPropIndex api)
{
//this can happen with certain .doc files
if((m_bInTable && (!m_bInRow || !m_bInCell)))
{
UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
return;
}
const PP_AttrProp * pAP = NULL;
const XML_Char* szValue = NULL;
bool bHaveProp = m_pDocument->getAttrProp(api,&pAP);
UT_UTF8String buf;
if(bHaveProp && pAP && pAP->getAttribute("xlink:href", szValue))
{
buf = szValue;
buf.escapeURL();
_closeAnchor();
_closeHyperlink();
if(buf.length())
{
m_pie->write("write(buf.utf8_str());
m_pie->write("\">");
m_bInHyperlink = true;
}
}
else
{
_closeHyperlink();
}
}
/*****************************************************************/
/*****************************************************************/
void s_WML_Listener::_handleMath(PT_AttrPropIndex api)
{
//this should never happen, but it doesn't hurt to make sure
if((m_bInTable && (!m_bInRow || !m_bInCell)))
{
UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
return;
}
const XML_Char* szValue = 0;
const PP_AttrProp * pAP = NULL;
bool bHaveProp = m_pDocument->getAttrProp(api,&pAP);
UT_return_if_fail(bHaveProp && pAP && pAP->getAttribute("dataid", szValue));
UT_UTF8String buf = "snapshot-png-";
buf += szValue;
char *dataid = UT_strdup(buf.utf8_str());
m_utvDataIDs.push_back(dataid);
buf += ".png";
m_pie->write("
write(UT_basename(m_pie->getFileName()));
m_pie->write("_data/");
m_pie->write(buf.utf8_str());
m_pie->write("\"");
if(pAP->getProperty("lang", szValue))
{
m_pie->write(" xml:lang=\"");
m_pie->write(szValue);
m_pie->write("\"");
}
m_pie->write("/>");
}
/*****************************************************************/
/*****************************************************************/
void s_WML_Listener::_handleImage(PT_AttrPropIndex api)
{
//this should never happen, but it doesn't hurt to make sure
if((m_bInTable && (!m_bInRow || !m_bInCell)))
{
UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
return;
}
const PP_AttrProp * pAP = NULL;
const XML_Char* szValue = NULL;
bool bHaveProp = m_pDocument->getAttrProp(api,&pAP);
UT_return_if_fail(bHaveProp && pAP && pAP->getAttribute("dataid", szValue));
UT_UTF8String buf;
char * dataid = UT_strdup(static_cast(szValue));
m_utvDataIDs.push_back(dataid);
char * temp = _stripSuffix(UT_basename(szValue), '_');
char * fstripped = _stripSuffix(temp, '.');
UT_UTF8String_sprintf(buf, "%s.png", fstripped);
FREEP(temp);
FREEP(fstripped);
m_pie->write("
getAttribute("alt", szValue)) // check for existing alt text
{
UT_UTF8String alt = szValue;
alt.escapeXML();
m_pie->write(alt.utf8_str());
}
else // fall back to the file name
{
m_pie->write("AbiWord Image ");
m_pie->write(buf.utf8_str());
}
m_pie->write("\" src=\"");
m_pie->write(UT_basename(m_pie->getFileName()));
m_pie->write("_data/");
m_pie->write(buf.utf8_str());
m_pie->write("\"");
const XML_Char * szWidth = 0;
const XML_Char * szHeight = 0;
UT_LocaleTransactor t(LC_NUMERIC, "C");
if(pAP->getProperty("width", szWidth))
{
if(szWidth)
{
UT_UTF8String_sprintf(buf, "%f", UT_convertToDimension(szWidth, DIM_PX));
m_pie->write (" width=\"");
m_pie->write (buf.utf8_str());
m_pie->write ("\"");
}
}
if(pAP->getProperty("height", szHeight))
{
if(szHeight)
{
UT_UTF8String_sprintf(buf, "%f", UT_convertToDimension(szHeight, DIM_PX));
m_pie->write (" height=\"");
m_pie->write (buf.utf8_str());
m_pie->write ("\"");
}
}
if(pAP->getProperty("lang", szValue))
{
m_pie->write(" xml:lang=\"");
m_pie->write(szValue);
m_pie->write("\"");
}
m_pie->write("/>");
}
/*****************************************************************/
/*****************************************************************/
void s_WML_Listener::_handlePositionedImage(PT_AttrPropIndex api)
{
//this should never happen, but it doesn't hurt to make sure
if((m_bInTable && (!m_bInRow || !m_bInCell)))
{
UT_ASSERT(UT_SHOULD_NOT_HAPPEN);
return;
}
const PP_AttrProp * pAP = NULL;
const XML_Char* szValue = NULL;
bool bHaveProp = m_pDocument->getAttrProp(api,&pAP);
UT_return_if_fail(bHaveProp && pAP && pAP->getAttribute("strux-image-dataid", szValue));
UT_UTF8String buf;
char * dataid = UT_strdup(static_cast(szValue));
m_utvDataIDs.push_back(dataid);
char * temp = _stripSuffix(UT_basename(szValue), '_');
char * fstripped = _stripSuffix(temp, '.');
UT_UTF8String_sprintf(buf, "%s.png", fstripped);
FREEP(temp);
FREEP(fstripped);
m_pie->write("
getAttribute("alt", szValue)) // check for existing alt text
{
UT_UTF8String alt = szValue;
alt.escapeXML();
m_pie->write(alt.utf8_str());
}
else // fall back to the file name
{
m_pie->write("AbiWord Image ");
m_pie->write(buf.utf8_str());
}
m_pie->write("\" src=\"");
m_pie->write(UT_basename(m_pie->getFileName()));
m_pie->write("_data/");
m_pie->write(buf.utf8_str());
m_pie->write("\"");
const XML_Char * szWidth = 0;
const XML_Char * szHeight = 0;
UT_LocaleTransactor t(LC_NUMERIC, "C");
if(pAP->getProperty("width", szWidth))
{
if(szWidth)
{
UT_UTF8String_sprintf(buf, "%f", UT_convertToDimension(szWidth, DIM_PX));
m_pie->write (" width=\"");
m_pie->write (buf.utf8_str());
m_pie->write ("\"");
}
}
if(pAP->getProperty("height", szHeight))
{
if(szHeight)
{
UT_UTF8String_sprintf(buf, "%f", UT_convertToDimension(szHeight, DIM_PX));
m_pie->write (" height=\"");
m_pie->write (buf.utf8_str());
m_pie->write ("\"");
}
}
if(pAP->getProperty("lang", szValue))
{
m_pie->write(" xml:lang=\"");
m_pie->write(szValue);
m_pie->write("\"");
}
m_pie->write("/>");
}
/*****************************************************************/
/*****************************************************************/
void s_WML_Listener::_handleDataItems(void)
{
const char * szName;
const char * szMimeType;
const UT_ByteBuf * pByteBuf;
for (UT_uint32 k=0; (m_pDocument->enumDataItems(k,NULL,&szName,&pByteBuf,reinterpret_cast(&szMimeType))); k++)
{
UT_sint32 loc = -1;
for (UT_uint32 i = 0; i < m_utvDataIDs.getItemCount(); i++)
{
if(UT_strcmp(static_cast(m_utvDataIDs[i]), szName) == 0)
{
loc = i;
break;
}
}
if(loc > -1)
{
FILE *fp;
UT_String fname;
#ifndef LEGIONS
UT_String_sprintf(fname, "%s_data", m_pie->getFileName());
#else
fname = "images";
#endif
UT_sint32 result = m_pDocument->getApp()->makeDirectory(fname.c_str(), 0750);
if (result < 0)
{
UT_DEBUGMSG(("WML Export: Failed to create directory\n"));
/* we might want to return an error here,
* but I don't think so. */
}
if (!UT_strcmp(szMimeType, "image/svg+xml"))
UT_String_sprintf(fname, "%s/%s_%d.svg", fname.c_str(), szName, loc);
if (!UT_strcmp(szMimeType, "application/mathml+xml"))
UT_String_sprintf(fname, "%s/%s_%d.mathml", fname.c_str(), szName, loc);
else // PNG Image
{
char * temp = _stripSuffix(UT_basename(szName), '_');
char * fstripped = _stripSuffix(temp, '.');
FREEP(temp);
UT_String_sprintf(fname, "%s/%s.png", fname.c_str(), fstripped);
FREEP(fstripped);
}
if (!UT_isRegularFile(fname.c_str()))
{
fp = fopen (fname.c_str(), "wb+");
if(!fp)
continue;
int cnt = 0, len = pByteBuf->getLength();
while (cnt < len)
{
cnt += fwrite (pByteBuf->getPointer(cnt),
sizeof(UT_Byte), len-cnt, fp);
}
fclose(fp);
}
}
}
}
/*****************************************************************/
/*****************************************************************/
void s_WML_Listener::_openSpan(PT_AttrPropIndex api)
{
if (!m_bInBlock || m_bInHyperlink || m_bInAnchor || (m_bInTable && (!m_bInRow || !m_bInCell)))
{
return;
}
const PP_AttrProp * pAP = NULL;
bool bHaveProp = m_pDocument->getAttrProp(api,&pAP);
if (bHaveProp && pAP)
{
const XML_Char * szValue = NULL;
if ((pAP->getProperty("font-weight", szValue))
&& !UT_strcmp(szValue, "bold"))
{
m_pie->write("");
}
if ((pAP->getProperty("font-style", szValue))
&& !UT_strcmp(szValue, "italic"))
{
m_pie->write("");
}
if ((pAP->getProperty("text-decoration", szValue)))
{
if(strstr(szValue,"underline"))
m_pie->write("");
}
// In my WML world...
// superscript = big
// subscript = small
if (pAP->getProperty("text-position", szValue))
{
if (!UT_strcmp("superscript", szValue))
{
m_pie->write("");
}
else if (!UT_strcmp("subscript", szValue))
{
m_pie->write("");
}
}
m_bInSpan = true;
m_pAP_Span = pAP;
}
}
void s_WML_Listener::_outputData(const UT_UCSChar * data, UT_uint32 length)
{
if (!m_bInBlock || (m_bInTable && (!m_bInRow || !m_bInCell)))
{
return;
}
// TODO deal with unicode.
// TODO for now, just squish it into ascii.
UT_UTF8String sBuf;
const UT_UCSChar * pData;
m_bWasSpace = false;
for (pData=data; (pData':
sBuf += ">";
pData++;
break;
case '&':
sBuf += "&";
pData++;
break;
case UCS_VTAB: // column break, export as a linebreak for now
case UCS_FF: // page break, export as a linebreak for now
case UCS_LF: // LF -- representing a Forced-Line-Break
sBuf += "
";
pData++;
break;
case ' ':
case UCS_TAB:
// try to honor multiple spaces
// tabs get treated as a single space
//
if(m_bWasSpace)
{
sBuf += " ";
pData++;
}
else
{
// just tack on a single space to the textrun
m_bWasSpace = true;
sBuf += " ";
pData++;
}
break;
default:
{
if(*pData < 0x20) //invalid xml chars
{
pData++;
}
else
{
sBuf.appendUCS4(pData, 1);
pData++;
}
m_bWasSpace = false;
}
}
}
m_pie->write(sBuf.utf8_str(),sBuf.byteLength());
}
void s_WML_Listener::_closeSpan(void)
{
if (!m_bInSpan || m_bInHyperlink || m_bInAnchor)
return;
const PP_AttrProp * pAP = m_pAP_Span;
if (pAP)
{
const XML_Char * szValue = NULL;
if (pAP->getProperty("text-position", szValue))
{
if (!UT_strcmp("superscript", szValue))
{
m_pie->write("");
}
else if (!UT_strcmp("subscript", szValue))
{
m_pie->write("");
}
}
if ((pAP->getProperty("text-decoration", szValue)))
{
if(strstr(szValue,"underline"))
m_pie->write("");
}
if ((pAP->getProperty("font-style", szValue))
&& !UT_strcmp(szValue, "italic"))
{
m_pie->write("");
}
if ((pAP->getProperty("font-weight", szValue))
&& !UT_strcmp(szValue, "bold"))
{
m_pie->write("");
}
m_pAP_Span = NULL;
}
m_bInSpan = false;
return;
}