📢 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…
 
(同じ利用者による、間の10版が非表示)
61行目: 61行目:
  }
  }
  </syntaxhighlight>
  </syntaxhighlight>
<br<<br>
<br><br>


== Markdownファイルの書き込み ==
== Markdownファイルの書き込み ==
168行目: 168行目:
   
   
     return a.exec();
     return a.exec();
}
</syntaxhighlight>
<br><br>
== cmarkライブラリ ==
==== cmarkライブラリとは ====
cmarkライブラリは、CommonMarkのC言語リファレンス実装で、Markdown構文の合理化バージョンである。<br>
<br>
CommonMarkドキュメントを抽象構文木 (AST) にパースして、<br>
ASTを操作、ドキュメントをHTML、groff man、LaTeX、CommonMark、ASTのXML表現にレンダリングする関数を備えたライブラリである。<br>
<br>
また、CommonMark文書の解析とレンダリングのためのコマンドラインプログラム (cmark) も提供する。<br>
<br>
ライブラリの機能と特徴を以下に示す。
下記の機能により、cmarkライブラリはMarkdownの解析や変換だけでなく、複雑なドキュメント処理システムの構築にも使用できる。<br>
<br>
* マークダウンの解析
*: cmarkは、Markdownテキストを構文解析し、抽象構文木 (AST) を生成する。
*: CommonMark標準に準拠しており、仕様に基づいた確実な解析が可能である。
*: <br>
* MarkdownからHTMLへの変換
*: 解析されたMarkdownをHTMLに変換する。
*: 変換時に様々なオプションを指定することで出力をカスタマイズできる。
*: <br>
* AST (抽象構文木) の操作
*: 解析されたMarkdownのASTを直接操作できる。
*: これにより、Markdownの構造を動的に変更したり、カスタム処理を行ったりすることが可能である。
*: <br>
* カスタム出力
*: 特定のニーズに合わせた出力フォーマットのカスタマイズが可能である。
*: 出力内容を制御するためのオプションやAPIが提供されている。
*: <br>
* マルチスレッドセーフ
*: 並行処理を行うアプリケーションでも安全に使用できる。
*: <br>
* 様々な出力形式
*: HTML以外にも、LaTeX、XML、Manページ形式等、複数の出力形式をサポートしている。
*: <br>
* UTF-8サポート
*: Unicode文字を適切に処理する。
*: <br>
* サニタイズ機能
*: XSS攻撃を防ぐため、HTMLの安全な出力オプションを提供している。
*: <br>
* コマンドラインツール
*: ライブラリと共にコマンドラインツールも提供されており、ファイルの変換やデバッグに使用できる。
<br>
==== cmarkライブラリのライセンス ====
cmarkライブラリは、2条項BSDライセンスに準拠している。<br>
<br>
==== cmarkライブラリのインストール ====
===== パッケージ管理システムからインストール =====
# RHEL
sudo dnf install cmark
# SUSE
sudo zypper install cmark
<br>
===== ソースコードからインストール =====
[https://github.com/commonmark/cmark cmarkライブラリのGithub]にアクセスして、ソースコードをダウンロードする。<br>
ダウンロードしたファイルを解凍する。<br>
tar xf cmark-<バージョン>.tar.gz
cd cmark-<バージョン>
<br>
cmarkライブラリをビルドおよびインストールする。<br>
mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release \
      -DCMAKE_INSTALL_PREFIX=<cmakeライブラリのインストールディレクトリ> \
      ..
make -j $(nproc)
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>
==== HTMLファイルへ変換 ====
以下の例では、cmarkライブラリを使用して、MarkdownファイルをHTMLファイルに変換している。<br>
# Markdownファイルを開いて、その内容を読み込む。
# cmarkライブラリを使用して、MarkdownをHTMLに変換する。
# 変換されたHTMLを基本的なHTML構造でラッピングする。
# ラッピングしたHTMLを新しいファイルに書き込む。
<br>
<syntaxhighlight lang="c++">
// MarkdownConverter.hファイル
#include <QCoreApplication>
#include <QFile>
#include <QTextStream>
#include <cmark.h>
#include <QDebug>
class MarkdownConverter
{
public:
    MarkdownConverter() = default;
    void convertFile(const QString &inputPath, const QString &outputPath)
    {
      // 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);
      if (!inputFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
          throw MarkdownConversionError(QString("Could not open input file: %1").arg(inputPath));
      }
      QTextStream in(&inputFile);
      QString content = in.readAll();
      inputFile.close();
      if (content.isEmpty()) {
          throw MarkdownConversionError(QString("Input file is empty: %1").arg(inputPath));
      }
      return content;
    }
    QString convertMarkdownToHtml(const QString &markdown)
    {
      // Markdownファイルをパース
      cmark_node *document = cmark_parse_document(markdown.toUtf8().constData(), markdown.length(), CMARK_OPT_DEFAULT);
      if (!document) {
          throw MarkdownConversionError("Markdownのパースに失敗");
      }
      // Convert to HTML
      char *html = cmark_render_html(document, CMARK_OPT_DEFAULT);
      if (!html) {
          cmark_node_free(document);
          throw MarkdownConversionError("MarkdownからHTMLのレンダリングに失敗");
      }
      // HTMLの基本構文にラッピング
      QString fullHtml = QString(
          "<!DOCTYPE html>\n"
          "<html lang=\"en\">\n"
          "<head>\n"
          "    <meta charset=\"UTF-8\">\n"
          "    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n"
          "    <title>Converted Markdown</title>\n"
          "</head>\n"
          "<body>\n"
          "%1\n"
          "</body>\n"
          "</html>"
      ).arg(QString::fromUtf8(html));
      // Free allocated memory
      free(html);
      cmark_node_free(document);
      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));
      }
    }
};
</syntaxhighlight>
<br>
<syntaxhighlight lang="c++">
// main.cppファイル
#include "MarkdownConverter.h"
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QString inputFile  = "<入力 : Markdownファイルのパス>";
    QString outputFile = "<出力 : HTMLファイルのパス>";
    MarkdownConverter converter;
    try {
      converter.convertFile(inputFile, outputFile);
      return 0;
    }
    catch (const MarkdownConversionError& e) {
      qCritical() << "変換に失敗: " << e.what();
      return -1;
    }
    catch (const std::exception &e) {
      qCritical() << "予期せぬエラーが発生: " << e.what();
      return -2;
    }
    return 0;
  }
  }
  </syntaxhighlight>
  </syntaxhighlight>
