update credits
[LibreOffice.git] / helpcompiler / source / BasCodeTagger.cxx
blobd394e1aad5319e16d5ba86e9243360be66df10b3
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <BasCodeTagger.hxx>
12 LibXmlTreeWalker::LibXmlTreeWalker( xmlDocPtr doc )
14 if ( doc == NULL )
15 throw BasicCodeTagger::NULL_DOCUMENT;
16 m_pCurrentNode = xmlDocGetRootElement( doc );
17 if ( m_pCurrentNode == NULL )
18 throw BasicCodeTagger::EMPTY_DOCUMENT;
19 else if ( m_pCurrentNode->xmlChildrenNode != NULL )
20 m_Queue.push_back( m_pCurrentNode->xmlChildrenNode );
21 nextNode();
24 void LibXmlTreeWalker::nextNode()
27 //next node
28 if ( m_pCurrentNode->next == NULL )
30 m_pCurrentNode = m_Queue.front();
31 m_Queue.pop_front();
33 else
34 m_pCurrentNode = m_pCurrentNode->next;
35 //queue chiledren if they exist
36 if ( m_pCurrentNode->xmlChildrenNode != NULL )
37 m_Queue.push_back( m_pCurrentNode->xmlChildrenNode );
40 void LibXmlTreeWalker::ignoreCurrNodesChildren()
42 if ( m_pCurrentNode->xmlChildrenNode != NULL )
43 m_Queue.pop_back();
46 bool LibXmlTreeWalker::end()
48 return m_pCurrentNode->next == NULL && m_Queue.empty();
51 xmlNodePtr LibXmlTreeWalker::currentNode()
53 return m_pCurrentNode;
56 //======================================================
58 BasicCodeTagger::BasicCodeTagger( xmlDocPtr rootDoc )
60 if ( rootDoc == NULL )
61 throw NULL_DOCUMENT;
62 m_pDocument = rootDoc;
63 m_pXmlTreeWalker = NULL;
64 m_Highlighter.initialize( HIGHLIGHT_BASIC );
65 m_bTaggingCompleted = false;
69 BasicCodeTagger::~BasicCodeTagger()
71 if ( m_pXmlTreeWalker != NULL )
72 delete m_pXmlTreeWalker;
74 //!Gathers all the <bascode> tag nodes from xml tree.
75 /*!
76 * Assumes m_pDocument is valid. Handles m_pXmlTreeWalker and m_BasicCodeContainerTags members.
78 void BasicCodeTagger::getBasicCodeContainerNodes()
80 xmlNodePtr currentNode;
82 m_BasicCodeContainerTags.clear();
84 if ( m_pXmlTreeWalker != NULL )
85 delete m_pXmlTreeWalker;
86 m_pXmlTreeWalker = new LibXmlTreeWalker( m_pDocument );
88 currentNode = m_pXmlTreeWalker->currentNode();
89 if ( !( xmlStrcmp( currentNode->name, (const xmlChar*) "bascode" ) ) )
90 { //Found <bascode>
91 m_BasicCodeContainerTags.push_back( currentNode ); //it goes to the end of the list
93 while ( !m_pXmlTreeWalker->end() )
95 m_pXmlTreeWalker->nextNode();
96 if ( !( xmlStrcmp( m_pXmlTreeWalker->currentNode()->name, (const xmlChar*) "bascode" ) ) )
97 { //Found <bascode>
98 m_BasicCodeContainerTags.push_back( m_pXmlTreeWalker->currentNode() ); //it goes to the end of the list
99 m_pXmlTreeWalker->ignoreCurrNodesChildren();
104 //! Extracts Basic Codes containted in <bascode> tags.
106 * For each <bascode> this method iterates trough it's <paragraph> tags and "inserts" <item> tags according
107 * to the Basic code syntax found in that paragraph.
109 void BasicCodeTagger::tagBasCodeParagraphs()
111 //helper variables
112 xmlNodePtr currBascodeNode;
113 xmlNodePtr currParagraph;
114 while ( !m_BasicCodeContainerTags.empty() )
116 currBascodeNode = m_BasicCodeContainerTags.front();
117 currParagraph = currBascodeNode->xmlChildrenNode; //first <paragraph>
118 while ( currParagraph != NULL )
120 tagParagraph( currParagraph );
121 currParagraph=currParagraph->next;
123 m_BasicCodeContainerTags.pop_front(); //next element
127 //! Used by tagBasCodeParagraphs(). It does the work on the current paragraph containing Basic code.
128 void BasicCodeTagger::tagParagraph( xmlNodePtr paragraph )
130 //1. get paragraph text
131 xmlChar* codeSnippet;
132 codeSnippet = xmlNodeListGetString( m_pDocument, paragraph->xmlChildrenNode, 1 );
133 if ( codeSnippet == NULL )
135 return; //no text, nothing more to do here
137 //2. delete every child from paragraph (except attributes)
138 xmlNodePtr curNode = paragraph->xmlChildrenNode;
139 xmlNodePtr sibling;
140 while ( curNode != NULL )
142 sibling = curNode->next;
143 xmlUnlinkNode( curNode );
144 xmlFreeNode( curNode );
145 curNode = sibling;
148 //3. create new paragraph content
149 OUString strLine( reinterpret_cast<const sal_Char*>(codeSnippet),
150 strlen(reinterpret_cast<const char*>(codeSnippet)),
151 RTL_TEXTENCODING_UTF8 );
152 m_Highlighter.notifyChange ( 0, 0, &strLine, 1 );
153 HighlightPortions portions;
154 m_Highlighter.getHighlightPortions( 0, strLine, portions );
155 for ( size_t i=0; i<portions.size(); i++ )
157 HighlightPortion& r = portions[i];
158 OString sToken(OUStringToOString(strLine.copy(r.nBegin, r.nEnd-r.nBegin), RTL_TEXTENCODING_UTF8));
159 xmlNodePtr text = xmlNewText((const xmlChar*)sToken.getStr());
160 if ( r.tokenType != TT_WHITESPACE )
162 xmlChar* typeStr = getTypeString( r.tokenType );
163 curNode = xmlNewTextChild( paragraph, 0, (xmlChar*)"item", 0 );
164 xmlNewProp( curNode, (xmlChar*)"type", typeStr );
165 xmlAddChild( curNode, text );
166 xmlFree( typeStr );
168 else
169 xmlAddChild( paragraph, text );
171 xmlFree( codeSnippet );
174 //! Manages tagging process.
176 * This is the "main" function of BasicCodeTagger.
178 void BasicCodeTagger::tagBasicCodes()
180 if ( m_bTaggingCompleted )
181 return;
182 //gather <bascode> nodes
185 getBasicCodeContainerNodes();
187 catch (TaggerException &ex)
189 std::cout << "BasCodeTagger error occured. Error code:" << ex << std::endl;
192 //tag basic code paragraphs in <bascode> tag
193 tagBasCodeParagraphs();
194 m_bTaggingCompleted = true;
197 //! Converts SyntaxHighlighter's TokenTypes enum to a type string for <item type=... >
198 xmlChar* BasicCodeTagger::getTypeString( TokenTypes tokenType )
200 const char* str;
201 switch ( tokenType )
203 case TT_UNKNOWN :
204 str = "unknown";
205 break;
206 case TT_IDENTIFIER :
207 str = "identifier";
208 break;
209 case TT_WHITESPACE :
210 str = "whitespace";
211 break;
212 case TT_NUMBER :
213 str = "number";
214 break;
215 case TT_STRING :
216 str = "string";
217 break;
218 case TT_EOL :
219 str = "eol";
220 break;
221 case TT_COMMENT :
222 str = "comment";
223 break;
224 case TT_ERROR :
225 str = "error";
226 break;
227 case TT_OPERATOR :
228 str = "operator";
229 break;
230 case TT_KEYWORDS :
231 str = "keyword";
232 break;
233 case TT_PARAMETER :
234 str = "parameter";
235 break;
236 default :
237 str = "unknown";
238 break;
240 return xmlCharStrdup( str );
243 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */