「Qtの基礎 - Markdown」の版間の差分

ナビゲーションに移動 検索に移動
240行目: 240行目:
  make -j $(nproc)
  make -j $(nproc)
  make install
  make install
<br>
==== Qtプロジェクトファイル / CMakeLists.txtファイル ====
<syntaxhighlight lang="make">
# Qtプロジェクトファイル (.pro)
# Pkg-configを使用する場合
CONFIG += link_pkgconfig
PKGCONFIG += libcmark
# Pkg-configを使用しない場合
LIBS += -lcmark
</syntaxhighlight>
<br>
<syntaxhighlight lang="cmake">
# CMakeLists.txtファイル
find_package(PkgConfig REQUIRED)
pkg_check_modules(CMARK REQUIRED libcmark)
target_link_libraries(<ターゲット名> PRIVATE
    # ...略
    ${CMARK_LIBRARIES}
)
target_include_directories(<ターゲット名> PRIVATE
    ${CMARK_INCLUDE_DIRS}
)
target_compile_options(<ターゲット名> PRIVATE
    ${CMARK_CFLAGS_OTHER}
)
</syntaxhighlight>
<br>
==== Markdownの解析および操作 1 ====
以下の例では、cmarkライブラリを使用してMarkdownを解析および操作している。<br>
# Markdownファイルを開いて、その内容を読み込む。
# cmarkライブラリを使用して、Markdownを解析する。
# Markdownの構造を表示する。
# 全ての段落を太字に変更する。
# 修正されたMarkdownを出力する。
<br>
<syntaxhighlight lang="c++">
// MarkdownParser.hファイル
#include <QCoreApplication>
#include <QFile>
#include <QTextStream>
#include <cmark.h>
#include <QDebug>
class MarkdownParser
{
public:
    MarkdownParser() = default;
    bool parseFile(const QString &filePath)
    {
      QFile file(filePath);
      if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
          qDebug() << "ファイルのオープンに失敗: " << filePath;
          return false;
        }
      QTextStream in(&file);
      QString content = in.readAll();
      file.close();
      parseMarkdown(content);
      return true;
    }
    void parseMarkdown(const QString& markdown)
    {
      cmark_node *document = cmark_parse_document(markdown.toUtf8().constData(), markdown.length(), CMARK_OPT_DEFAULT);
      // Markdownの構造を表示
      printStructure(document);
      // 全ての段落を太字に変更
      modifyParagraphs(document);
      // 修正されたMarkdownを出力
      char *modified_markdown = cmark_render_commonmark(document, CMARK_OPT_DEFAULT, 0);
      qDebug() << "Modified Markdown:";
      qDebug() << QString::fromUtf8(modified_markdown);
      free(modified_markdown);
      cmark_node_free(document);
    }
private:
    void printStructure(cmark_node *node, int depth = 0)
    {
      while (node) {
          QString nodeType = QString::fromUtf8(cmark_node_get_type_string(node));
          qDebug().nospace() << QString(depth * 2, ' ') << nodeType;
          if (cmark_node_first_child(node)) {
            printStructure(cmark_node_first_child(node), depth + 1);
          }
          node = cmark_node_next(node);
      }
    }
    void modifyParagraphs(cmark_node *node)
    {
      while (node) {
          if (cmark_node_get_type(node) == CMARK_NODE_PARAGRAPH) {
            cmark_node *strong = cmark_node_new(CMARK_NODE_STRONG);
            cmark_node *child = cmark_node_first_child(node);
            while (child) {
                cmark_node *next = cmark_node_next(child);
                cmark_node_append_child(strong, cmark_node_unlink(child));
                child = next;
            }
            cmark_node_append_child(node, strong);
          }
          if (cmark_node_first_child(node)) {
            modifyParagraphs(cmark_node_first_child(node));
          }
          node = cmark_node_next(node);
      }
    }
};
</syntaxhighlight>
<br>
<syntaxhighlight lang="c++">
// main.cppファイル
#include "MarkdownParser.h"
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    MarkdownParser parser;
    parser.parseFile("<Markdownファイルのパス>");
    return a.exec();
}
</syntaxhighlight>
<br>
<br>
==== Markdownの解析および操作 2 ====
以下の例では、cmarkライブラリを使用してMarkdownを解析および操作している。<br>
# Markdownファイルを開いて、その内容を読み込む。
# cmarkライブラリを使用してMarkdownを解析する。
# ドキュメント内の全ての見出しを出力する。
# ドキュメント内のリンクを修正する<br>(全てのリンクの前に"https://example.com/"を追加)
# 修正したMarkdownを出力する。
<br>
<syntaxhighlight lang="c++">
// MarkdownParser.hファイル
#include <QCoreApplication>
#include <QFile>
#include <QTextStream>
#include <cmark.h>
#include <QDebug>
class MarkdownParser
{
public:
    MarkdownParser() = default;
    bool parseFile(const QString& filePath) {
      QFile file(filePath);
      if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
          qDebug() << "Could not open file:" << filePath;
          return false;
      }
      QTextStream in(&file);
      QString content = in.readAll();
      file.close();
      parseMarkdown(content);
      return true;
    }
    void parseMarkdown(const QString& markdown)
    {
      cmark_parser *parser = cmark_parser_new(CMARK_OPT_DEFAULT);
      cmark_parser_feed(parser, markdown.toUtf8().constData(), markdown.length());
      cmark_node *document = cmark_parser_finish(parser);
      // ドキュメント内の全ての見出しを出力
      printHeadings(document);
      // ドキュメント内のリンクを修正
      modifyLinks(document);
      // 修正されたMarkdownを出力
      char *modified_markdown = cmark_render_commonmark(document, CMARK_OPT_DEFAULT, 0);
      qDebug() << "Modified Markdown:";
      qDebug() << QString::fromUtf8(modified_markdown);
      free(modified_markdown);
      cmark_node_free(document);
      cmark_parser_free(parser);
    }
private:
    void printHeadings(cmark_node *node)
    {
      cmark_iter *iter = cmark_iter_new(node);
      cmark_event_type ev_type;
      cmark_node *cur;
      while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {
          cur = cmark_iter_get_node(iter);
          if (cmark_node_get_type(cur) == CMARK_NODE_HEADING) {
            char *heading_text = cmark_render_commonmark(cur, CMARK_OPT_DEFAULT, 0);
            qDebug() << "Heading:" << QString::fromUtf8(heading_text);
            free(heading_text);
          }
      }
      cmark_iter_free(iter);
    }
    void modifyLinks(cmark_node *node)
    {
      cmark_iter *iter = cmark_iter_new(node);
      cmark_event_type ev_type;
      cmark_node *cur;
      while ((ev_type = cmark_iter_next(iter)) != CMARK_EVENT_DONE) {
          cur = cmark_iter_get_node(iter);
          if (cmark_node_get_type(cur) == CMARK_NODE_LINK) {
            const char *url = cmark_node_get_url(cur);
            if (url) {
                QString newUrl = QString("https://example.com/") + QString::fromUtf8(url);
                cmark_node_set_url(cur, newUrl.toUtf8().constData());
            }
          }
      }
      cmark_iter_free(iter);
    }
};
</syntaxhighlight>
<br>
<syntaxhighlight lang="c++">
// main.cppファイル
#include "MarkdownParser.h"
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    MarkdownParser parser;
    parser.parseFile("<Markdownファイルのパス>");
    return a.exec();
}
</syntaxhighlight>
<br><br>
<br><br>


== cmark-gfmライブラリ ==
== cmark-gfmライブラリ ==

案内メニュー