1 /*
2  * marker-exporter.c
3  *
4  * Copyright (C) 2017 - 2018 Fabio Colacio
5  *
6  * Marker is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public License as
8  * published by the Free Software Foundation; either version 3 of the
9  * License, or (at your option) any later version.
10  *
11  * Marker is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with Marker; see the file LICENSE.md. If not,
18  * see <http://www.gnu.org/licenses/>.
19  *
20  */
21 
22 #define _GNU_SOURCE
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 
27 #include "marker.h"
28 #include "marker-utils.h"
29 #include "marker-string.h"
30 #include "marker-markdown.h"
31 #include "marker-prefs.h"
32 #include "marker-preview.h"
33 #include "marker-editor.h"
34 
35 #include "marker-exporter.h"
36 
37 MarkerExportFormat
marker_exporter_str_to_fmt(const char * str)38 marker_exporter_str_to_fmt(const char* str)
39 {
40   if (strcmp(str, "PDF") == 0)
41   {
42     return PDF;
43   }
44 
45   if (strcmp(str, "RTF") == 0)
46   {
47     return RTF;
48   }
49 
50   if (strcmp(str, "ODT") == 0)
51   {
52     return ODT;
53   }
54 
55   if (strcmp(str, "DOCX") == 0)
56   {
57     return DOCX;
58   }
59 
60   if (strcmp(str, "LATEX") == 0)
61   {
62     return LATEX;
63   }
64 
65   return HTML;
66 }
67 
68 void
marker_exporter_export_pandoc(const char * markdown,const char * stylesheet_path,const char * outfile)69 marker_exporter_export_pandoc(const char*        markdown,
70                               const char*        stylesheet_path,
71                               const char*        outfile)
72 {
73   const char* ftmp = ".marker_tmp_markdown.md";
74   char* path = marker_string_filename_get_path(outfile);
75   if (chdir(path) == 0)
76   {
77     FILE* fp = NULL;
78     fp = fopen(ftmp, "w");
79     if (fp)
80     {
81       fputs(markdown, fp);
82       fclose(fp);
83       char* command = NULL;
84 
85       asprintf(&command,
86                "pandoc -s -c %s -o %s %s",
87                stylesheet_path,
88                outfile,
89                ftmp);
90 
91       if (command)
92       {
93         system(command);
94       }
95 
96       free(command);
97       remove(ftmp);
98     }
99   }
100   free(path);
101 }
102 
103 void
marker_exporter_show_export_dialog(MarkerWindow * window)104 marker_exporter_show_export_dialog(MarkerWindow* window)
105 {
106   GtkDialog *dialog = GTK_DIALOG(gtk_file_chooser_dialog_new ("Export",
107                                                               GTK_WINDOW(window),
108                                                               GTK_FILE_CHOOSER_ACTION_SAVE,
109                                                               "Cancel", GTK_RESPONSE_CANCEL,
110                                                               "Export", GTK_RESPONSE_ACCEPT,
111                                                               NULL));
112 
113   GtkFileChooser *chooser = GTK_FILE_CHOOSER (dialog);
114   gtk_file_chooser_set_do_overwrite_confirmation (chooser, TRUE);
115   gtk_file_chooser_set_create_folders (chooser, TRUE);
116   gtk_file_chooser_set_select_multiple (chooser, FALSE);
117 
118   GtkFileFilter *filter = NULL;
119 
120   filter = gtk_file_filter_new ();
121   gtk_file_filter_set_name (filter, "HTML");
122   gtk_file_filter_add_pattern (filter, "*.html");
123   gtk_file_chooser_add_filter (chooser, filter);
124 
125   filter = gtk_file_filter_new ();
126   gtk_file_filter_set_name (filter, "PDF");
127   gtk_file_filter_add_pattern (filter, "*.pdf");
128   gtk_file_chooser_add_filter (chooser, filter);
129 
130   filter = gtk_file_filter_new ();
131   gtk_file_filter_set_name (filter, "RTF");
132   gtk_file_filter_add_pattern (filter, "*.rtf");
133   gtk_file_chooser_add_filter (chooser, filter);
134 
135   filter = gtk_file_filter_new ();
136   gtk_file_filter_set_name (filter, "DOCX");
137   gtk_file_filter_add_pattern (filter, "*.docx");
138   gtk_file_chooser_add_filter (chooser, filter);
139 
140   filter = gtk_file_filter_new ();
141   gtk_file_filter_set_name (filter, "ODT");
142   gtk_file_filter_add_pattern (filter, "*.odt");
143   gtk_file_chooser_add_filter (chooser, filter);
144 
145   filter = gtk_file_filter_new ();
146   gtk_file_filter_set_name (filter, "LATEX");
147   gtk_file_filter_add_pattern (filter, "*.tex");
148   gtk_file_chooser_add_filter (chooser, filter);
149 
150   filter = NULL;
151 
152   gint ret = gtk_dialog_run (dialog);
153   if (ret == GTK_RESPONSE_ACCEPT)
154   {
155     g_autofree gchar *filename = gtk_file_chooser_get_filename(chooser);
156     g_autofree gchar *stylesheet_path = marker_prefs_get_css_theme();
157     g_autofree gchar *markdown = NULL;
158 
159     filter = gtk_file_chooser_get_filter(chooser);
160     const gchar* file_type = gtk_file_filter_get_name(filter);
161     MarkerExportFormat fmt = marker_exporter_str_to_fmt(file_type);
162 
163 
164     MarkerEditor *editor = marker_window_get_active_editor (window);
165     MarkerPreview *preview = marker_editor_get_preview(editor);
166 
167     MarkerSourceView *source_view = marker_editor_get_source_view (editor);
168     markdown = marker_source_view_get_text (source_view, false);
169 
170     GFile * source = marker_editor_get_file(editor);
171     char * base_folder = NULL;
172 
173     if (source)
174       base_folder = g_file_get_path(g_file_get_parent(source));
175     size_t len = strlen(markdown);
176     metadata * meta = marker_markdown_metadata(markdown, len);
177     enum scidown_paper_size paper_size = meta->paper_size;
178     if (meta->doc_class == CLASS_BEAMER && !(paper_size == B43 || paper_size == B169))
179       paper_size = B43;
180 
181     if (!meta) {
182       fprintf(stderr, "marker-exporter.c#show_export_dialog: Document Metadata NULL!\n");
183       return;
184     }
185     GtkPageOrientation orientation = meta->doc_class == CLASS_BEAMER ? GTK_PAGE_ORIENTATION_LANDSCAPE : GTK_PAGE_ORIENTATION_PORTRAIT;
186     switch (fmt)
187     {
188       case HTML:
189         marker_markdown_to_html_file_with_css_inline(markdown,
190                                                      len,
191                                                      base_folder,
192                                                      (marker_prefs_get_use_mathjs())
193                                                        ? MATHJS_NET
194                                                        : MATHJS_OFF,
195                                                      (marker_prefs_get_use_highlight())
196                                                        ? HIGHLIGHT_NET
197                                                        : HIGHLIGHT_OFF,
198                                                      (marker_prefs_get_use_mermaid()
199                                                        ? MERMAID_NET
200                                                        : MERMAID_OFF),
201                                                      stylesheet_path,
202                                                      filename);
203         break;
204 
205       case PDF:
206         marker_preview_print_pdf(preview, filename, paper_size, orientation);
207         break;
208 
209       case LATEX:
210         marker_markdown_to_latex_file(markdown,
211                                       len,
212                                       base_folder,
213                                       (marker_prefs_get_use_mathjs())
214                                         ? MATHJS_NET
215                                         : MATHJS_OFF,
216                                       (marker_prefs_get_use_highlight())
217                                         ? HIGHLIGHT_NET
218                                         : HIGHLIGHT_OFF,
219                                       (marker_prefs_get_use_mermaid()
220                                         ? MERMAID_NET
221                                         : MERMAID_OFF),
222                                       filename);
223         break;
224 
225       default:
226         marker_exporter_export_pandoc(marker_markdown_to_html_with_css_inline(markdown,
227                                                                               len,
228                                                                               base_folder,
229                                                                               (marker_prefs_get_use_mathjs())
230                                                                                 ? MATHJS_NET
231                                                                                 : MATHJS_OFF,
232                                                                               (marker_prefs_get_use_highlight())
233                                                                                 ? HIGHLIGHT_NET
234                                                                                 : HIGHLIGHT_OFF,
235                                                                               (marker_prefs_get_use_mermaid()
236                                                                                 ? MERMAID_NET
237                                                                                 : MERMAID_OFF),
238                                                                               stylesheet_path,
239                                                                               -1),
240                                       stylesheet_path,
241                                       filename);
242         break;
243     }
244   }
245 
246   gtk_widget_destroy(GTK_WIDGET(dialog));
247 }
248 
249 void
marker_exporter_export(const gchar * infile,const gchar * outfile)250 marker_exporter_export (const gchar *infile,
251                         const gchar *outfile)
252 {
253   g_return_if_fail (infile != NULL && outfile != NULL);
254 
255   long len = 0;
256   g_autofree gchar *markdown = marker_utils_read_file (infile, &len);
257   g_autofree gchar *stylesheet = marker_prefs_get_css_theme ();
258   g_autofree gchar *base_folder = marker_string_filename_get_path (infile);
259 
260   metadata *meta = marker_markdown_metadata(markdown, len);
261   enum scidown_paper_size paper_size = meta->paper_size;
262   if (meta->doc_class == CLASS_BEAMER && !(paper_size == B43 || paper_size == B169))
263     paper_size = B43;
264   GtkPageOrientation orientation = meta->doc_class == CLASS_BEAMER ?
265     GTK_PAGE_ORIENTATION_LANDSCAPE :
266     GTK_PAGE_ORIENTATION_PORTRAIT;
267 
268   if (marker_string_ends_with (outfile, ".html")) {
269     marker_markdown_to_html_file_with_css_inline(markdown, len, base_folder,
270                                                  (marker_prefs_get_use_mathjs())
271                                                    ? MATHJS_NET
272                                                    : MATHJS_OFF,
273                                                  (marker_prefs_get_use_highlight())
274                                                    ? HIGHLIGHT_NET
275                                                    : HIGHLIGHT_OFF,
276                                                  (marker_prefs_get_use_mermaid()
277                                                    ? MERMAID_NET
278                                                    : MERMAID_OFF),
279                                                  stylesheet, outfile);
280   }
281   else if (marker_string_ends_with (outfile, ".pdf")) {
282     /*
283     g_autoptr (MarkerPreview) preview = marker_preview_new ();
284     marker_preview_render_markdown (preview, markdown, stylesheet, base_folder);
285     marker_preview_print_pdf (preview, outfile, paper_size, orientation);
286     */
287   }
288   else if (marker_string_ends_with (outfile, ".tex")) {
289     marker_markdown_to_latex_file(markdown, len, base_folder,
290                                   (marker_prefs_get_use_mathjs())
291                                     ? MATHJS_NET
292                                     : MATHJS_OFF,
293                                   (marker_prefs_get_use_highlight())
294                                     ? HIGHLIGHT_NET
295                                     : HIGHLIGHT_OFF,
296                                   (marker_prefs_get_use_mermaid()
297                                     ? MERMAID_NET
298                                     : MERMAID_OFF),
299                                   outfile);
300   }
301   else {
302     marker_exporter_export_pandoc(markdown, stylesheet, outfile);
303   }
304 }
305