/* ---------------Xalan XSLT Extension Functions ---------------- */
public static String getFirstStyleFromClass
(String classValue
) {
int i
= classValue.
indexOf(" ");
if (i
>0
) {
return classValue.
substring(0, i
);
} else {
return classValue
;
}
}
/**
* Intent is to be able to detect a normal paragraph;
* A Normal style is implied by Word, never explicit.
*
* @param classValue
* @return
*/
public static boolean isNormalParagraph
(String classValue
) {
if (classValue
== null || classValue.
trim().
equals("") ) {
return true;
} else if (classValue.
startsWith("Normal") ) {
return true;
} else {
return false;
}
}
/**
* Word has @xml:space="preserve" iff the string starts or
* ends with a space.
*
* @param theText
* @return
*/
public static boolean needPreserveSpace
(String theText
) {
if (theText
== null ) {
return false;
} else if (theText.
startsWith(" ")
|| theText.
endsWith(" ")) {
return true;
} else {
return false;
}
}
public static DocumentFragment createPPr
(String classVal,
String styleVal
) {
// create a pPr object
PPr pPr
= Context.
getWmlObjectFactory().
createPPr();
// if @class!=null
if (classVal
!=null && !classVal.
equals("") ) {
if (isNormalParagraph
(classVal
)) {
// Don't attach Normal, its implied
} else {
// create <w:rStyle>
PStyle pStyle
= Context.
getWmlObjectFactory().
createPPrBasePStyle();
// set @w:val from getFirstStyleFromClass($class)
pStyle.
setVal( getFirstStyleFromClass
(classVal
) );
// add this to rPr
pPr.
setPStyle(pStyle
);
}
}
// other pPr
if (styleVal
!=null && !styleVal.
equals("") ) {
setPPr
(pPr, styleVal
);
}
// convert our rPr to a document fragment, and return it
Document document
= XmlUtils.
marshaltoW3CDomDocument(pPr
);
DocumentFragment docfrag
= document.
createDocumentFragment();
docfrag.
appendChild(document.
getDocumentElement());
return docfrag
;
}
public static void setPPr
(PPr pPr,
String styleVal
) {
// Create a CSSStyleDeclaration
if (cssOMParser
==null) {
cssOMParser
= new CSSOMParser
();
}
CSSStyleDeclaration cssStyleDeclaration
= null;
try {
cssStyleDeclaration
= cssOMParser.
parseStyleDeclaration(
new org.
w3c.
css.
sac.
InputSource(new StringReader(styleVal
)) );
} catch (IOException e
) {
log.
error(e
);
return;
}
// iterate through it
// for each entry,
for (int i
=0
; i
< cssStyleDeclaration.
getLength() ; i
++) {
String propertyName
= cssStyleDeclaration.
item(i
);
CSSValue value
= cssStyleDeclaration.
getPropertyCSSValue(propertyName
);
String cssText
= value.
getCssText();
// create a docx4j property object
Property property
= PropertyFactory.
createPropertyFromCssName(propertyName, value
);
if (property
!=null) {
// invoke AbstractRunProperty set
((AbstractParagraphProperty
)property
).
set(pPr
);
}
}
}
public static DocumentFragment createRPr
(NodeIterator spanNodeIt
) {
// create an rPr object
RPr rPr
= Context.
getWmlObjectFactory().
createRPr();
// Most nested is last child,
DTMNodeProxy n
= (DTMNodeProxy
)spanNodeIt.
nextNode();
int i
= 0;
String styleName
= null;
do {
log.
debug("In node " + i
);
if (n.
getNodeType()==org.
w3c.
dom.
Node.
DOCUMENT_NODE) {
log.
debug("unexpected DOCUMENT_NODE!");
// The following is just debug
NodeList nodes
= n.
getChildNodes();
if (nodes
!= null) {
log.
debug("it has child nodes");
for (int j
=0; j
<nodes.
getLength(); j
++) {
if (((org.
w3c.
dom.
Node)nodes.
item(j
)).
getLocalName().
equals("span") ) {
log.
debug("is a span");
if ( ((org.
w3c.
dom.
Node)nodes.
item(i
)).
hasChildNodes() ) {
log.
debug("nested child nodes");
}
// ignore
log.
debug(".. ignoring <span/> ");
} else {
log.
debug("is a " + ((org.
w3c.
dom.
Node)nodes.
item(j
)).
getLocalName()) ;
}
}
}
} else {
// Expected case
// handle <w:rStyle> - we only want the most nested
// so the last time we set it, we get it right
String classVal
= n.
getAttribute("class");
if (classVal
!=null && !classVal.
equals("")
&& !classVal.
equals("Apple-style-span")) {
log.
debug("@class=" + classVal
);
styleName
= getFirstStyleFromClass
(classVal
);
}
// other rPr
String styleVal
= n.
getAttribute("style");
if (styleVal
!=null && !styleVal.
equals("") ) {
if (classVal
== null ||
(classVal
!=null && !classVal.
equals("Apple-style-span")) ) {
// Ignore style="color: rgb(0, 0, 0)
// if there is an Apple-style-span
// which Chrome inserts when you backspace into a prior para
log.
debug("@style=" + styleVal
);
setRPr
(rPr, styleVal
);
}
}
}
// next
n
= (DTMNodeProxy
)spanNodeIt.
nextNode();
i
++;
} while ( n
!=null );
// create <w:rStyle>
if (styleName
!=null) {
RStyle rStyle
= Context.
getWmlObjectFactory().
createRStyle();
rStyle.
setVal( styleName
);
rPr.
setRStyle(rStyle
);
}
// convert our rPr to a document fragment, and return it
Document document
= XmlUtils.
marshaltoW3CDomDocument(rPr
);
DocumentFragment docfrag
= document.
createDocumentFragment();
docfrag.
appendChild(document.
getDocumentElement());
return docfrag
;
}
public static void setRPr
(RPr rPr,
String styleVal
) {
// Create a CSSStyleDeclaration
if (cssOMParser
==null) {
cssOMParser
= new CSSOMParser
();
}
CSSStyleDeclaration cssStyleDeclaration
= null;
try {
cssStyleDeclaration
= cssOMParser.
parseStyleDeclaration(
new org.
w3c.
css.
sac.
InputSource(new StringReader(styleVal
)) );
} catch (IOException e
) {
log.
error(e
);
return;
}
// iterate through it
// for each entry,
for (int i
=0
; i
< cssStyleDeclaration.
getLength() ; i
++) {
String propertyName
= cssStyleDeclaration.
item(i
);
CSSValue value
= cssStyleDeclaration.
getPropertyCSSValue(propertyName
);
String cssText
= value.
getCssText();
// create a docx4j property object
Property property
= PropertyFactory.
createPropertyFromCssName(propertyName, value
);
// invoke AbstractRunProperty set
if (property
!=null) {
((AbstractRunProperty
)property
).
set(rPr
);
}
}
}
private static CSSOMParser cssOMParser
= null;
/* Extension function to create an HTML <img> element
* from "E2.0 images"
* //w:drawing/wp:inline
* |//w:drawing/wp:anchor
*/
public static DocumentFragment createHtmlImgE20ForMSIE
(WordprocessingMLPackage wmlPackage,
String docID,
NodeIterator pictureData, NodeIterator picSize,
NodeIterator picLink, NodeIterator linkData
) {
WordXmlPicture picture
= createWordXmlPicture
( wmlPackage,
docID, pictureData, picSize,
picLink, linkData
);
Document d
= picture.
createHtmlImageElement();
log.
info( XmlUtils.
w3CDomNodeToString(d
) );
DocumentFragment docfrag
= d.
createDocumentFragment();
docfrag.
appendChild(d.
getDocumentElement());
return docfrag
;
}
public static WordXmlPicture createWordXmlPicture
(WordprocessingMLPackage wmlPackage,
String docID,
NodeIterator pictureData, NodeIterator picSize,
NodeIterator picLink, NodeIterator linkData
) {
// incoming objects are org.apache.xml.dtm.ref.DTMNodeIterator
// which implements org.w3c.dom.traversal.NodeIterator
WordXmlPicture picture
= new WordXmlPicture
();
picture.
readStandardAttributes( pictureData.
nextNode() );
org.
w3c.
dom.
Node picSizeNode
= picSize.
nextNode();
if ( picSizeNode
!=null ) {
picture.
readSizeAttributes(picSizeNode
);
}
org.
w3c.
dom.
Node linkDataNode
= linkData.
nextNode();
if (linkDataNode
== null) {
log.
warn("Couldn't find a:blip!");
} else {
String imgRelId
= ConvertUtils.
getAttributeValueNS(linkDataNode,
"http://schemas.openxmlformats.org/officeDocument/2006/relationships",
"embed"); // Microsoft code had r:link here
if (imgRelId
!=null && !imgRelId.
equals(""))
{
picture.
setID(imgRelId
);
Relationship rel
= wmlPackage.
getMainDocumentPart().
getRelationshipsPart().
getRelationshipByID(imgRelId
);
if (rel.
getTargetMode() == null
|| rel.
getTargetMode().
equals("Internal")) {
// Give them a link to the cached image which we'll serve dynamically
picture.
setSrc("/share/proxy/plutext/img"+docID
+"?id="+imgRelId
); // Can't use #, since the client doesn't send fragment to the server
} else {
// Give them a link to an External image
picture.
setSrc(rel.
getTarget());
}
}
// if the relationship isn't found, produce a warning
// if (String.IsNullOrEmpty(picture.Src))
// {
// this.embeddedPicturesDropped++;
// }
}
return picture
;
}
Parsed in 0.036 seconds, using
GeSHi 1.0.8.4