// MakePDF.cpp : Defines the entry point for the console application.
//
#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "DocVisitor.h"
#include "DocTemplate.h"
#include "DocOutput.h"
#include "DocSVG.h"
#include "Util.h"
//#include "document.h"
#include "html.h"
#include "tinyxml.h"
#ifndef _WIN32
# include <unistd.h>
//# define __cdecl
#else
extern "C" void __stdcall Sleep(unsigned int);
#endif
#ifdef GUI_APP
# include "ui.h"
#endif
#define DEF_IUNIT 1024
#define DEF_OUNIT 64
#define DEF_MAX_NESTING 16
extern void runTests();
struct Context
{
const char* title;
const char* inFileName;
const char* outFileName_PDF;
const char* outFileName_HTML;
DocOutputDevice* doc;
hoedown_buffer *inputBuffer;
hoedown_buffer *outputBuffer;
};
static void RemoveFile(const char* fileName)
{
#ifdef _WIN32
FILE* tmpF = 0;
bool first = true;
do
{
fopen_s(&tmpF, fileName, "rb");
if (tmpF)
{
fclose(tmpF);
_unlink(fileName);
::Sleep(100);
if (first)
printf("waiting for output file to be removed.");
else
printf(".");
first = false;
fflush(stdout);
}
} while (tmpF != 0);
#else
unlink(fileName);
#endif
}
hoedown_buffer *ReadInWholeFile(const char* inputFileName)
{
// Read in the markdown file
FILE* f = 0;
fopen_s(&f, inputFileName, "rt"); // text or binary? Can it be utf8, and if so, do I need to read in binary mode?
if (!f)
return 0;
/*
fseek(f, 0L, SEEK_END);
long fileSize = ftell(f);
fseek(f, 0L, SEEK_SET);
uint8_t* inputBuffer = (uint8_t*)malloc(fileSize);
size_t inputBufferSize = fread(inputBuffer, 1, fileSize, f);
*/
hoedown_buffer *ib = hoedown_buffer_new(DEF_IUNIT);
if (hoedown_buffer_putf(ib, f))
fprintf(stderr, "I/O errors found while reading input.\n");
fclose(f);
return ib;
}
hoedown_buffer *ConvertMarkdownToHTML(uint8_t* inputBuffer, size_t inputBufferSize)
{
hoedown_html_flags flags = (hoedown_html_flags)(HOEDOWN_HTML_ESCAPE | HOEDOWN_HTML_HARD_WRAP | HOEDOWN_HTML_USE_XHTML);
hoedown_renderer *renderer = hoedown_html_renderer_new(flags, 0);
hoedown_buffer *ob = hoedown_buffer_new(DEF_OUNIT);
hoedown_document *document = hoedown_document_new(renderer, HOEDOWN_EXT_SPACE_HEADERS, DEF_MAX_NESTING);
hoedown_document_render(document, ob, inputBuffer, inputBufferSize);
hoedown_document_free(document);
hoedown_html_renderer_free(renderer);
return ob;
}
void SVGTest(const char* a_fileName, double scale, DocOutputDevice* outputDoc)
{
hoedown_buffer* inputBuffer = ReadInWholeFile(a_fileName);
if (!inputBuffer)
return;
// SVG xml parse
TiXmlDocument parser;
parser.Parse((char*)inputBuffer->data);
DocSVG visitor(scale);
parser.Accept(&visitor);
visitor.DumpOperations();
visitor.WriteTo(outputDoc);
hoedown_buffer_free(inputBuffer);
}
void ConvertHTMLToPDF(uint8_t* inputBuffer, DocOutputDevice* outputDoc)
{
// xml parse
DocStyle style;
DocTemplate templ;
TiXmlDocument parser;
templ.ReadTemplateFile("test.tmpl");
parser.Parse((char*)inputBuffer);
DocVisitor visitor(outputDoc, &style, &templ);
parser.Accept(&visitor);
//SVGTest("test/triangle.svg", 0.02, outputDoc);
//SVGTest("test/ArcTest.svg", 1.0, outputDoc);
}
void SaveHTML(const char* fileName, const uint8_t* data, size_t dataSize)
{
RemoveFile(fileName);
FILE* f = 0;
fopen_s(&f, fileName, "wb");
if (!f)
return;
const char *CSSText = "<!DOCTYPE html><html><head><title>test</title><link rel=\"stylesheet\" type=\"text/css\" href=\"base.css\"></head><body>";
fwrite(CSSText, 1, strlen(CSSText), f);
fwrite(data, 1, dataSize, f);
fclose(f);
}
int ProcessConversionContext(Context* context)
{
context->inputBuffer = ReadInWholeFile(context->inFileName);
if (!context->inputBuffer)
return -1;
context->outputBuffer = ConvertMarkdownToHTML(context->inputBuffer->data, context->inputBuffer->size);
//free(inputBuffer);
hoedown_buffer_free(context->inputBuffer);
ConvertHTMLToPDF(context->outputBuffer->data, context->doc);
SaveHTML(context->outFileName_HTML, context->outputBuffer->data, context->outputBuffer->size);
hoedown_buffer_free(context->outputBuffer);
RemoveFile(context->outFileName_PDF);
context->doc->finalize(context->outFileName_PDF);
return 0;
}
int main(int argc, char* argv[])
{
DocOutputDevice outputDoc;
Context context = {
"Test Markdown to PDF",
"test/test.md",
"test/test.pdf",
"test/test.html",
&outputDoc
};
ProcessConversionContext(&context);
/*
// Qt MDI Example does this:
Q_INIT_RESOURCE(mdi);
QApplication app(argc, argv);
QCoreApplication::setApplicationVersion(QT_VERSION_STR);
QCommandLineParser parser;
parser.setApplicationDescription("Qt MDI Example");
parser.addHelpOption();
parser.addVersionOption();
parser.addPositionalArgument("file", "The file to open.");
parser.process(app);
MainWindow mainWin;
foreach (const QString &fileName, parser.positionalArguments())
mainWin.openFile(fileName);
mainWin.show();
return app.exec();
*/
#ifdef GUI_APP
QApplication app(argc, argv);
UiContext ui;
ui.setupUi();
//YQ_LOG_DEBUG("This is a test message");
//runTests();
app.exec();
#endif
/*
fprintf(stderr, "HERE!\n\n\n");
QApplication app2(argc, argv);
QLabel l(0);
l.setText("Hello!");
l.show();
app2.exec();
*/
return 0;
}