1 #include "asciidoc.h"
2
3 #include <fstream>
4 #include <signal.h>
5 #include <stdlib.h>
6 #include <string.h>
7
8 #include "Wt/WString.h"
9
10 #ifndef WT_WIN32
11 #include <unistd.h>
12 #endif
13
14 namespace {
15
tempFileName()16 std::string tempFileName()
17 {
18 #ifndef WT_WIN32
19 char spool[20];
20 strcpy(spool, "/tmp/wtXXXXXX");
21
22 int i = mkstemp(spool);
23 close(i);
24 #else
25 char spool[2 * L_tmpnam];
26 tmpnam(spool);
27 #endif
28 return std::string(spool);
29 }
30
readFileToString(const std::string & fileName)31 std::string readFileToString(const std::string& fileName)
32 {
33 std::fstream file(fileName.c_str(), std::ios::in | std::ios::binary | std::ios::ate);
34 int length = file.tellg();
35 file.seekg(0, std::ios::beg);
36
37 std::unique_ptr<char[]> buf(new char[length]);
38 file.read(buf.get(), length);
39 file.close();
40
41 return std::string(buf.get(), length);
42 }
43
44 }
45
asciidoc(const Wt::WString & src)46 Wt::WString asciidoc(const Wt::WString& src)
47 {
48 std::string srcFileName = tempFileName();
49 std::string htmlFileName = tempFileName();
50
51 {
52 std::ofstream srcFile(srcFileName.c_str(), std::ios::out);
53 std::string ssrc = src.toUTF8();
54 srcFile.write(ssrc.c_str(), (std::streamsize)ssrc.length());
55 srcFile.close();
56 }
57
58 #if defined(ASCIIDOC_EXECUTABLE)
59 #define xstr(s) str(s)
60 #define str(s) #s
61 std::string cmd = xstr(ASCIIDOC_EXECUTABLE);
62 #else
63 std::string cmd = "asciidoc";
64 #endif
65 std::string command = cmd + " -o " + htmlFileName + " -s " + srcFileName;
66
67 #ifndef WT_WIN32
68 /*
69 * So, asciidoc apparently sends a SIGINT which is caught by its parent
70 * process.. So we have to temporarily ignore it.
71 */
72 struct sigaction newAction, oldAction;
73 newAction.sa_handler = SIG_IGN;
74 newAction.sa_flags = 0;
75 sigemptyset(&newAction.sa_mask);
76 sigaction(SIGINT, &newAction, &oldAction);
77 #endif
78 bool ok = system(command.c_str()) == 0;
79 #ifndef WT_WIN32
80 sigaction(SIGINT, &oldAction, 0);
81 #endif
82
83 Wt::WString result;
84
85 if (ok) {
86 result = Wt::WString(readFileToString(htmlFileName));
87 } else
88 result = Wt::WString("<i>Could not execute asciidoc</i>");
89
90 unlink(srcFileName.c_str());
91 unlink(htmlFileName.c_str());
92
93 return result;
94 }
95