252行目: 749行目:
以下の例では、cmark-gfmライブラリを使用して、MarkdownファイルからHTMLファイルへ変換している。<br>
以下の例では、cmark-gfmライブラリを使用して、MarkdownファイルからHTMLファイルへ変換している。<br>
  <syntaxhighlight lang="c++">
  <syntaxhighlight lang="c++">
  #include <QcoreApplication>
  #include <QCoreApplication>
  #include <QFile>
  #include <QFile>
  #include <QTextStream>
  #include <QTextStream>
305行目: 802行目:
  </syntaxhighlight>
  </syntaxhighlight>
<br>
<br>
==== HTMLファイルへ変換 ====
 
==== HTMLからMarkdownへ変換 ====
以下の例では、cmark-gfmライブラリを使用して、HTMLファイルからMarkdownファイルへ変換している。<br>
以下の例では、cmark-gfmライブラリを使用して、HTMLファイルからMarkdownファイルへ変換している。<br>
  <syntaxhighlight lang="c++">
  <syntaxhighlight lang="c++">
365行目: 863行目:
<br><br>
<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;
}
</syntaxhighlight>
<br><br>
== その他のMarkdownパーサライブラリ ==
* PEG Markdown Highlight
*: PEGによるMarkdownパーサであり、Markdownの解析とシンタックスハイライトに特化している。
* Discount
*: C言語で記述されたMarkdownパーサであり、ANSIに準拠している。
* MD4C
*: C言語で記述されたMarkdownパーサであり、UTF-8に対応しており、HTMLレンダリングも可能である。
<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]]