You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

html.cc 9.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. /*
  2. Output only format for Human Readable formats.
  3. Copyright (C) 2004 Scott Brynen, scott (at) brynen.com
  4. Copyright (C) 2002 Robert Lipe, robertlipe+source@gpsbabel.org
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
  16. */
  17. #include "defs.h"
  18. #include "jeeps/gpsmath.h"
  19. #include "src/core/xmltag.h"
  20. #include <stdlib.h>
  21. #include <stdio.h>
  22. static gbfile* file_out;
  23. static short_handle mkshort_handle;
  24. static char* stylesheet = NULL;
  25. static char* html_encrypt = NULL;
  26. static char* includelogs = NULL;
  27. static char* degformat = NULL;
  28. static char* altunits = NULL;
  29. #define MYNAME "HTML"
  30. static
  31. arglist_t html_args[] = {
  32. {
  33. "stylesheet", &stylesheet,
  34. "Path to HTML style sheet", NULL, ARGTYPE_STRING, ARG_NOMINMAX
  35. },
  36. {
  37. "encrypt", &html_encrypt,
  38. "Encrypt hints using ROT13", NULL, ARGTYPE_BOOL, ARG_NOMINMAX
  39. },
  40. {
  41. "logs", &includelogs,
  42. "Include groundspeak logs if present", NULL, ARGTYPE_BOOL, ARG_NOMINMAX
  43. },
  44. {
  45. "degformat", &degformat,
  46. "Degrees output as 'ddd', 'dmm'(default) or 'dms'", "dmm", ARGTYPE_STRING, ARG_NOMINMAX
  47. },
  48. {
  49. "altunits", &altunits,
  50. "Units for altitude (f)eet or (m)etres", "m", ARGTYPE_STRING, ARG_NOMINMAX
  51. },
  52. ARG_TERMINATOR
  53. };
  54. static void
  55. wr_init(const QString& fname)
  56. {
  57. file_out = gbfopen(fname, "w", MYNAME);
  58. mkshort_handle = mkshort_new_handle();
  59. }
  60. static void
  61. wr_deinit(void)
  62. {
  63. gbfclose(file_out);
  64. mkshort_del_handle(&mkshort_handle);
  65. }
  66. static void
  67. html_disp(const Waypoint* wpt)
  68. {
  69. char* cout;
  70. int32_t utmz;
  71. double utme, utmn;
  72. char utmzc;
  73. fs_xml* fs_gpx = NULL;
  74. GPS_Math_WGS84_To_UTM_EN(wpt->latitude, wpt->longitude,
  75. &utme, &utmn, &utmz, &utmzc);
  76. gbfprintf(file_out, "\n<a name=\"%s\"><hr></a>\n", CSTRc(wpt->shortname));
  77. gbfprintf(file_out, "<table width=\"100%%\">\n");
  78. gbfprintf(file_out, "<tr><td><p class=\"gpsbabelwaypoint\">%s - ",(global_opts.synthesize_shortnames) ? CSTRc(mkshort_from_wpt(mkshort_handle, wpt)) : CSTRc(wpt->shortname));
  79. cout = pretty_deg_format(wpt->latitude, wpt->longitude, degformat[2], " ", 1);
  80. gbfprintf(file_out, "%s (%d%c %6.0f %7.0f)", cout, utmz, utmzc, utme, utmn);
  81. xfree(cout);
  82. if (wpt->altitude != unknown_alt) {
  83. gbfprintf(file_out, " alt:%d", (int)((altunits[0]=='f')?METERS_TO_FEET(wpt->altitude):wpt->altitude));
  84. }
  85. gbfprintf(file_out, "<br>\n");
  86. if (wpt->description != wpt->shortname) {
  87. if (wpt->HasUrlLink()) {
  88. char* d = html_entitize(CSTRc(wpt->description));
  89. UrlLink link = wpt->GetUrlLink();
  90. gbfprintf(file_out, "<a href=\"%s\">%s</a>", CSTR(link.url_), d);
  91. xfree(d);
  92. } else {
  93. gbfprintf(file_out, "%s", CSTRc(wpt->description));
  94. }
  95. if (!wpt->gc_data->placer.isEmpty()) {
  96. gbfprintf(file_out, " by %s", CSTR(wpt->gc_data->placer));
  97. }
  98. }
  99. gbfprintf(file_out, "</p></td>\n");
  100. gbfprintf(file_out, "<td align=\"right\">");
  101. if (wpt->gc_data->terr) {
  102. gbfprintf(file_out, "<p class=\"gpsbabelcacheinfo\">%d%s / %d%s<br>\n",
  103. (int)(wpt->gc_data->diff / 10), (wpt->gc_data->diff%10)?"&frac12;":"",
  104. (int)(wpt->gc_data->terr / 10), (wpt->gc_data->terr%10)?"&frac12;":"");
  105. gbfprintf(file_out, "%s / %s</p>",
  106. gs_get_cachetype(wpt->gc_data->type),
  107. gs_get_container(wpt->gc_data->container));
  108. }
  109. gbfprintf(file_out, "</td></tr>\n");
  110. gbfprintf(file_out, "<tr><td colspan=\"2\">");
  111. if (!wpt->gc_data->desc_short.utfstring.isEmpty()) {
  112. char* tmpstr = strip_nastyhtml(wpt->gc_data->desc_short.utfstring);
  113. gbfprintf(file_out, "<p class=\"gpsbabeldescshort\">%s</p>\n", tmpstr);
  114. xfree(tmpstr);
  115. }
  116. if (!wpt->gc_data->desc_long.utfstring.isEmpty()) {
  117. char* tmpstr = strip_nastyhtml(wpt->gc_data->desc_long.utfstring);
  118. gbfprintf(file_out, "<p class=\"gpsbabeldesclong\">%s</p>\n", tmpstr);
  119. xfree(tmpstr);
  120. }
  121. if (!wpt->gc_data->hint.isEmpty()) {
  122. QString hint;
  123. if (html_encrypt) {
  124. hint = rot13(wpt->gc_data->hint);
  125. } else {
  126. hint = wpt->gc_data->hint;
  127. }
  128. gbfprintf(file_out, "<p class=\"gpsbabelhint\"><strong>Hint:</strong> %s</p>\n", CSTR(hint));
  129. } else if (!wpt->notes.isEmpty() && (wpt->description.isEmpty() || wpt->notes != wpt->description)) {
  130. gbfprintf(file_out, "<p class=\"gpsbabelnotes\">%s</p>\n", CSTRc(wpt->notes));
  131. }
  132. fs_gpx = NULL;
  133. if (includelogs) {
  134. fs_gpx = (fs_xml*)fs_chain_find(wpt->fs, FS_GPX);
  135. }
  136. if (fs_gpx && fs_gpx->tag) {
  137. xml_tag* root = fs_gpx->tag;
  138. xml_tag* curlog = NULL;
  139. xml_tag* logpart = NULL;
  140. curlog = xml_findfirst(root, "groundspeak:log");
  141. while (curlog) {
  142. time_t logtime = 0;
  143. struct tm* logtm = NULL;
  144. gbfprintf(file_out, "<p class=\"gpsbabellog\">\n");
  145. logpart = xml_findfirst(curlog, "groundspeak:type");
  146. if (logpart) {
  147. gbfprintf(file_out, "<span class=\"gpsbabellogtype\">%s</span> by ", CSTR(logpart->cdata));
  148. }
  149. logpart = xml_findfirst(curlog, "groundspeak:finder");
  150. if (logpart) {
  151. char* f = html_entitize(CSTR(logpart->cdata));
  152. gbfprintf(file_out, "<span class=\"gpsbabellogfinder\">%s</span> on ", f);
  153. xfree(f);
  154. }
  155. logpart = xml_findfirst(curlog, "groundspeak:date");
  156. if (logpart) {
  157. logtime = xml_parse_time(logpart->cdata).toTime_t();
  158. logtm = localtime(&logtime);
  159. if (logtm) {
  160. gbfprintf(file_out,
  161. "<span class=\"gpsbabellogdate\">%04d-%02d-%02d</span><br>\n",
  162. logtm->tm_year+1900,
  163. logtm->tm_mon+1,
  164. logtm->tm_mday);
  165. }
  166. }
  167. logpart = xml_findfirst(curlog, "groundspeak:log_wpt");
  168. if (logpart) {
  169. char* coordstr = NULL;
  170. double lat = 0;
  171. double lon = 0;
  172. coordstr = xml_attribute(logpart, "lat");
  173. if (coordstr) {
  174. lat = atof(coordstr);
  175. }
  176. coordstr = xml_attribute(logpart, "lon");
  177. if (coordstr) {
  178. lon = atof(coordstr);
  179. }
  180. coordstr = pretty_deg_format(lat, lon, degformat[2], " ", 1);
  181. gbfprintf(file_out,
  182. "<span class=\"gpsbabellogcoords\">%s</span><br>\n",
  183. coordstr);
  184. xfree(coordstr);
  185. }
  186. logpart = xml_findfirst(curlog, "groundspeak:text");
  187. if (logpart) {
  188. char* encstr = NULL;
  189. int encoded = 0;
  190. encstr = xml_attribute(logpart, "encoded");
  191. encoded = (toupper(encstr[0]) != 'F');
  192. QString s;
  193. if (html_encrypt && encoded) {
  194. s = rot13(logpart->cdata);
  195. } else {
  196. s = xstrdup(logpart->cdata);
  197. }
  198. QString t = html_entitize(s);
  199. gbfputs(t, file_out);
  200. }
  201. gbfprintf(file_out, "</p>\n");
  202. curlog = xml_findnext(root, curlog, "groundspeak:log");
  203. }
  204. }
  205. gbfprintf(file_out, "</td></tr></table>\n");
  206. }
  207. static void
  208. html_index(const Waypoint* wpt)
  209. {
  210. char* sn = html_entitize(wpt->shortname);
  211. char* d = html_entitize(wpt->description);
  212. gbfprintf(file_out, "<a href=\"#%s\">%s - %s</a><br>\n", sn, sn, d);
  213. xfree(sn);
  214. xfree(d);
  215. }
  216. static void
  217. data_write(void)
  218. {
  219. setshort_length(mkshort_handle, 6);
  220. gbfprintf(file_out, "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n");
  221. gbfprintf(file_out, "<html>\n");
  222. gbfprintf(file_out, "<head>\n");
  223. gbfprintf(file_out, " <meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\">\n");
  224. // Don't write this line when running test suite. Actually, we should
  225. // probably not write this line at all...
  226. if (!getenv("GPSBABEL_FREEZE_TIME")) {
  227. gbfprintf(file_out, " <meta name=\"Generator\" content=\"GPSBabel %s\">\n", gpsbabel_version);
  228. }
  229. gbfprintf(file_out, " <title>GPSBabel HTML Output</title>\n");
  230. if (stylesheet) {
  231. gbfprintf(file_out, " <link rel=\"stylesheet\" type=\"text/css\" href=\"%s\">\n", stylesheet);
  232. } else {
  233. gbfprintf(file_out, " <style>\n");
  234. gbfprintf(file_out, " p.gpsbabelwaypoint { font-size: 120%%; font-weight: bold }\n");
  235. gbfprintf(file_out, " </style>\n");
  236. }
  237. gbfprintf(file_out, "</head>\n");
  238. gbfprintf(file_out, "<body>\n");
  239. gbfprintf(file_out, "<p class=\"index\">\n");
  240. waypt_disp_all(html_index);
  241. gbfprintf(file_out, "</p>\n");
  242. waypt_disp_all(html_disp);
  243. gbfprintf(file_out, "</body>");
  244. gbfprintf(file_out, "</html>");
  245. }
  246. ff_vecs_t html_vecs = {
  247. ff_type_file,
  248. { ff_cap_write, ff_cap_none, ff_cap_none },
  249. NULL,
  250. wr_init,
  251. NULL,
  252. wr_deinit,
  253. NULL,
  254. data_write,
  255. NULL,
  256. html_args,
  257. CET_CHARSET_UTF8, 0 /* CET-REVIEW */
  258. };