📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)
細 文字列「__FORCETOC__」を「{{#seo: |title={{PAGENAME}} : Exploring Electronics and SUSE Linux | MochiuWiki |keywords=MochiuWiki,Mochiu,Wiki,Mochiu Wiki,Electric Circuit,Electric,pcb,Mathematics,AVR,TI,STMicro,AVR,ATmega,MSP430,STM,Arduino,Xilinx,FPGA,Verilog,HDL,PinePhone,Pine Phone,Raspberry,Raspberry Pi,C,C++,C#,Qt,Qml,MFC,Shell,Bash,Zsh,Fish,SUSE,SLE,Suse Enterprise,Suse Linux,openSUSE,open SUSE,Leap,Linux,uCLnux,Podman,電気回路,電子回路,基板,プリント基板 |description={{PAGENAME}} - 電子回路とSUSE Linuxに関する情報 | This pag… |
|||
| (同じ利用者による、間の4版が非表示) | |||
| 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; | |||
} | } | ||
| 741行目: | 803行目: | ||
<br> | <br> | ||
==== | ==== HTMLからMarkdownへ変換 ==== | ||
以下の例では、cmark-gfmライブラリを使用して、HTMLファイルからMarkdownファイルへ変換している。<br> | 以下の例では、cmark-gfmライブラリを使用して、HTMLファイルからMarkdownファイルへ変換している。<br> | ||
<syntaxhighlight lang="c++"> | <syntaxhighlight lang="c++"> | ||
| 795行目: | 857行目: | ||
return -1; | return -1; | ||
} | } | ||
return 0; | |||
} | |||
</syntaxhighlight> | |||
<br><br> | |||
== Hoedownライブラリ == | |||
==== Hoedownライブラリとは ==== | |||
Hoedownライブラリは、高速で柔軟性のあるMarkdown処理のためのC言語ベースのライブラリである。<br> | |||
このライブラリは高速で柔軟性があり、多くのアプリケーションで使用されている。<br> | |||
<br> | |||
Hoedownの特徴として、標準的なMarkdown構文のサポートに加えて、拡張機能も提供している。<br> | |||
これには表、コードブロック、自動リンク、脚注等が含まれる。<br> | |||
開発者は、これらの拡張機能を必要に応じて有効 / 無効にできるため、様々な要件に適応可能である。<br> | |||
<br> | |||
パフォーマンス面では、Hoedownは高速な処理を実現している。<br> | |||
大量のMarkdownテキストを扱う場合でも効率的に動作して、リソース使用量も抑えられている。<br> | |||
<br> | |||
また、Hoedownはカスタマイズ性も高く、独自のレンダラーを作成することが可能である。<br> | |||
これにより、Markdownを任意の出力形式に変換でき、HTML以外の他の形式への変換も可能である。<br> | |||
<br> | |||
セキュリティ面では、XSS攻撃などのセキュリティリスクを軽減するための機能が組み込まれている。<br> | |||
<br> | |||
Hoedownは様々なプログラミング言語から使用可能である。<br> | |||
C言語で記述されているため、多くの言語からバインディングを通じて使用できる。<br> | |||
Python、Ruby、Node.js等、多くの言語でHoedownを利用するためのラッパーが提供されている。<br> | |||
<br> | |||
Hoedownの使用には、C言語の基本的な知識およびMarkdownの仕様についての理解が必要である。<br> | |||
<br> | |||
==== Hoedownライブラリのライセンス ==== | |||
Hoedownライブラリは、ISCライセンスに準拠している。<br> | |||
<br> | |||
==== Hoedownライブラリのインストール ==== | |||
[https://github.com/hoedown/hoedown HoedownライブラリのGithub]にアクセスして、ソースコードをダウンロードする。<br> | |||
tar xf hoedown-<バージョン>.tar.gz | |||
cd hoedown-<バージョン> | |||
<br> | |||
または、<code>git clone</code>コマンドを実行して、ソースコードをダウンロードする。<br> | |||
git clone https://github.com/hoedown/hoedown.git | |||
cd hoedown | |||
<br> | |||
Hoedownライブラリをビルドおよびインストールする。<br> | |||
make PREFIX=<hoedownのインストールディレクトリ> -j $(nproc) | |||
make install | |||
<br> | |||
==== QtプロジェクトファイルおよびCMakeLists.txtファイル ==== | |||
<syntaxhighlight lang="make"> | |||
# Qtプロジェクトファイル (.pro) | |||
# Pkg-configを使用する場合 | |||
CONFIG += link_pkgconfig | |||
PKGCONFIG += hoedown | |||
# Pkg-configを使用しない場合 | |||
LIBS += -lhoedown | |||
</syntaxhighlight> | |||
<br> | |||
<syntaxhighlight lang="cmake"> | |||
# CMakeLists.txtファイル | |||
find_package(PkgConfig REQUIRED) | |||
pkg_check_modules(HOEDOWN REQUIRED hoedown) | |||
target_link_libraries(<ターゲット名> PRIVATE | |||
${HOEDOWN_LIBRARIES} | |||
) | |||
target_include_directories(<ターゲット名> PRIVATE | |||
${HOEDOWN_INCLUDE_DIRS} | |||
) | |||
target_compile_options(<ターゲット名> PRIVATE | |||
${HOEDOWN_CFLAGS_OTHER} | |||
) | |||
</syntaxhighlight> | |||
<br> | |||
==== HTMLファイルへ変換 ==== | |||
以下の例では、Hoedownライブラリを使用してMarkdownファイルを解析および操作している。<br> | |||
# Markdownファイルを読み込む。 | |||
# Hoedownライブラリを使用してMarkdownをHTMLに変換する。 | |||
# 変換結果を出力する。 | |||
<br> | |||
<syntaxhighlight lang="c++"> | |||
// main.cppファイル | |||
#include <QCoreApplication> | |||
#include <QFile> | |||
#include <QTextStream> | |||
#include <stdexcept> | |||
#include <hoedown/hoedown.h> | |||
#include <QDebug> | |||
QString parseMarkdown(const QString &markdown) | |||
{ | |||
hoedown_buffer *ib = nullptr, | |||
*ob = nullptr; | |||
hoedown_renderer *renderer = nullptr; | |||
hoedown_document *document = nullptr; | |||
QString result; | |||
try { | |||
ib = hoedown_buffer_new(markdown.toUtf8().length()); | |||
if (!ib) throw std::runtime_error("Failed to create input buffer"); | |||
hoedown_buffer_put(ib, markdown.toUtf8().constData(), markdown.toUtf8().length()); | |||
ob = hoedown_buffer_new(64); | |||
if (!ob) throw std::runtime_error("出力バッファの生成に失敗"); | |||
renderer = hoedown_html_renderer_new(HOEDOWN_HTML_SKIP_HTML, 0); | |||
if (!renderer) throw std::runtime_error("HTMLレンダラの生成に失敗"); | |||
document = hoedown_document_new(renderer, HOEDOWN_EXT_TABLES | HOEDOWN_EXT_FENCED_CODE, 16); | |||
if (!document) throw std::runtime_error("ドキュメントの生成に失敗"); | |||
hoedown_document_render(document, ob, ib->data, ib->size); | |||
result = QString::fromUtf8(hoedown_buffer_cstr(ob)); | |||
} | |||
catch (const std::exception &e) { | |||
qCritical() << "Markdownのパースに失敗: " << e.what(); | |||
} | |||
// リソースを削除 | |||
if (ib) hoedown_buffer_free(ib); | |||
if (ob) hoedown_buffer_free(ob); | |||
if (renderer) hoedown_html_renderer_free(renderer); | |||
if (document) hoedown_document_free(document); | |||
return result; | |||
} | |||
bool readMarkdownFile(const QString &filePath, QString &content) | |||
{ | |||
QFile file(filePath); | |||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { | |||
qCritical() << "Markdownファイルのオープンに失敗: " << file.errorString(); | |||
return false; | |||
} | |||
QTextStream in(&file); | |||
content = in.readAll(); | |||
file.close(); | |||
if (content.isEmpty()) { | |||
qWarning() << "The file is empty"; | |||
return false; | |||
} | |||
return true; | |||
} | |||
int main(int argc, char *argv[]) | |||
{ | |||
QCoreApplication a(argc, argv); | |||
QString filePath = "<Markdownファイルのパス>"; | |||
QFileInfo fileInfo(filePath); | |||
if (!fileInfo.exists()) { | |||
qCritical() << "Markdownファイルが見つからない: " << filePath; | |||
return -1; | |||
} | |||
if (!fileInfo.isFile() || !fileInfo.isReadable()) { | |||
qCritical() << "ファイルが読めない、または、正規のファイルではない: " << filePath; | |||
return -1; | |||
} | |||
QString content; | |||
if (!readMarkdownFile(filePath, content)) { | |||
return -1; | |||
} | |||
QString parsedContent = parseMarkdown(content); | |||
if (parsedContent.isEmpty()) { | |||
qCritical() << "Markdownのパースに失敗"; | |||
return 1; | |||
} | |||
qDebug() << "パースされたMarkdownの内容:"; | |||
qDebug().noquote() << parsedContent; | |||
return 0; | return 0; | ||
| 802行目: | 1,046行目: | ||
== その他のMarkdownパーサライブラリ == | == その他のMarkdownパーサライブラリ == | ||
* PEG Markdown Highlight | * PEG Markdown Highlight | ||
*: PEGによるMarkdownパーサであり、Markdownの解析とシンタックスハイライトに特化している。 | *: PEGによるMarkdownパーサであり、Markdownの解析とシンタックスハイライトに特化している。 | ||
| 812行目: | 1,054行目: | ||
<br><br> | <br><br> | ||
{{#seo: | |||
|title={{PAGENAME}} : Exploring Electronics and SUSE Linux | MochiuWiki | |||
|keywords=MochiuWiki,Mochiu,Wiki,Mochiu Wiki,Electric Circuit,Electric,pcb,Mathematics,AVR,TI,STMicro,AVR,ATmega,MSP430,STM,Arduino,Xilinx,FPGA,Verilog,HDL,PinePhone,Pine Phone,Raspberry,Raspberry Pi,C,C++,C#,Qt,Qml,MFC,Shell,Bash,Zsh,Fish,SUSE,SLE,Suse Enterprise,Suse Linux,openSUSE,open SUSE,Leap,Linux,uCLnux,Podman,電気回路,電子回路,基板,プリント基板 | |||
|description={{PAGENAME}} - 電子回路とSUSE Linuxに関する情報 | This page is {{PAGENAME}} in our wiki about electronic circuits and SUSE Linux | |||
|image=/resources/assets/MochiuLogo_Single_Blue.png | |||
}} | |||
__FORCETOC__ | __FORCETOC__ | ||
[[カテゴリ:Qt]] | [[カテゴリ:Qt]] | ||