Doxygen
rtfstyle.cpp
浏览该文件的文档.
1 /******************************************************************************
2  *
3  * Copyright (C) 1997-2021 by Dimitri van Heesch.
4  *
5  * Permission to use, copy, modify, and distribute this software and its
6  * documentation under the terms of the GNU General Public License is hereby
7  * granted. No representations are made about the suitability of this software
8  * for any purpose. It is provided "as is" without express or implied warranty.
9  * See the GNU General Public License for more details.
10  *
11  * Documents produced by Doxygen are derivative works derived from the
12  * input used in their production; they are not affected by this license.
13  *
14  */
15 
16 #include <string>
17 #include <fstream>
18 
19 #include "rtfstyle.h"
20 #include "message.h"
21 #include "regex.h"
22 
33 
34 static std::map<std::string,QCString &> g_styleMap =
35 {
36  { "Title", rtf_title },
37  { "Subject", rtf_subject },
38  { "Comments", rtf_comments },
39  { "Company", rtf_company },
40  { "LogoFilename", rtf_logoFilename },
41  { "Author", rtf_author },
42  { "Manager", rtf_manager },
43  { "DocumentType", rtf_documentType },
44  { "DocumentId", rtf_documentId },
45  { "Keywords", rtf_keywords }
46 };
47 
48 
49 char rtf_Style_Reset[] = "\\pard\\plain ";
50 
51 #define RTF_LatexToc(lvl,nest,nxt,pos,twps) \
52  \
53  { "LatexTOC"#lvl, \
54  "\\s"#nest"\\li"#pos"\\sa"#twps"\\sb"#twps"\\widctlpar\\tqr\\tldot\\tx8640\\adjustright \\fs20\\cgrid ",\
55  "\\sbasedon0 \\snext"#nxt" LatexTOC "#lvl \
56  }
57 
58 #define RTF_ListBullet(lvl,nest,nxt,pos,lvl2) \
59  { "ListBullet"#lvl, \
60  "\\s"#nest"\\fi-360\\li"#pos"\\widctlpar\\jclisttab\\tx"#pos"{\\*\\pn \\pnlvlbody\\ilvl0\\ls"#lvl2"\\pnrnot0\\pndec }\\ls1\\adjustright \\fs20\\cgrid ", \
61  "\\sbasedon0 \\snext"#nxt" \\sautoupd List Bullet "#lvl \
62  }
63 
64 #define RTF_ListEnum(lvl,nest,nxt,pos) \
65  { "ListEnum"#lvl, \
66  "\\s"#nest"\\fi-360\\li"#pos"\\widctlpar\\fs20\\cgrid ", \
67  "\\sbasedon0 \\snext"#nxt" \\sautoupd List Enum "#lvl \
68  }
69 
70 #define RTF_CodeExample(lvl,nest,nxt,pos) \
71  { "CodeExample"#lvl, \
72  "\\s"#nest"\\li"#pos"\\widctlpar\\adjustright \\shading1000\\cbpat8 \\f2\\fs16\\cgrid ", \
73  "\\sbasedon0 \\snext"#nxt" Code Example "#lvl \
74  }
75 
76 #define RTF_ListContinue(lvl,nest,nxt,pos) \
77  { "ListContinue"#lvl, \
78  "\\s"#nest"\\li"#pos"\\sa60\\sb30\\qj\\widctlpar\\qj\\adjustright \\fs20\\cgrid ", \
79  "\\sbasedon0 \\snext"#nxt" List Continue "#lvl \
80  }
81 
82 #define RTF_DescContinue(lvl,nest,nxt,pos) \
83  { "DescContinue"#lvl, \
84  "\\s"#nest"\\li"#pos"\\widctlpar\\ql\\adjustright \\fs20\\cgrid ", \
85  "\\sbasedon0 \\snext"#nxt" DescContinue "#lvl \
86  }
87 
89 {
90  { "Heading1",
91  "\\s1\\sb240\\sa60\\keepn\\widctlpar\\adjustright \\b\\f1\\fs36\\kerning36\\cgrid ",
92  "\\sbasedon0 \\snext0 heading 1"
93  },
94  { "Heading2",
95  "\\s2\\sb240\\sa60\\keepn\\widctlpar\\adjustright \\b\\f1\\fs28\\kerning28\\cgrid ",
96  "\\sbasedon0 \\snext0 heading 2"
97  },
98  { "Heading3",
99  "\\s3\\sb240\\sa60\\keepn\\widctlpar\\adjustright \\b\\f1\\cgrid ",
100  "\\sbasedon0 \\snext0 heading 3"
101  },
102  { "Heading4",
103  "\\s4\\sb240\\sa60\\keepn\\widctlpar\\adjustright \\b\\f1\\fs20\\cgrid ",
104  "\\sbasedon0 \\snext0 heading 4;}{\\*\\cs10 \\additive Default Paragraph Font"
105  },
106  { "Heading5",
107  "\\s5\\sb90\\sa30\\keepn\\widctlpar\\adjustright \\b\\f1\\fs20\\cgrid ",
108  "\\sbasedon0 \\snext0 heading 5;}{\\*\\cs10 \\additive Default Paragraph Font"
109  },
110  { "Title",
111  "\\s15\\qc\\sb240\\sa60\\widctlpar\\outlinelevel0\\adjustright \\b\\f1\\fs32\\kerning28\\cgrid ",
112  "\\sbasedon0 \\snext15 Title"
113  },
114  { "SubTitle",
115  "\\s16\\qc\\sa60\\widctlpar\\outlinelevel1\\adjustright \\f1\\cgrid ",
116  "\\sbasedon0 \\snext16 Subtitle"
117  },
118  { "BodyText",
119  "\\s17\\sa60\\sb30\\widctlpar\\qj \\fs22\\cgrid ",
120  "\\sbasedon0 \\snext17 BodyText"
121  },
122  { "DenseText",
123  "\\s18\\widctlpar\\fs22\\cgrid ",
124  "\\sbasedon0 \\snext18 DenseText"
125  },
126  { "Header",
127  "\\s28\\widctlpar\\tqc\\tx4320\\tqr\\tx8640\\adjustright \\fs20\\cgrid ",
128  "\\sbasedon0 \\snext28 header"
129  },
130  { "Footer",
131  "\\s29\\widctlpar\\tqc\\tx4320\\tqr\\tx8640\\qr\\adjustright \\fs20\\cgrid ",
132  "\\sbasedon0 \\snext29 footer"
133  },
134  { "GroupHeader",
135  "\\s30\\li360\\sa60\\sb120\\keepn\\widctlpar\\adjustright \\b\\f1\\fs20\\cgrid ",
136  "\\sbasedon0 \\snext30 GroupHeader"
137  },
138 
139  RTF_CodeExample( 0, 40, 41, 0),
140  RTF_CodeExample( 1, 41, 42, 360),
141  RTF_CodeExample( 2, 42, 43, 720),
142  RTF_CodeExample( 3, 43, 44,1080),
143  RTF_CodeExample( 4, 44, 45,1440),
144  RTF_CodeExample( 5, 45, 46,1800),
145  RTF_CodeExample( 6, 46, 47,2160),
146  RTF_CodeExample( 7, 47, 48,2520),
147  RTF_CodeExample( 8, 48, 49,2880),
148  RTF_CodeExample( 9, 49, 50,3240),
149  RTF_CodeExample(10, 50, 51,3600),
150  RTF_CodeExample(11, 51, 52,3960),
151  RTF_CodeExample(12, 52, 53,4320),
152  RTF_CodeExample(13, 53, 53,4680),
153 
154  RTF_ListContinue( 0, 60, 61, 0),
155  RTF_ListContinue( 1, 61, 62, 360),
156  RTF_ListContinue( 2, 62, 63, 720),
157  RTF_ListContinue( 3, 63, 64,1080),
158  RTF_ListContinue( 4, 64, 65,1440),
159  RTF_ListContinue( 5, 65, 66,1800),
160  RTF_ListContinue( 6, 66, 67,2160),
161  RTF_ListContinue( 7, 67, 68,2520),
162  RTF_ListContinue( 8, 68, 69,2880),
163  RTF_ListContinue( 9, 69, 70,3240),
164  RTF_ListContinue(10, 70, 71,3600),
165  RTF_ListContinue(11, 71, 72,3960),
166  RTF_ListContinue(12, 72, 73,4320),
167  RTF_ListContinue(13, 73, 73,4680),
168 
169  RTF_DescContinue( 0, 80, 81, 0),
170  RTF_DescContinue( 1, 81, 82, 360),
171  RTF_DescContinue( 2, 82, 83, 720),
172  RTF_DescContinue( 3, 83, 84,1080),
173  RTF_DescContinue( 4, 84, 85,1440),
174  RTF_DescContinue( 5, 85, 86,1800),
175  RTF_DescContinue( 6, 86, 87,2160),
176  RTF_DescContinue( 7, 87, 88,2520),
177  RTF_DescContinue( 8, 88, 89,2880),
178  RTF_DescContinue( 9, 89, 90,3240),
179  RTF_DescContinue(10, 90, 91,3600),
180  RTF_DescContinue(11, 91, 92,3960),
181  RTF_DescContinue(12, 92, 93,4320),
182  RTF_DescContinue(13, 93, 93,4680),
183 
184  RTF_LatexToc( 0,100,101, 0,30),
185  RTF_LatexToc( 1,101,102, 360,27),
186  RTF_LatexToc( 2,102,103, 720,24),
187  RTF_LatexToc( 3,103,104,1080,21),
188  RTF_LatexToc( 4,104,105,1440,18),
189  RTF_LatexToc( 5,105,106,1800,15),
190  RTF_LatexToc( 6,106,107,2160,12),
191  RTF_LatexToc( 7,107,108,2520, 9),
192  RTF_LatexToc( 8,108,109,2880, 6),
193  RTF_LatexToc( 9,109,110,3240, 3),
194  RTF_LatexToc(10,110,111,3600, 3),
195  RTF_LatexToc(11,111,112,3960, 3),
196  RTF_LatexToc(12,112,113,4320, 3),
197  RTF_LatexToc(13,113,113,4680, 3),
198 
199  RTF_ListBullet( 0,120,121, 360, 1),
200  RTF_ListBullet( 1,121,122, 720, 2),
201  RTF_ListBullet( 2,122,123,1080, 3),
202  RTF_ListBullet( 3,123,124,1440, 4),
203  RTF_ListBullet( 4,124,125,1800, 5),
204  RTF_ListBullet( 5,125,126,2160, 6),
205  RTF_ListBullet( 6,126,127,2520, 7),
206  RTF_ListBullet( 7,127,128,2880, 8),
207  RTF_ListBullet( 8,128,129,3240, 9),
208  RTF_ListBullet( 9,129,130,3600,10),
209  RTF_ListBullet(10,130,131,3960,11),
210  RTF_ListBullet(11,131,132,4320,12),
211  RTF_ListBullet(12,132,133,4680,13),
212  RTF_ListBullet(13,133,133,5040,14),
213 
214  RTF_ListEnum( 0,140,141, 360),
215  RTF_ListEnum( 1,141,142, 720),
216  RTF_ListEnum( 2,142,143,1080),
217  RTF_ListEnum( 3,143,144,1440),
218  RTF_ListEnum( 4,144,145,1800),
219  RTF_ListEnum( 5,145,146,2160),
220  RTF_ListEnum( 6,146,147,2520),
221  RTF_ListEnum( 7,147,148,2880),
222  RTF_ListEnum( 8,148,149,3240),
223  RTF_ListEnum( 9,149,150,3600),
224  RTF_ListEnum(10,150,151,3960),
225  RTF_ListEnum(11,151,152,4320),
226  RTF_ListEnum(12,152,153,4680),
227  RTF_ListEnum(13,153,153,5040),
228 
229  { 0,
230  0,
231  0
232  }
233 };
234 
235 static const reg::Ex s_clause(R"(\\s(\d+)\s*)"); // match, e.g. '\s30' and capture '30'
236 
237 StyleData::StyleData(const std::string &reference, const std::string &definition)
238 {
241  {
242  m_index = static_cast<int>(std::stoul(match[1].str()));
243  }
244  else // error
245  {
246  m_index = 0;
247  }
250 }
251 
252 bool StyleData::setStyle(const std::string &command, const std::string &styleName)
253 {
255  if (!reg::search(command,match,s_clause))
256  {
257  err("Style sheet '%s' contains no '\\s' clause.\n{%s}", styleName.c_str(), command.c_str());
258  return false;
259  }
260  m_index = static_cast<int>(std::stoul(match[1].str()));
261 
262  size_t index = command.find("\\sbasedon");
263  if (index!=std::string::npos)
264  {
265  m_reference = command.substr(0,index);
266  m_definition = command.substr(index);
267  }
268 
269  return true;
270 }
271 
272 
273 void loadStylesheet(const QCString &name, StyleDataMap& map)
274 {
275  std::ifstream file(name.str());
276  if (!file.is_open())
277  {
278  err("Can't open RTF style sheet file %s. Using defaults.",qPrint(name));
279  return;
280  }
281  msg("Loading RTF style sheet %s...\n",qPrint(name));
282 
283  uint lineNr=1;
284 
285  for (std::string line ; getline(file,line) ; ) // for each line
286  {
287  if (line.empty() || line[0]=='#') continue; // skip blanks & comments
288  static const reg::Ex assignment_splitter(R"(\s*=\s*)");
290  if (reg::search(line,match,assignment_splitter))
291  {
292  std::string key = match.prefix().str();
293  std::string value = match.suffix().str();
294  auto it = map.find(key);
295  if (it!=map.end())
296  {
297  StyleData& styleData = it->second;
298  styleData.setStyle(value,key);
299  }
300  else
301  {
302  warn(name,lineNr,"Unknown style sheet name %s ignored.",key.data());
303  }
304  }
305  else
306  {
307  warn(name,lineNr,"Assignment of style sheet name expected line='%s'!",line.c_str());
308  }
309  lineNr++;
310  }
311 }
312 
314 
315 void loadExtensions(const QCString &name)
316 {
317  std::ifstream file(name.str());
318  if (!file.is_open())
319  {
320  err("Can't open RTF extensions file %s. Using defaults.",qPrint(name));
321  return;
322  }
323  msg("Loading RTF extensions %s...\n",qPrint(name));
324 
325  uint lineNr=1;
326 
327  for (std::string line ; getline(file,line) ; ) // for each line
328  {
329  if (line.empty() || line[0]=='#') continue; // skip blanks & comments
330  static const reg::Ex assignment_splitter(R"(\s*=\s*)");
332  if (reg::search(line,match,assignment_splitter))
333  {
334  std::string key = match.prefix().str();
335  std::string value = match.suffix().str();
336  auto it = g_styleMap.find(key);
337  if (it!=g_styleMap.end())
338  {
339  it->second = value;
340  }
341  else
342  {
343  warn(name,lineNr,"Ignoring unknown extension key '%s'...",key.c_str());
344  }
345  }
346  else
347  {
348  warn(name,lineNr,"Assignment of style sheet name expected!");
349  }
350  lineNr++;
351  }
352 }
353 
rtfstyle.h
RTF_ListEnum
#define RTF_ListEnum(lvl, nest, nxt, pos)
Definition: rtfstyle.cpp:64
RTF_LatexToc
#define RTF_LatexToc(lvl, nest, nxt, pos, twps)
Definition: rtfstyle.cpp:51
reg::match
bool match(const std::string &str, Match &match, const Ex &re)
Matches a given string str for a match against regular expression re.
Definition: regex.cpp:729
RTF_ListContinue
#define RTF_ListContinue(lvl, nest, nxt, pos)
Definition: rtfstyle.cpp:76
rtf_Style_Reset
char rtf_Style_Reset[]
Definition: rtfstyle.cpp:49
QCString::str
std::string str() const
Definition: qcstring.h:442
RTF_DescContinue
#define RTF_DescContinue(lvl, nest, nxt, pos)
Definition: rtfstyle.cpp:82
err
void err(const char *fmt,...)
Definition: message.cpp:203
rtf_company
QCString rtf_company
Definition: rtfstyle.cpp:26
Rtf_Style_Default
Definition: rtfstyle.h:38
warn
void warn(const QCString &file, int line, const char *fmt,...)
Definition: message.cpp:151
StyleData::m_index
uint m_index
Definition: rtfstyle.h:64
StyleData::definition
const char * definition() const
Definition: rtfstyle.h:60
StyleData
Definition: rtfstyle.h:48
rtf_keywords
QCString rtf_keywords
Definition: rtfstyle.cpp:32
uint
unsigned uint
Definition: qcstring.h:40
s_clause
static const reg::Ex s_clause(R"(\\s(\d+)\s*)")
g_styleMap
static std::map< std::string, QCString & > g_styleMap
Definition: rtfstyle.cpp:34
rtf_Style
StyleDataMap rtf_Style
Definition: rtfstyle.cpp:313
message.h
StyleDataMap
std::map< std::string, StyleData > StyleDataMap
Definition: rtfstyle.h:69
loadExtensions
void loadExtensions(const QCString &name)
Definition: rtfstyle.cpp:315
loadStylesheet
void loadStylesheet(const QCString &name, StyleDataMap &map)
Definition: rtfstyle.cpp:273
rtf_documentType
QCString rtf_documentType
Definition: rtfstyle.cpp:30
reg::Match
Object representing the matching results.
Definition: regex.h:163
StyleData::index
uint index() const
Definition: rtfstyle.h:61
rtf_author
QCString rtf_author
Definition: rtfstyle.cpp:28
regex.h
StyleData::setStyle
bool setStyle(const std::string &command, const std::string &styleName)
Definition: rtfstyle.cpp:252
rtf_logoFilename
QCString rtf_logoFilename
Definition: rtfstyle.cpp:27
rtf_documentId
QCString rtf_documentId
Definition: rtfstyle.cpp:31
rtf_title
QCString rtf_title
Definition: rtfstyle.cpp:23
reg::Ex
Class representing a regular expression.
Definition: regex.h:48
msg
void msg(const char *fmt,...)
Definition: message.cpp:53
qPrint
const char * qPrint(const char *s)
Definition: qcstring.h:589
rtf_Style_Default
Rtf_Style_Default rtf_Style_Default[]
Definition: rtfstyle.cpp:88
rtf_manager
QCString rtf_manager
Definition: rtfstyle.cpp:29
QCString::data
const char * data() const
Returns a pointer to the contents of the string in the form of a 0-terminated C string
Definition: qcstring.h:153
RTF_ListBullet
#define RTF_ListBullet(lvl, nest, nxt, pos, lvl2)
Definition: rtfstyle.cpp:58
RTF_CodeExample
#define RTF_CodeExample(lvl, nest, nxt, pos)
Definition: rtfstyle.cpp:70
StyleData::m_reference
std::string m_reference
Definition: rtfstyle.h:65
rtf_subject
QCString rtf_subject
Definition: rtfstyle.cpp:24
StyleData::StyleData
StyleData()=default
rtf_comments
QCString rtf_comments
Definition: rtfstyle.cpp:25
reg::search
bool search(const std::string &str, Match &match, const Ex &re, size_t pos)
Search in a given string str starting at position pos for a match against regular expression re.
Definition: regex.cpp:718
StyleData::reference
const char * reference() const
Definition: rtfstyle.h:59
StyleData::m_definition
std::string m_definition
Definition: rtfstyle.h:66
QCString
This is an alternative implementation of QCString.
Definition: qcstring.h:108