|
1 /****************************************************************************** |
|
2 * |
|
3 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
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 */ |
|
12 #include "xmlditaelementprefix.h" |
|
13 |
|
14 // Version to use in the DOCTYPE declaration |
|
15 // Should match regex: v(\d+)\.(\d+)\.(\d+)(\S*) |
|
16 const char *DOCTYPE_VERSION = "v0.1.0"; |
|
17 |
|
18 DITAElementPrefix::DITAElementPrefix() |
|
19 { |
|
20 //QDict<char> m_extToLang; |
|
21 //QDict<char> m_langToPrefix; |
|
22 // NOTE: Keys must be in lowercase as the extension will be |
|
23 // coerced to lowercase before matching |
|
24 // NOTE: Value is case sensitive and must match the key of m_langToPrefix |
|
25 // C/C++ languages - our primary concern - we treat C as C++ for the moment |
|
26 // NOTE: This is very similar to initDefaultExtensionMapping() in util.h/util.cpp |
|
27 // TODO: Respect extension/language mapping in config file |
|
28 // TODO: Have list of supported languages in DITA e.g. isSupported(Definition*); |
|
29 // so that callers can decide to supress output for unsupported languages |
|
30 m_extToLang.insert(".h", "C++"); |
|
31 m_extToLang.insert(".c", "C++"); |
|
32 m_extToLang.insert(".cpp", "C++"); |
|
33 m_extToLang.insert(".cp", "C++"); |
|
34 m_extToLang.insert(".cxx", "C++"); |
|
35 m_extToLang.insert(".inl", "C++"); |
|
36 // Other languages |
|
37 m_extToLang.insert(".idl", "IDL"); |
|
38 m_extToLang.insert(".ddl", "IDL"); |
|
39 m_extToLang.insert(".odl", "IDL"); |
|
40 m_extToLang.insert(".java", "Java"); |
|
41 m_extToLang.insert(".as", "JavaScript"); |
|
42 m_extToLang.insert(".js", "JavaScript"); |
|
43 m_extToLang.insert(".cs", "C Sharp"); |
|
44 m_extToLang.insert(".d", "D"); |
|
45 m_extToLang.insert(".php", "PHP"); |
|
46 m_extToLang.insert(".php4", "PHP"); |
|
47 m_extToLang.insert(".php5", "PHP"); |
|
48 m_extToLang.insert(".inc", "PHP"); |
|
49 m_extToLang.insert(".phtml", "PHP"); |
|
50 m_extToLang.insert(".m", "Objective C"); |
|
51 m_extToLang.insert(".M", "Objective C"); |
|
52 m_extToLang.insert(".mm", "Objective C"); |
|
53 m_extToLang.insert(".py", "Python"); |
|
54 m_extToLang.insert(".f", "Fortran"); |
|
55 m_extToLang.insert(".f90", "Fortran"); |
|
56 m_extToLang.insert(".vhd", "VHDL"); |
|
57 m_extToLang.insert(".vhdl", "VHDL"); |
|
58 // |
|
59 // Now load the language to element prefix, case sensitve all round. |
|
60 // However the class behavior is that if there is no entry then the prefix is the |
|
61 // language in lower case with spaces removed i.e. implicitly "C Sharp" -> "csharp" |
|
62 // |
|
63 m_langToPrefix.insert("C++", "cxx"); |
|
64 // Map of language to the owner of the DOCTYPE |
|
65 m_langToDoctypeOwner.insert("C++", "NOKIA"); |
|
66 m_langToDoctypeOwner.insert("Java", "IBM"); |
|
67 } |
|
68 |
|
69 QString DITAElementPrefix::srcLang(const QString &fileName) |
|
70 { |
|
71 QString retStr; |
|
72 int i = fileName.findRev('.'); |
|
73 QString ext = fileName.right(fileName.length() - i).lower(); |
|
74 if (i != -1 && (fileName.length() - i)) { |
|
75 char *p = m_extToLang[ext]; |
|
76 if (p) { |
|
77 retStr = QString(p); |
|
78 } else { |
|
79 // WTF? |
|
80 retStr = "_" + ext + "_"; |
|
81 } |
|
82 } |
|
83 return retStr; |
|
84 } |
|
85 |
|
86 QString DITAElementPrefix::elemPrefix(const QString &srcLang) |
|
87 { |
|
88 char *p = m_langToPrefix[srcLang]; |
|
89 if (p) { |
|
90 return QString(p); |
|
91 } |
|
92 // Fall back to returning the suppied argument but in lower case and |
|
93 // with spaces removed |
|
94 QString retStr; |
|
95 for (uint i = 0; i < srcLang.length(); ++i) { |
|
96 if (srcLang[i] != " ") { |
|
97 retStr.append(srcLang[i]); |
|
98 } |
|
99 } |
|
100 return retStr.lower(); |
|
101 } |
|
102 |
|
103 QString DITAElementPrefix::srcLang(const Definition *d) |
|
104 { |
|
105 QCString myFileName = d->getDefFileName(); |
|
106 return srcLang(myFileName); |
|
107 } |
|
108 |
|
109 QString DITAElementPrefix::memberKind(const MemberDef *md) |
|
110 { |
|
111 // Get the kind, make lower case and capitalise the first letter |
|
112 // Special case turn "enumvalue" to "Enumerator" |
|
113 // [ISO/IEC 9899:1999 (E) 6.7.2.2 Enumeration specifiers] |
|
114 if (md->memberTypeName() == "enumvalue") { |
|
115 return QString("Enumerator"); |
|
116 } |
|
117 return capFirstLetter(md->memberTypeName()); |
|
118 } |
|
119 |
|
120 QString DITAElementPrefix::memberKind(const ClassDef *cd) |
|
121 { |
|
122 return capFirstLetter(cd->compoundTypeString()); |
|
123 } |
|
124 |
|
125 /** Return a string that is the input lowercased then first letter capitalised */ |
|
126 QString DITAElementPrefix::capFirstLetter(const QString& in) const |
|
127 { |
|
128 if (in.length() == 0) { |
|
129 return in.upper(); |
|
130 } |
|
131 QString myStr(in.lower()); |
|
132 QString myPref(myStr.left(1).upper()); |
|
133 QString mySuff(myStr.remove(0, 1)); |
|
134 return myPref + mySuff; |
|
135 } |
|
136 |
|
137 QString DITAElementPrefix::elemPrefix(const Definition *d) |
|
138 { |
|
139 QCString myFileName = d->getDefFileName(); |
|
140 return elemPrefix(srcLang(myFileName)); |
|
141 } |
|
142 |
|
143 QString DITAElementPrefix::elemPrefix(const MemberDef *md, bool includeKind) |
|
144 { |
|
145 QCString myFileName = md->getDefFileName(); |
|
146 if (includeKind) { |
|
147 return elemPrefix(srcLang(myFileName)) + memberKind(md); |
|
148 } |
|
149 return elemPrefix(srcLang(myFileName)); |
|
150 } |
|
151 |
|
152 QString DITAElementPrefix::elemPrefix(const ClassDef *cd, bool includeKind) |
|
153 { |
|
154 QCString myFileName = cd->getDefFileName(); |
|
155 if (includeKind) { |
|
156 // Get the kind and capitalise the first letter |
|
157 return elemPrefix(srcLang(myFileName)) + capFirstLetter(cd->compoundTypeString()); |
|
158 } |
|
159 return elemPrefix(srcLang(myFileName)); |
|
160 } |
|
161 |
|
162 QString DITAElementPrefix::elemPrefix(const NamespaceDef *nd, bool includeKind) |
|
163 { |
|
164 QCString myFileName = nd->getDefFileName(); |
|
165 if (includeKind) { |
|
166 return elemPrefix(srcLang(myFileName)) + "Namespace"; |
|
167 } |
|
168 return elemPrefix(srcLang(myFileName)); |
|
169 } |
|
170 |
|
171 QString DITAElementPrefix::elemPrefix(const FileDef *fd, bool includeKind) |
|
172 { |
|
173 QCString myFileName = fd->getDefFileName(); |
|
174 if (includeKind) { |
|
175 return elemPrefix(srcLang(myFileName)) + "File"; |
|
176 } |
|
177 return elemPrefix(srcLang(myFileName)); |
|
178 } |
|
179 |
|
180 /** Return a string that can be use as a element name that refers to the MemberDef */ |
|
181 QString DITAElementPrefix::elemReference(const MemberDef *md) |
|
182 { |
|
183 return elemPrefix(md, true); |
|
184 } |
|
185 |
|
186 /** Return a string that can be use as a element name that refers to the ClassDef */ |
|
187 QString DITAElementPrefix::elemReference(const ClassDef *cd) |
|
188 { |
|
189 return elemPrefix(cd, true); |
|
190 } |
|
191 |
|
192 // DITA Map references to the 'big four' |
|
193 QString DITAElementPrefix::ditaMapRef(const MemberDef *md) |
|
194 { |
|
195 return elemPrefix(md, true)+"Ref"; |
|
196 } |
|
197 |
|
198 QString DITAElementPrefix::ditaMapRef(const ClassDef *cd) |
|
199 { |
|
200 return elemPrefix(cd, true)+"Ref"; |
|
201 } |
|
202 |
|
203 QString DITAElementPrefix::ditaMapRef(const NamespaceDef *nd) |
|
204 { |
|
205 return elemPrefix(nd, true)+"Ref"; |
|
206 } |
|
207 |
|
208 QString DITAElementPrefix::ditaMapRef(const FileDef *fd) |
|
209 { |
|
210 return elemPrefix(fd, true)+"Ref"; |
|
211 } |
|
212 |
|
213 |
|
214 /* Returns the DOCTYPE owner from the source code language or "???" */ |
|
215 QString DITAElementPrefix::doctypeOwner(const QString &srcLang) |
|
216 { |
|
217 char *p = m_langToDoctypeOwner[srcLang]; |
|
218 if (p) { |
|
219 return QString(p); |
|
220 } |
|
221 return QString("???"); |
|
222 } |
|
223 |
|
224 QString DITAElementPrefix::doctypeStr(const QString &srcLang, const QString &ePref, const QString &sInsert) |
|
225 { |
|
226 QString retVal = ePref; |
|
227 retVal += " PUBLIC \"-//"; |
|
228 retVal += doctypeOwner(srcLang); |
|
229 retVal += "//DTD DITA "; |
|
230 retVal += srcLang; |
|
231 retVal += " API "; |
|
232 retVal += sInsert; |
|
233 retVal += " Reference Type "; |
|
234 retVal += DOCTYPE_VERSION; |
|
235 retVal += "//EN\" \"dtd/"; |
|
236 retVal += ePref; |
|
237 retVal += ".dtd\" "; |
|
238 return retVal; |
|
239 } |
|
240 |
|
241 QString DITAElementPrefix::doctypeStr(const Definition *d, const QString &ePref, const QString &sInsert) |
|
242 { |
|
243 return doctypeStr(srcLang(d), ePref, sInsert); |
|
244 } |
|
245 /** Return a string that can be use as a DOCTYPE for the XML for the ClassDef */ |
|
246 QString DITAElementPrefix::doctypeStr(const MemberDef *md) |
|
247 { |
|
248 return doctypeStr(md, elemPrefix(md, true), capFirstLetter(md->memberTypeName())); |
|
249 } |
|
250 |
|
251 /** Return a string that can be use as a DOCTYPE for the XML for the MemberDef */ |
|
252 QString DITAElementPrefix::doctypeStr(const ClassDef *cd) |
|
253 { |
|
254 return doctypeStr(cd, elemPrefix(cd, true), capFirstLetter(cd->compoundTypeString())); |
|
255 } |
|
256 |
|
257 /** Return a string that can be use as a DOCTYPE for the XML for the Namespace */ |
|
258 QString DITAElementPrefix::doctypeStr(const NamespaceDef *nd) |
|
259 { |
|
260 return doctypeStr(nd, elemPrefix(nd, true), "Namespace"); |
|
261 } |
|
262 |
|
263 /** Return a string that can be use as a DOCTYPE for the XML for the File */ |
|
264 QString DITAElementPrefix::doctypeStr(const FileDef *fd) |
|
265 { |
|
266 return doctypeStr(fd, elemPrefix(fd, true), "File"); |
|
267 } |
|
268 |