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