12,788
回編集
506行目: | 506行目: | ||
<br> | <br> | ||
==== HTMLファイルへ変換 ==== | ==== HTMLファイルへ変換 ==== | ||
以下の例では、cmarkライブラリを使用して、MarkdownファイルをHTMLファイルに変換している。<br> | |||
# Markdownファイルを開いて、その内容を読み込む。 | |||
# cmarkライブラリを使用して、MarkdownをHTMLに変換する。 | |||
# 変換されたHTMLを基本的なHTML構造でラッピングする。 | |||
# ラッピングしたHTMLを新しいファイルに書き込む。 | |||
<br> | |||
<syntaxhighlight lang="c++"> | <syntaxhighlight lang="c++"> | ||
// MarkdownConverter.hファイル | // MarkdownConverter.hファイル | ||
520行目: | 526行目: | ||
MarkdownConverter() = default; | MarkdownConverter() = default; | ||
void convertFile(const QString &inputPath, const QString &outputPath) | |||
{ | { | ||
// Markdownファイルの読み込み | // Markdownファイルの読み込み | ||
try { | |||
QString markdownContent = readMarkdownFile(inputPath); | |||
QString htmlContent = convertMarkdownToHtml(markdownContent); | |||
writeHtmlFile(outputPath, htmlContent); | |||
qInfo() << "変換に成功: " << outputPath; | |||
} | |||
catch (const MarkdownConversionError& e) { | |||
qCritical() << "変換エラー: " << e.what(); | |||
throw; | |||
} | |||
catch (const std::exception& e) { | |||
qCritical() << "予期せぬエラーが発生: " << e.what(); | |||
throw; | |||
} | |||
} | |||
private: | |||
QString readMarkdownFile(const QString &inputPath) | |||
{ | |||
QFileInfo fileInfo(inputPath); | |||
if (!fileInfo.exists()) { | |||
throw MarkdownConversionError(QString("Input file does not exist: %1").arg(inputPath)); | |||
} | |||
if (!fileInfo.isReadable()) { | |||
throw MarkdownConversionError(QString("Input file is not readable: %1").arg(inputPath)); | |||
} | |||
QFile inputFile(inputPath); | QFile inputFile(inputPath); | ||
if (!inputFile.open(QIODevice::ReadOnly | QIODevice::Text)) { | if (!inputFile.open(QIODevice::ReadOnly | QIODevice::Text)) { | ||
throw MarkdownConversionError(QString("Could not open input file: %1").arg(inputPath)); | |||
} | } | ||
QTextStream in(&inputFile); | QTextStream in(&inputFile); | ||
QString | QString content = in.readAll(); | ||
inputFile.close(); | inputFile.close(); | ||
if (content.isEmpty()) { | |||
throw MarkdownConversionError(QString("Input file is empty: %1").arg(inputPath)); | |||
if ( | |||
} | } | ||
return content; | |||
return | |||
} | } | ||
QString convertMarkdownToHtml(const QString &markdown) | |||
QString convertMarkdownToHtml(const QString& markdown) | |||
{ | { | ||
// Markdownファイルをパース | // Markdownファイルをパース | ||
cmark_node *document = cmark_parse_document(markdown.toUtf8().constData(), markdown.length(), CMARK_OPT_DEFAULT); | cmark_node *document = cmark_parse_document(markdown.toUtf8().constData(), markdown.length(), CMARK_OPT_DEFAULT); | ||
if (!document) { | |||
throw MarkdownConversionError("Markdownのパースに失敗"); | |||
} | |||
// Convert to HTML | // Convert to HTML | ||
char *html = cmark_render_html(document, CMARK_OPT_DEFAULT); | char *html = cmark_render_html(document, CMARK_OPT_DEFAULT); | ||
if (!html) { | |||
cmark_node_free(document); | |||
throw MarkdownConversionError("MarkdownからHTMLのレンダリングに失敗"); | |||
} | |||
// HTMLの基本構文にラッピング | // HTMLの基本構文にラッピング | ||
580行目: | 609行目: | ||
return fullHtml; | return fullHtml; | ||
} | |||
void writeHtmlFile(const QString& outputPath, const QString& htmlContent) | |||
{ | |||
QFileInfo fileInfo(outputPath); | |||
QDir dir = fileInfo.dir(); | |||
if (!dir.exists()) { | |||
if (!dir.mkpath(".")) { | |||
throw MarkdownConversionError(QString("HTMLファイルを保存するディレクトリの作成に失敗: %1").arg(outputPath)); | |||
} | |||
} | |||
QFile outputFile(outputPath); | |||
if (!outputFile.open(QIODevice::WriteOnly | QIODevice::Text)) { | |||
throw MarkdownConversionError(QString("HTMLファイルの作成に失敗: %1").arg(outputPath)); | |||
} | |||
QTextStream out(&outputFile); | |||
out << htmlContent; | |||
outputFile.close(); | |||
if (outputFile.error() != QFile::NoError) { | |||
throw MarkdownConversionError(QString("HTMLファイルの書き込みに失敗: %1").arg(outputPath)); | |||
} | |||
} | } | ||
}; | }; | ||
597行目: | 651行目: | ||
MarkdownConverter converter; | MarkdownConverter converter; | ||
try { | |||
converter.convertFile(inputFile, outputFile); | |||
return 0; | |||
} | |||
catch (const MarkdownConversionError& e) { | |||
qCritical() << "変換に失敗: " << e.what(); | |||
return -1; | return -1; | ||
} | |||
catch (const std::exception &e) { | |||
qCritical() << "予期せぬエラーが発生: " << e.what(); | |||
return -2; | |||
} | } | ||