1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * The Contents of this file are made available subject to the terms of
5 * either of the following licenses
7 * - GNU Lesser General Public License Version 2.1
8 * - Sun Industry Standards Source License Version 1.1
10 * Sun Microsystems Inc., October, 2000
12 * GNU Lesser General Public License Version 2.1
13 * =============================================
14 * Copyright 2000 by Sun Microsystems, Inc.
15 * 901 San Antonio Road, Palo Alto, CA 94303, USA
17 * This library is free software; you can redistribute it and/or
18 * modify it under the terms of the GNU Lesser General Public
19 * License version 2.1, as published by the Free Software Foundation.
21 * This library is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 * Lesser General Public License for more details.
26 * You should have received a copy of the GNU Lesser General Public
27 * License along with this library; if not, write to the Free Software
28 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
32 * Sun Industry Standards Source License Version 1.1
33 * =================================================
34 * The contents of this file are subject to the Sun Industry Standards
35 * Source License Version 1.1 (the "License"); You may not use this file
36 * except in compliance with the License. You may obtain a copy of the
37 * License at http://www.openoffice.org/license.html.
39 * Software provided under this License is provided on an "AS IS" basis,
40 * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
41 * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
42 * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
43 * See the License for the specific provisions governing your rights and
44 * obligations concerning the Software.
46 * The Initial Developer of the Original Code is: IBM Corporation
48 * Copyright: 2008 by IBM Corporation
50 * All Rights Reserved.
52 * Contributor(s): _______________________________________
55 ************************************************************************/
56 #include "lwpglobalmgr.hxx"
58 #include "lwpfootnote.hxx"
59 #include "lwppagehint.hxx"
60 #include "lwpdivinfo.hxx"
61 #include "lwpholder.hxx"
62 #include "lwpparastyle.hxx"
63 #include "lwpstory.hxx"
64 #include "lwppara.hxx"
65 #include "lwpsilverbullet.hxx"
66 #include "lwplayout.hxx"
67 #include "lwppagelayout.hxx"
68 #include "lwpverdocument.hxx"
69 #include "xfilter/xfstylemanager.hxx"
70 #include <osl/thread.h>
72 LwpDocument::LwpDocument(LwpObjectHeader
& objHdr
, LwpSvStream
* pStrm
)
73 : LwpDLNFPVList(objHdr
, pStrm
)
74 , m_pOwnedFoundry(nullptr)
75 , m_bGettingFirstDivisionWithContentsThatIsNotOLE(false)
77 , m_nPersistentFlags(0)
82 LwpDocument::~LwpDocument()
90 delete m_pOwnedFoundry
;
94 * @descr Read VO_Document from object stream
96 void LwpDocument::Read()
98 LwpDLNFPVList::Read();
102 m_nPersistentFlags
= m_pObjStrm
->QuickReaduInt32();
104 //Skip the SortOption and UIDocument
106 LwpSortOption
aDocSort( m_pObjStrm
.get() );
107 LwpUIDocument
aUIDoc( m_pObjStrm
.get() );
110 m_pLnOpts
= new LwpLineNumberOptions(m_pObjStrm
.get());
112 //Skip LwpUserDictFiles
114 LwpUserDictFiles
aUsrDicts( m_pObjStrm
.get() );
119 //Skip LwpPrinterInfo
120 LwpPrinterInfo
aPrtInfo( m_pObjStrm
.get() );
123 m_pFoundry
= m_pOwnedFoundry
= new LwpFoundry(m_pObjStrm
.get(), this);
125 m_DivOpts
.ReadIndexed(m_pObjStrm
.get());
129 m_FootnoteOpts
.ReadIndexed(m_pObjStrm
.get());
130 m_DocData
.ReadIndexed(m_pObjStrm
.get());
134 //Skip the docdata used in old version
135 LwpObjectID dummyDocData
;
136 dummyDocData
.ReadIndexed(m_pObjStrm
.get());
138 m_DivInfo
.ReadIndexed(m_pObjStrm
.get());
139 m_Epoch
.Read(m_pObjStrm
.get());
140 m_WYSIWYGPageHints
.ReadIndexed(m_pObjStrm
.get());
141 m_VerDoc
.ReadIndexed(m_pObjStrm
.get());
142 m_STXInfo
.ReadIndexed(m_pObjStrm
.get());
146 * @descr Read plug related data from m_pObjStram
148 void LwpDocument::ReadPlug()
150 m_DocSockID
.ReadIndexed(m_pObjStrm
.get());
151 m_nFlags
= m_pObjStrm
->QuickReaduInt16();
152 m_pObjStrm
->SkipExtra();
156 * @descr Parse obj to IXFStream
158 void LwpDocument::Parse(IXFStream
* pOutputStream
)
160 //check the name and skip script division
161 if (!IsSkippedDivision())
163 //the frames which anchor are to page must output before other contents
164 ParseFrameInPage(pOutputStream
);
165 ParseDocContent(pOutputStream
);
168 rtl::Reference
<LwpObject
> pDocSock
= GetSocket().obj( VO_DOCSOCK
);
171 pDocSock
->DoParse(pOutputStream
);
175 bool LwpDocument::IsSkippedDivision()
179 LwpDivInfo
* pDiv
= dynamic_cast<LwpDivInfo
*>(GetDivInfoID().obj(VO_DIVISIONINFO
).get());
182 sDivName
= pDiv
->GetDivName();
183 if (!sDivName
.isEmpty() && !pDiv
->IsGotoable()) //including toa,scripts division
185 //skip endnote division
186 OUString strClassName
= pDiv
->GetClassName();
187 if ((strClassName
== STR_DivisionEndnote
)
188 || (strClassName
== STR_DivisionGroupEndnote
)
189 || (strClassName
== STR_DocumentEndnote
))
191 LwpPageLayout
* pPageLayout
= dynamic_cast<LwpPageLayout
*>(pDiv
->GetInitialLayoutID().obj(VO_PAGELAYOUT
).get());
194 LwpStory
* pStory
= dynamic_cast<LwpStory
*>(pPageLayout
->GetContent().obj(VO_STORY
).get());
197 //This judgement maybe have problem. If there is only one para in the story,
198 //this endnote division has no other contents except endnote table.
199 LwpObjectID
& rFirst
= pStory
->GetFirstPara();
200 LwpObjectID
& rLast
= pStory
->GetLastPara();
210 * @descr Register all styles in this division
212 void LwpDocument::RegisterStyle()
214 RegisterDefaultParaStyles();
215 RegisterGraphicsStyles();
216 RegisterBulletStyles();
218 RegisterTextStyles();
219 RegisterLayoutStyles();
220 RegisterStylesInPara();
222 RegisterLinenumberStyles();
223 RegisterFootnoteStyles();
225 //Register styles in other document connected with this document: next doc, children doc
226 rtl::Reference
<LwpObject
> pDocSock
= GetSocket().obj();
229 pDocSock
->DoRegisterStyle();
233 * @descr Register all named para styles
235 void LwpDocument::RegisterTextStyles()
237 //Register all text styles: para styles, character styles
238 LwpDLVListHeadHolder
* pParaStyleHolder
= m_pFoundry
239 ? dynamic_cast<LwpDLVListHeadHolder
*>(m_pFoundry
->GetTextStyleHead().obj().get())
243 LwpTextStyle
* pParaStyle
= dynamic_cast<LwpTextStyle
*> (pParaStyleHolder
->GetHeadID().obj().get());
246 pParaStyle
->SetFoundry(m_pFoundry
);
247 pParaStyle
->RegisterStyle();
248 pParaStyle
= dynamic_cast<LwpParaStyle
*>(pParaStyle
->GetNext().obj().get());
251 ChangeStyleName();//for click here block
254 * @descr Register all layouts styles (page master and master page)
255 * All para styles used in master page (header and footer) are registered and then showed
257 void LwpDocument::RegisterLayoutStyles()
261 //Register all layout styles, before register all styles in para
262 m_pFoundry
->RegisterAllLayouts();
265 //set initial pagelayout in story for parsing pagelayout
266 LwpDivInfo
* pDivInfo
= dynamic_cast<LwpDivInfo
*> (m_DivInfo
.obj( VO_DIVISIONINFO
).get());
269 LwpPageLayout
* pPageLayout
= dynamic_cast<LwpPageLayout
*>(pDivInfo
->GetInitialLayoutID().obj(VO_PAGELAYOUT
).get());
272 //In Ole division, the content of pagelayout is VO_OLEOBJECT
273 LwpStory
* pStory
= dynamic_cast<LwpStory
*>(pPageLayout
->GetContent().obj(VO_STORY
).get());
276 //add all the pagelayout in order into the pagelayout list;
277 pStory
->SortPageLayout();
278 pStory
->SetCurrentLayout(pPageLayout
);
284 * @descr Register all styles used in para
286 void LwpDocument::RegisterStylesInPara()
288 //Register all automatic styles in para
289 rtl::Reference
<LwpHeadContent
> xContent(m_pFoundry
290 ? dynamic_cast<LwpHeadContent
*> (m_pFoundry
->GetContentManager().GetContentList().obj().get())
294 rtl::Reference
<LwpStory
> xStory(dynamic_cast<LwpStory
*>(xContent
->GetChildHead().obj(VO_STORY
).get()));
297 //Register the child para
298 xStory
->SetFoundry(m_pFoundry
);
299 xStory
->DoRegisterStyle();
300 xStory
.set(dynamic_cast<LwpStory
*>(xStory
->GetNext().obj(VO_STORY
).get()));
305 * @descr Register all bullet styles used in this division
307 void LwpDocument::RegisterBulletStyles()
311 //Register bullet styles
312 LwpDLVListHeadHolder
* pBulletHead
= dynamic_cast<LwpDLVListHeadHolder
*>
313 (m_pFoundry
->GetBulletManagerID().obj(VO_HEADHOLDER
).get());
316 LwpSilverBullet
* pBullet
= dynamic_cast<LwpSilverBullet
*>
317 (pBulletHead
->GetHeadID().obj().get());
320 pBullet
->SetFoundry(m_pFoundry
);
321 pBullet
->RegisterStyle();
322 pBullet
= dynamic_cast<LwpSilverBullet
*> (pBullet
->GetNext().obj().get());
326 * @descr Register all styles used in VO_Graphic
328 void LwpDocument::RegisterGraphicsStyles()
332 //Register all graphics styles, the first object should register the next;
333 rtl::Reference
<LwpObject
> pGraphic
= m_pFoundry
->GetGraphicListHead().obj(VO_GRAPHIC
);
336 pGraphic
->SetFoundry(m_pFoundry
);
337 pGraphic
->DoRegisterStyle();
340 * @descr Register line number styles
342 void LwpDocument::RegisterLinenumberStyles()
346 m_pLnOpts
->RegisterStyle();
350 * @descr Register footnote/endnote configuration for the entire document
352 void LwpDocument::RegisterFootnoteStyles()
354 //Register footnote and endnote configuration for the entire document
355 if(!m_FootnoteOpts
.IsNull())
357 LwpFootnoteOptions
* pFootnoteOpts
= dynamic_cast<LwpFootnoteOptions
*>(m_FootnoteOpts
.obj().get());
360 pFootnoteOpts
->SetMasterPage("Endnote");
361 pFootnoteOpts
->RegisterStyle();
364 //Register endnote page style for endnote configuration, use the last division that has endnote for the endnote page style
365 //This page style must register after its division default styles have registered
366 LwpDocument
* pEndnoteDiv
= GetLastDivisionThatHasEndnote();
367 if(this == pEndnoteDiv
)
369 LwpDLVListHeadTailHolder
* pHeadTail
= dynamic_cast<LwpDLVListHeadTailHolder
*>(GetPageHintsID().obj().get());
372 LwpPageHint
* pPageHint
= dynamic_cast<LwpPageHint
*>(pHeadTail
->GetTail().obj().get());
373 if(pPageHint
&& !pPageHint
->GetPageLayoutID().IsNull())
375 LwpPageLayout
* pPageLayout
= dynamic_cast<LwpPageLayout
*>(pPageHint
->GetPageLayoutID().obj().get());
378 pPageLayout
->SetFoundry(GetFoundry());
379 pPageLayout
->RegisterEndnoteStyle();
387 * @descr Register default para styles
389 void LwpDocument::RegisterDefaultParaStyles()
394 //LwpDocument* pFirstDoc = GetFirstDivision();
395 LwpDocument
* pFirstDoc
= GetFirstDivisionWithContentsThatIsNotOLE();
398 LwpVerDocument
* pVerDoc
= dynamic_cast<LwpVerDocument
*>(pFirstDoc
->GetVerDoc().obj().get());
401 pVerDoc
->RegisterStyle();
409 * @descr Parse content in this division to IXFStream
410 * LwpDocument->LwpDivInfo->LwpPageLayout.Parse()
412 void LwpDocument::ParseDocContent(IXFStream
* pOutputStream
)
414 //Parse content in PageLayout
415 LwpDivInfo
* pDivInfo
= dynamic_cast<LwpDivInfo
*> (m_DivInfo
.obj().get());
416 if(pDivInfo
==nullptr) return;
418 rtl::Reference
<LwpObject
> pLayoutObj
= pDivInfo
->GetInitialLayoutID().obj();
421 //master document not supported now.
424 pLayoutObj
->SetFoundry(m_pFoundry
);
425 pLayoutObj
->DoParse(pOutputStream
);
429 * @descr Get the footnoteoptions from the root document
431 LwpObjectID
* LwpDocument::GetValidFootnoteOpts()
433 LwpDocument
* pRoot
= GetRootDocument();
436 return &pRoot
->GetFootnoteOpts();
442 * @descr Get the endnote type
444 sal_uInt16
LwpDocument::GetEndnoteType()
446 LwpDivInfo
* pDivInfo
= dynamic_cast<LwpDivInfo
*>(GetDivInfoID().obj().get());
449 OUString strClassName
= pDivInfo
->GetClassName();
450 if (strClassName
== STR_DivisionEndnote
)
451 return FN_DIVISION_SEPARATE
;
452 if (strClassName
== STR_DivisionGroupEndnote
)
453 return FN_DIVISIONGROUP_SEPARATE
;
454 if (strClassName
== STR_DocumentEndnote
)
455 return FN_DOCUMENT_SEPARATE
;
459 * @descr Get previous division
461 LwpDocument
* LwpDocument::GetPreviousDivision()
463 LwpDocSock
* pDocSock
= dynamic_cast<LwpDocSock
*>(GetSocket().obj().get());
466 return dynamic_cast<LwpDocument
*>(pDocSock
->GetPrevious().obj().get());
471 * @descr Get next division
473 LwpDocument
* LwpDocument::GetNextDivision()
475 LwpDocSock
* pDocSock
= dynamic_cast<LwpDocSock
*>(GetSocket().obj().get());
478 return dynamic_cast<LwpDocument
*>(pDocSock
->GetNext().obj().get());
483 * @descr Get parent division
485 LwpDocument
* LwpDocument::GetParentDivision()
487 LwpDocSock
* pDocSock
= dynamic_cast<LwpDocSock
*>(GetSocket().obj().get());
490 return dynamic_cast<LwpDocument
*>(pDocSock
->GetParent().obj().get());
495 * @descr Get previous division in group, copy from lwp source code
497 LwpDocument
* LwpDocument::GetPreviousInGroup()
499 LwpDocument
* pPrev
= nullptr;
501 for (pPrev
= GetPreviousDivision(); pPrev
; pPrev
= pPrev
->GetPreviousDivision())
503 LwpDivInfo
* pDivInfo
= dynamic_cast<LwpDivInfo
*>(pPrev
->GetDivInfoID().obj().get());
504 if(pDivInfo
&& pDivInfo
->HasContents())
510 * @descr Get previous division in group, copy from lwp source code
512 LwpDocument
* LwpDocument::GetNextInGroup()
514 LwpDocument
* pNext
= nullptr;
516 for (pNext
= GetNextDivision(); pNext
; pNext
= pNext
->GetNextDivision())
518 LwpDivInfo
* pDivInfo
= dynamic_cast<LwpDivInfo
*>(pNext
->GetDivInfoID().obj().get());
519 if(pDivInfo
&& pDivInfo
->HasContents())
526 * @descr Get previous division which has contents, copy from lwp source code
528 LwpDocument
* LwpDocument::GetPreviousDivisionWithContents()
530 if(GetPreviousDivision())
532 LwpDocument
* pDoc
= GetPreviousDivision()->GetLastDivisionWithContents();
536 if(GetParentDivision())
537 return GetParentDivision()->GetPreviousDivisionWithContents();
541 * @descr Get last division which has contents, copy from lwp source code
543 LwpDocument
* LwpDocument::GetLastDivisionWithContents()
545 LwpDivInfo
* pDivInfo
= dynamic_cast<LwpDivInfo
*>(GetDivInfoID().obj().get());
546 if(pDivInfo
&& pDivInfo
->HasContents())
551 LwpDocument
* pDivision
= GetLastDivision();
553 while (pDivision
&& pDivision
!= this)
555 LwpDocument
* pContentDivision
= pDivision
->GetLastDivisionWithContents();
558 return pContentDivision
;
560 pDivision
= pDivision
->GetPreviousDivision();
566 * @descr Get last division in group which has contents, copy from lwp source code
568 LwpDocument
* LwpDocument::GetLastInGroupWithContents()
570 LwpDocument
* pLast
= nullptr;
571 LwpDocument
* pNext
= this;
575 LwpDivInfo
* pDivInfo
= dynamic_cast<LwpDivInfo
*>(pNext
->GetDivInfoID().obj().get());
576 if (pDivInfo
&& pDivInfo
->HasContents())
578 pNext
= pNext
->GetNextInGroup();
585 * @descr Get last division
587 LwpDocument
* LwpDocument::GetLastDivision()
589 LwpDocSock
* pDocSock
= dynamic_cast<LwpDocSock
*>(GetSocket().obj().get());
591 return dynamic_cast<LwpDocument
*>(pDocSock
->GetChildTail().obj().get());
596 * @descr Get first division
598 LwpDocument
* LwpDocument::GetFirstDivision()
600 LwpDocSock
* pDocSock
= dynamic_cast<LwpDocSock
*>(GetSocket().obj().get());
602 return dynamic_cast<LwpDocument
*>(pDocSock
->GetChildHead().obj().get());
607 * @descr Get root document
609 LwpDocument
* LwpDocument::GetRootDocument()
611 LwpDocument
* pRoot
= this;
614 if(!pRoot
->IsChildDoc())
616 pRoot
= pRoot
->GetParentDivision();
621 * @descr Get first division with contents that is not ole, copy from lwp-source code
623 LwpDocument
* LwpDocument::ImplGetFirstDivisionWithContentsThatIsNotOLE()
625 LwpDivInfo
* pDivInfo
= dynamic_cast<LwpDivInfo
*>(GetDivInfoID().obj().get());
626 if(pDivInfo
&& pDivInfo
->HasContents()
627 && !pDivInfo
->IsOleDivision())
630 LwpDocument
* pDivision
= GetFirstDivision();
634 LwpDocument
* pContentDivision
= pDivision
->GetFirstDivisionWithContentsThatIsNotOLE();
636 return pContentDivision
;
637 pDivision
= pDivision
->GetNextDivision();
642 * @descr Get last division that has endnote
644 LwpDocument
* LwpDocument::GetLastDivisionThatHasEndnote()
646 LwpDocument
* pRoot
= GetRootDocument();
647 LwpDocument
*pLastDoc
= pRoot
? pRoot
->GetLastDivisionWithContents() : nullptr;
650 if (pLastDoc
->GetEnSuperTableLayout().is())
652 pLastDoc
= pLastDoc
->GetPreviousDivisionWithContents();
658 * @descr Get endnote supertable layout, every division has only one endnote supertable layout.
660 rtl::Reference
<LwpVirtualLayout
> LwpDocument::GetEnSuperTableLayout()
662 LwpHeadLayout
* pHeadLayout
= dynamic_cast<LwpHeadLayout
*>(GetFoundry()->GetLayout().obj().get());
665 return pHeadLayout
->FindEnSuperTableLayout();
667 return rtl::Reference
<LwpVirtualLayout
>();
671 * @descr Get the numbers of page before pEndDivision, copy from lwp source code
673 bool LwpDocument::GetNumberOfPages(LwpDocument
* pEndDivision
, sal_uInt16
& nCount
)
675 if(this == pEndDivision
)
678 LwpDivInfo
* pDivInfo
= dynamic_cast<LwpDivInfo
*>(m_DivInfo
.obj().get());
681 pDivInfo
->GetNumberOfPages(nCount
);
684 LwpDocument
* pDivision
= GetFirstDivision();
687 if(pDivision
->GetNumberOfPages(pEndDivision
,nCount
))
689 pDivision
= pDivision
->GetNextDivision();
695 * @descr Get the numbers of page before current division
697 sal_uInt16
LwpDocument::GetNumberOfPagesBefore()
699 sal_uInt16 nPageNumber
= 0;
700 LwpDocument
* pRoot
= GetRootDocument();
702 pRoot
->GetNumberOfPages(this,nPageNumber
);
707 * @descr Get Max number of pages
709 void LwpDocument::MaxNumberOfPages(sal_uInt16
& nNumPages
)
711 LwpDocument
* pDivision
= GetFirstDivision();
713 LwpDivInfo
* pDivInfo
= dynamic_cast<LwpDivInfo
*>(m_DivInfo
.obj().get());
715 nNumPages
+= pDivInfo
->GetMaxNumberOfPages();
718 pDivision
->MaxNumberOfPages(nNumPages
);
719 pDivision
= pDivision
->GetNextDivision();
723 * @descr Parse the frame which anchor is to page before parse other contents,
724 * This method is called when the document is root document.
726 void LwpDocument::ParseFrameInPage(IXFStream
* pOutputStream
)
731 XFContentContainer
* pXFContainer
= new XFContentContainer
;
733 XFConvertFrameInPage(pXFContainer
);
735 pXFContainer
->ToXml(pOutputStream
);
737 pXFContainer
= nullptr;
740 * @descr Parse the frame which anchor is to page in the entire document
742 void LwpDocument::XFConvertFrameInPage(XFContentContainer
* pCont
)
744 LwpDocument
* pDivision
= GetFirstDivision();
746 LwpDivInfo
* pDivInfo
= dynamic_cast<LwpDivInfo
*> (GetDivInfoID().obj().get());
749 LwpPageLayout
* pPageLayout
= dynamic_cast<LwpPageLayout
*>(pDivInfo
->GetInitialLayoutID().obj().get());
752 LwpStory
* pStory
= dynamic_cast<LwpStory
*>(pPageLayout
->GetContent().obj().get());
754 pStory
->XFConvertFrameInPage(pCont
);
759 pDivision
->XFConvertFrameInPage(pCont
);
760 pDivision
= pDivision
->GetNextDivision();
764 * @descr change click here to placeholder
766 void LwpDocument::ChangeStyleName()
768 XFStyleManager
* pXFStyleManager
= LwpGlobalMgr::GetInstance()->GetXFStyleManager();
769 XFTextStyle
* pStyle
= dynamic_cast<XFTextStyle
*>(pXFStyleManager
->FindStyle("ClickHere"));
772 pStyle
->SetStyleName("Placeholder");
775 LwpDocSock::LwpDocSock(LwpObjectHeader
& objHdr
, LwpSvStream
* pStrm
)
776 :LwpDLNFVList(objHdr
, pStrm
)
780 * @descr read VO_DOCSOCK from file
782 void LwpDocSock::Read()
784 LwpDLNFVList::Read();
785 m_Doc
.ReadIndexed(m_pObjStrm
.get());
786 m_pObjStrm
->SkipExtra();
789 * @descr register styles in documents plugged
791 void LwpDocSock::RegisterStyle()
793 rtl::Reference
<LwpObject
> pDoc
= GetNext().obj();
795 pDoc
->DoRegisterStyle();
797 pDoc
= GetChildHead().obj();
799 pDoc
->DoRegisterStyle();
802 * @descr parse contents of documents plugged
804 void LwpDocSock::Parse(IXFStream
* pOutputStream
)
806 rtl::Reference
<LwpObject
> pDoc
= GetChildHead().obj();
808 pDoc
->DoParse(pOutputStream
);
810 pDoc
= GetNext().obj();
812 pDoc
->DoParse(pOutputStream
);
815 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */