@@ -108,107 +108,139 @@ const char *CitationManager::anchorPrefix() const
108
108
return " CITEREF_" ;
109
109
}
110
110
111
- void CitationManager::generatePage ( )
111
+ void CitationManager::insertCrossReferencesForBibFile ( const QCString &bibFile )
112
112
{
113
- // printf("** CitationManager::generatePage() count=%d\n",m_ordering.count());
113
+ // sanity checks
114
+ if (bibFile.isEmpty ())
115
+ {
116
+ return ;
117
+ }
118
+ QFileInfo fi (bibFile);
119
+ if (!fi.exists ())
120
+ {
121
+ err (" bib file %s not found!\n " ,bibFile.data ());
122
+ return ;
123
+ }
124
+ QFile f (bibFile);
125
+ if (!f.open (IO_ReadOnly))
126
+ {
127
+ err (" could not open file %s for reading\n " ,bibFile.data ());
128
+ return ;
129
+ }
114
130
115
- // do not generate an empty citations page
116
- if (isEmpty ()) return ; // nothing to cite
131
+ // convert file to string
132
+ QCString doc;
133
+ QCString input (fi.size ()+1 );
134
+ f.readBlock (input.rawData (),fi.size ());
135
+ f.close ();
136
+ input.at (fi.size ())=' \0 ' ;
117
137
118
- // 0. add cross references from the bib files to the cite dictionary
119
- QFile f;
120
- const StringVector &citeDataList = Config_getList (CITE_BIB_FILES);
121
- for (const auto &bibdata : citeDataList)
138
+ int pos=0 ;
139
+ int s;
140
+
141
+ // helper lambda function to get the next line of input and update pos accordingly
142
+ auto get_next_line = [&input,&pos,&s]()
122
143
{
123
- QCString bibFile = bibdata.c_str ();
124
- if (!bibFile.isEmpty () && bibFile.right (4 )!=" .bib" ) bibFile+=" .bib" ;
125
- QFileInfo fi (bibFile);
126
- if (fi.exists ())
144
+ uint prevPos = (uint)pos;
145
+ pos=s+1 ;
146
+ return input.mid (prevPos,(uint)(s-prevPos));
147
+ };
148
+
149
+ // helper lambda function to return if the end of the input has reached
150
+ auto end_of_input = [&s]()
151
+ {
152
+ return s==-1 ;
153
+ };
154
+
155
+ // helper lambda function to proceed to the next line in the input, and update s
156
+ // to point to the start of the line. Return true as long as there is a new line.
157
+ auto has_next_line = [&input,&pos,&s]()
158
+ {
159
+ s=input.find (' \n ' ,pos);
160
+ return s!=-1 ;
161
+ };
162
+
163
+ // search for citation cross references
164
+ QCString citeName;
165
+ while (has_next_line ())
166
+ {
167
+ QCString line = get_next_line ();
168
+
169
+ int i;
170
+ if (line.stripWhiteSpace ().startsWith (" @" ))
127
171
{
128
- if (!bibFile.isEmpty ())
172
+ // assumption entry like: "@book { name," or "@book { name" (spaces optional)
173
+ int j = line.find (' {' );
174
+ // when no {, go hunting for it
175
+ while (j==-1 && has_next_line ())
129
176
{
130
- f.setName (bibFile);
131
- if (!f.open (IO_ReadOnly))
132
- {
133
- err (" could not open file %s for reading\n " ,bibFile.data ());
134
- }
135
- QCString doc;
136
- QCString input (fi.size ()+1 );
137
- f.readBlock (input.rawData (),fi.size ());
138
- f.close ();
139
- input.at (fi.size ())=' \0 ' ;
140
- int pos=0 ;
141
- int s;
142
- QCString citeName;
143
- while ((s=input.find (' \n ' ,pos))!=-1 )
177
+ line = get_next_line ();
178
+ j = line.find (' {' );
179
+ }
180
+ // search for the name
181
+ citeName = " " ;
182
+ if (!end_of_input () && j!=-1 ) // to prevent something like "@manual ," and no { found
183
+ {
184
+ int k = line.find (' ,' ,j);
185
+ j++;
186
+ // found a line "@....{.....,...." or "@.....{....."
187
+ // ^=j ^=k ^=j k=-1
188
+ while (!end_of_input () && citeName.isEmpty ())
144
189
{
145
- QCString line = input. mid ((uint)pos,(uint)(s-pos));
146
- pos=s+ 1 ;
147
-
148
- int i;
149
- if ((i = line. find ( " crossref " )) != - 1 ) /* assumption cross reference is on one line and the only item */
190
+ if (k!=- 1 )
191
+ {
192
+ citeName = line. mid ((uint)(j),(uint)(k-j));
193
+ }
194
+ else
150
195
{
151
- int j=line.find (" {" ,i);
152
- int k=line.find (" }" ,i);
153
- if (j!=-1 && k!=-1 )
154
- {
155
- QCString crossrefName = line.mid ((uint)(j+1 ),(uint)(k-j-1 ));
156
- // check if the reference with the cross reference is used
157
- // insert cross refererence when cross reference has not yet been added.
158
- if ((p->entries .find (citeName.data ())!=p->entries .end ()) &&
159
- (p->entries .find (crossrefName.data ())==p->entries .end ())) // not found yet
160
- {
161
- insert (crossrefName);
162
- }
163
- }
196
+ citeName = line.mid ((uint)(j));
164
197
}
165
- else if (line.stripWhiteSpace ().startsWith (" @" ))
198
+ citeName = citeName.stripWhiteSpace ();
199
+ j = 0 ;
200
+ if (citeName.isEmpty () && has_next_line ())
166
201
{
167
- // assumption entry like: "@book { name," or "@book { name" (spaces optional)
168
- int j=line.find (" {" );
169
- // when no {, go hunting for it
170
- while (j==-1 && (s=input.find (' \n ' ,pos))!=-1 )
171
- {
172
- line = input.mid ((uint)pos,(uint)(s-pos));
173
- j=line.find (" {" );
174
- pos=s+1 ;
175
- }
176
- // search for the name
177
- citeName = " " ;
178
- if (s != -1 && j!= -1 ) // to prevent something like "@manual ," and no { found
179
- {
180
- int k=line.find (" ," ,j);
181
- j++;
182
- while (s != -1 && citeName.isEmpty ())
183
- {
184
- if (k != -1 )
185
- {
186
- citeName = line.mid ((uint)(j),(uint)(k-j));
187
- }
188
- else
189
- {
190
- citeName = line.mid ((uint)(j));
191
- }
192
- citeName = citeName.stripWhiteSpace ();
193
- j = 0 ;
194
- if (citeName.isEmpty () && (s=input.find (' \n ' ,pos))!=-1 )
195
- {
196
- line = input.mid ((uint)pos,(uint)(s-pos));
197
- pos=s+1 ;
198
- k=line.find (" ," );
199
- }
200
- }
201
- }
202
- // printf("citeName = #%s#\n",citeName.data());
202
+ line = get_next_line ();
203
+ k = line.find (' ,' );
203
204
}
204
205
}
205
206
}
207
+ // printf("citeName = #%s#\n",citeName.data());
206
208
}
207
- else if (!fi. exists ())
209
+ else if ((i=line. find ( " crossref " ))!=- 1 && !citeName. isEmpty ()) /* assumption cross reference is on one line and the only item */
208
210
{
209
- err (" bib file %s not found!\n " ,bibFile.data ());
211
+ int j = line.find (' {' ,i);
212
+ int k = line.find (' }' ,i);
213
+ if (j>i && k>j)
214
+ {
215
+ QCString crossrefName = line.mid ((uint)(j+1 ),(uint)(k-j-1 ));
216
+ // check if the reference with the cross reference is used
217
+ // insert cross refererence when cross reference has not yet been added.
218
+ if ((p->entries .find (citeName.data ())!=p->entries .end ()) &&
219
+ (p->entries .find (crossrefName.data ())==p->entries .end ())) // not found yet
220
+ {
221
+ insert (crossrefName);
222
+ }
223
+ }
210
224
}
211
225
}
226
+ }
227
+
228
+ void CitationManager::generatePage ()
229
+ {
230
+ // printf("** CitationManager::generatePage() count=%d\n",m_ordering.count());
231
+
232
+ // do not generate an empty citations page
233
+ if (isEmpty ()) return ; // nothing to cite
234
+
235
+ // 0. add cross references from the bib files to the cite dictionary
236
+ QFile f;
237
+ const StringVector &citeDataList = Config_getList (CITE_BIB_FILES);
238
+ for (const auto &bibdata : citeDataList)
239
+ {
240
+ QCString bibFile = bibdata.c_str ();
241
+ if (!bibFile.isEmpty () && bibFile.right (4 )!=" .bib" ) bibFile+=" .bib" ;
242
+ insertCrossReferencesForBibFile (bibFile);
243
+ }
212
244
213
245
// 1. generate file with markers and citations to OUTPUT_DIRECTORY
214
246
QCString outputDir = Config_getString (OUTPUT_DIRECTORY);
0 commit comments