Remove the existing offline plugins documentation
This commit is contained in:
parent
3cfde39f10
commit
d601f8f0e6
7 changed files with 25 additions and 525 deletions
|
@ -236,6 +236,7 @@ if (APPLE)
|
|||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fPIC -stdlib=libc++ -Wno-inconsistent-missing-override")
|
||||
# This is necessary for genManual to be executed during the build phase,
|
||||
# it needs to be able to get the Qt libs.
|
||||
# TODO: is it still needed? genManual is removed.
|
||||
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||
SET(CMAKE_INSTALL_RPATH "${QT_INSTALL_LIBS}")
|
||||
else (APPLE)
|
||||
|
@ -899,14 +900,7 @@ add_custom_target(lrelease
|
|||
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
|
||||
)
|
||||
|
||||
##
|
||||
## Create and install the plugin framework manual
|
||||
##
|
||||
|
||||
add_custom_command(OUTPUT ${PROJECT_BINARY_DIR}/plugins
|
||||
COMMAND genManual ${PROJECT_SOURCE_DIR} ${PROJECT_BINARY_DIR}
|
||||
DEPENDS genManual
|
||||
)
|
||||
add_dependencies(mscore pluginDocumentation)
|
||||
|
||||
|
||||
##
|
||||
|
|
|
@ -10,62 +10,16 @@
|
|||
# the file LICENSE.GPL
|
||||
#=============================================================================
|
||||
|
||||
include (${PROJECT_SOURCE_DIR}/build/CopyFilesMacros.cmake)
|
||||
include (${PROJECT_SOURCE_DIR}/build/functions.cmake)
|
||||
|
||||
include_directories(
|
||||
${PROJECT_BINARY_DIR}
|
||||
${PROJECT_SOURCE_DIR}
|
||||
set(MANUAL_DEST "${PROJECT_BINARY_DIR}/share/manual/plugins/plugins3.html")
|
||||
|
||||
fn__copy_during_build(
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/plugins3.html"
|
||||
"${MANUAL_DEST}"
|
||||
)
|
||||
|
||||
if (APPLE)
|
||||
file(GLOB_RECURSE INCS "*.h")
|
||||
else (APPLE)
|
||||
set(INCS "")
|
||||
endif (APPLE)
|
||||
|
||||
add_executable(
|
||||
genManual
|
||||
${INCS}
|
||||
genManual.cpp
|
||||
)
|
||||
target_link_libraries(
|
||||
genManual
|
||||
${QT_LIBRARIES}
|
||||
)
|
||||
|
||||
if(APPLE)
|
||||
set_target_properties (
|
||||
genManual
|
||||
PROPERTIES
|
||||
COMPILE_FLAGS "-include all.h -D TESTROOT=\\\\\"${PROJECT_SOURCE_DIR}\\\\\" -g -Wall -Wextra"
|
||||
)
|
||||
else(APPLE)
|
||||
if (NOT MSVC)
|
||||
set_target_properties (
|
||||
genManual
|
||||
PROPERTIES
|
||||
COMPILE_FLAGS "-include all.h -D TESTROOT=\\\"${PROJECT_SOURCE_DIR}\\\" -g -Wall -Wextra"
|
||||
)
|
||||
else (NOT MSVC)
|
||||
set_target_properties (
|
||||
genManual
|
||||
PROPERTIES
|
||||
COMPILE_FLAGS "${PCH_INCLUDE} -D TESTROOT=\\\"${PROJECT_SOURCE_DIR}\\\""
|
||||
)
|
||||
|
||||
endif (NOT MSVC)
|
||||
endif(APPLE)
|
||||
|
||||
if(NOT MSVC)
|
||||
ADD_DEPENDENCIES(genManual mops1)
|
||||
endif(NOT MSVC)
|
||||
|
||||
add_custom_target(pluginDocumentation
|
||||
ALL
|
||||
DEPENDS genManual
|
||||
)
|
||||
|
||||
add_custom_command(TARGET pluginDocumentation
|
||||
POST_BUILD
|
||||
COMMAND ${PROJECT_BINARY_DIR}/manual/${CMAKE_CFG_INTDIR}/genManual ${PROJECT_SOURCE_DIR} ${PROJECT_BINARY_DIR}/share/manual
|
||||
DEPENDS "${MANUAL_DEST}"
|
||||
)
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
This program creates the manual pages for the plugin
|
||||
framework from the sources.
|
||||
|
||||
It reads in several header files and writes the output
|
||||
to mscore/share/manual/plugins/.
|
||||
|
||||
|
||||
Understood annotations in the source:
|
||||
|
||||
//@ object description
|
||||
@@ ObjectName
|
||||
/// object description
|
||||
@P propertyName propertyType propertyDescription
|
||||
|
||||
//@ methodDescription
|
||||
//@ ...
|
||||
Q_INVOKABLE methodDeclaration
|
||||
|
||||
|
||||
|
|
@ -1,443 +0,0 @@
|
|||
//=============================================================================
|
||||
// MuseScore
|
||||
// Music Composition & Notation
|
||||
//
|
||||
// Copyright (C) 2002-2011 Werner Schweer
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2
|
||||
// as published by the Free Software Foundation and appearing in
|
||||
// the file LICENCE.GPL
|
||||
//=============================================================================
|
||||
|
||||
#include <stdio.h>
|
||||
#include <QString>
|
||||
|
||||
QString srcPath;
|
||||
QString dstPath;
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Prop
|
||||
//---------------------------------------------------------
|
||||
|
||||
struct Prop {
|
||||
QString name;
|
||||
QString type;
|
||||
QString description;
|
||||
};
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Proc
|
||||
//---------------------------------------------------------
|
||||
|
||||
struct Proc {
|
||||
QString name;
|
||||
QString type;
|
||||
QStringList description;
|
||||
};
|
||||
|
||||
//---------------------------------------------------------
|
||||
// Class
|
||||
//---------------------------------------------------------
|
||||
|
||||
struct Class {
|
||||
QString name;
|
||||
QStringList description;
|
||||
QString parent;
|
||||
|
||||
QList<Prop> props;
|
||||
QList<Proc> procs;
|
||||
|
||||
bool operator<(const Class& c) const {
|
||||
return name < c.name;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
static QList<Class> classes;
|
||||
|
||||
//---------------------------------------------------------
|
||||
// addHeader
|
||||
//---------------------------------------------------------
|
||||
|
||||
static void addHeader(QString& out)
|
||||
{
|
||||
out += "<!DOCTYPE html>\n"
|
||||
"<html>\n"
|
||||
"<head>\n"
|
||||
" <meta charset=\"utf-8\">\n"
|
||||
" </head>\n"
|
||||
"<body>\n";
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// addFooter
|
||||
//---------------------------------------------------------
|
||||
|
||||
static void addFooter(QString& out)
|
||||
{
|
||||
out += /* "<div class=\"footer\"><a href=\"https://musescore.org/\">MuseScore</a> - Free music notation software<br/>\n"
|
||||
"© 2002-2016 Werner Schweer & others</div>\n" */
|
||||
"</body>\n"
|
||||
"</html>\n";
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// parseClass
|
||||
//---------------------------------------------------------
|
||||
|
||||
static void parseClass(const QString& name, const QString& in)
|
||||
{
|
||||
Class cl;
|
||||
cl.name = name;
|
||||
|
||||
QStringList sl = in.split("\n");
|
||||
QStringList methodDescription;
|
||||
|
||||
QRegExp re("@P ([^\\s]+)\\s+([^\\s]+)(.*)");
|
||||
|
||||
// matches Q_INVOKABLE void mops(int a); // comment
|
||||
QRegExp re1("Q_INVOKABLE +([^ ]+) +([^;]+); */*(.*)");
|
||||
QRegExp re2("Q_INVOKABLE +([^ ]+) +([^\\{]+)\\{");
|
||||
QRegExp re3("Q_INVOKABLE +([^ ]+) +(\\w+\\([^\\)]*\\))\\s+const\\s*([^\\{]*)\\{");
|
||||
|
||||
QRegExp reD("//@ (.*)");
|
||||
QRegExp re4 ("class +(\\w+) *(?:final)* *: *public +(\\w+) *\\{");
|
||||
QRegExp re4b("class +(\\w+) *(?:final)* *: *public +(\\w+), *public");
|
||||
|
||||
Q_ASSERT(re1.isValid() && re2.isValid() && re3.isValid());
|
||||
|
||||
bool parseClassDescription = true;
|
||||
|
||||
for(const QString& s : sl) {
|
||||
if (re.indexIn(s, 0) != -1) { //@P
|
||||
parseClassDescription = false;
|
||||
Prop p;
|
||||
p.name = re.cap(1);
|
||||
p.type = re.cap(2);
|
||||
p.description = re.cap(3);
|
||||
cl.props.append(p);
|
||||
}
|
||||
else if (re2.indexIn(s, 0) != -1) {
|
||||
parseClassDescription = false;
|
||||
Proc p;
|
||||
p.type = re2.cap(1);
|
||||
p.name = re2.cap(2);
|
||||
p.description = methodDescription;
|
||||
methodDescription.clear();
|
||||
cl.procs.append(p);
|
||||
}
|
||||
else if (re1.indexIn(s, 0) != -1) {
|
||||
parseClassDescription = false;
|
||||
Proc p;
|
||||
p.type = re1.cap(1);
|
||||
p.name = re1.cap(2);
|
||||
p.description = methodDescription;
|
||||
methodDescription.clear();
|
||||
cl.procs.append(p);
|
||||
}
|
||||
else if (re3.indexIn(s, 0) != -1) {
|
||||
parseClassDescription = false;
|
||||
Proc p;
|
||||
p.type = re3.cap(1);
|
||||
p.name = re3.cap(2);
|
||||
p.description = methodDescription;
|
||||
methodDescription.clear();
|
||||
cl.procs.append(p);
|
||||
}
|
||||
else if ((reD.indexIn(s, 0) != -1)) {
|
||||
if (parseClassDescription)
|
||||
cl.description.append(reD.cap(1));
|
||||
else
|
||||
methodDescription.append(reD.cap(1));
|
||||
}
|
||||
else if (s.startsWith("///")) {
|
||||
QString ss = s.mid(3);
|
||||
if (parseClassDescription)
|
||||
cl.description.append(ss);
|
||||
else
|
||||
methodDescription.append(ss);
|
||||
}
|
||||
else if (re4.indexIn(s, 0) != -1) {
|
||||
parseClassDescription = false;
|
||||
QString parent = re4.cap(2).simplified();
|
||||
if (name == re4.cap(1).simplified()) {
|
||||
cl.parent = parent;
|
||||
}
|
||||
else {
|
||||
printf("?<%s>!=<%s> derived from <%s>\n",
|
||||
qPrintable(name), qPrintable(re4.cap(1).simplified()), qPrintable(parent));
|
||||
}
|
||||
}
|
||||
else if (re4b.indexIn(s, 0) != -1) {
|
||||
parseClassDescription = false;
|
||||
QString parent = re4b.cap(2).simplified();
|
||||
if (name == re4b.cap(1).simplified()) {
|
||||
cl.parent = parent;
|
||||
}
|
||||
else {
|
||||
printf("?<%s>!=<%s> derived from <%s>\n",
|
||||
qPrintable(name), qPrintable(re4b.cap(1).simplified()), qPrintable(parent));
|
||||
}
|
||||
}
|
||||
}
|
||||
classes.append(cl);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// scanFile
|
||||
//---------------------------------------------------------
|
||||
|
||||
static void scanFile(const QString& in)
|
||||
{
|
||||
QList<Prop> props;
|
||||
QList<Proc> procs;
|
||||
|
||||
QRegExp re("@@ ([^\\n]*)");
|
||||
int gpos = 0;
|
||||
QString className;
|
||||
for (;;) {
|
||||
int rv = re.indexIn(in, gpos);
|
||||
if (rv == -1) {
|
||||
if (!className.isEmpty())
|
||||
parseClass(className, in.mid(gpos, in.size() - gpos));
|
||||
break;
|
||||
}
|
||||
int next = rv + re.matchedLength();
|
||||
if (gpos)
|
||||
parseClass(className, in.mid(gpos, next-gpos));
|
||||
|
||||
className = re.cap(1).simplified();
|
||||
gpos = next;
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// linkClass
|
||||
//
|
||||
// Given something like "array[Note]", will return "array[<a href="note.html">Note</a>]"
|
||||
//---------------------------------------------------------
|
||||
static QRegExp reClasses("");
|
||||
|
||||
static QString linkClass(const QString& in)
|
||||
{
|
||||
if (reClasses.pattern().isEmpty()) {
|
||||
QStringList classNames;
|
||||
foreach(const Class& cl, classes)
|
||||
classNames.append(cl.name);
|
||||
|
||||
reClasses.setPattern("\\b(" + classNames.join('|') + ")\\b");
|
||||
Q_ASSERT(reClasses.isValid());
|
||||
}
|
||||
|
||||
int pos = reClasses.indexIn(in);
|
||||
if (pos != -1) {
|
||||
QString out(in);
|
||||
out.insert(pos + reClasses.matchedLength(), "</a>");
|
||||
out.insert(pos, "<a href=\"" + in.mid(pos, reClasses.matchedLength()).toLower() + ".html\">");
|
||||
|
||||
return out;
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// writeOutput
|
||||
//---------------------------------------------------------
|
||||
|
||||
static void writeOutput()
|
||||
{
|
||||
for(const Class& cl : classes) {
|
||||
QString out;
|
||||
addHeader(out);
|
||||
out += QString("<h3>%1</h3>\n").arg(cl.name);
|
||||
|
||||
if (!cl.parent.isEmpty()) {
|
||||
// show parent only if its part of the exported classes
|
||||
for(const Class& lcl : classes) {
|
||||
if (lcl.name == cl.parent) {
|
||||
QString path = cl.parent.toLower();
|
||||
out += QString("<div class=\"class-inherit\">inherits <a href=\"%1.html\">%2</a></div>\n").arg(path).arg(cl.parent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!cl.description.isEmpty()) {
|
||||
out += "<div class=\"class-description\">\n";
|
||||
for(const QString& s : cl.description) {
|
||||
out += s.simplified().replace("\\brief ", "");
|
||||
out += "\n";
|
||||
}
|
||||
out += "</div>\n";
|
||||
}
|
||||
else
|
||||
out += "<br/>";
|
||||
|
||||
if (!cl.procs.isEmpty()) {
|
||||
out += "<h4>Methods</h4>\n";
|
||||
out += "<div class=\"methods\">\n";
|
||||
for(const Proc& p : cl.procs) {
|
||||
out += "<div class=\"method\">\n";
|
||||
out += linkClass(p.type) + " ";
|
||||
|
||||
QRegExp re("([^(]+)\\(([^)]*)\\)");
|
||||
if (re.indexIn(p.name, 0) != -1) {
|
||||
out += QString("<b>%2</b>(%3)\n") .arg(re.cap(1)).arg(linkClass(re.cap(2)));
|
||||
}
|
||||
else {
|
||||
out += QString("<b>%2</b>\n").arg(p.name);
|
||||
}
|
||||
out += "</div>\n";
|
||||
if (!p.description.isEmpty()) {
|
||||
out += "<div class=\"method-description\">\n";
|
||||
for(const QString& s : p.description) {
|
||||
out += s.simplified();
|
||||
out += "<br/>\n";
|
||||
}
|
||||
out += "</div>\n";
|
||||
}
|
||||
}
|
||||
out += "</div>\n";
|
||||
}
|
||||
if (!cl.props.isEmpty()) {
|
||||
out += "<h4>Properties</h4>\n";
|
||||
out += "<div class=\"properties\">\n";
|
||||
out += "<table>\n";
|
||||
int count = 1;
|
||||
for(const Prop& m : cl.props) {
|
||||
out += QString("<tr class=\"prop-%1\">") .arg( (count & 1) ? "odd" : "even");
|
||||
out += QString("<td class=\"prop-name\">%1</td>"
|
||||
"<td class=\"prop-type\">%2</td>"
|
||||
"<td class=\"prop-desc\">%3</td>")
|
||||
.arg(m.name).arg(linkClass(m.type)).arg(m.description);
|
||||
out += "</tr>\n";
|
||||
count++;
|
||||
}
|
||||
out += "</table></div>\n";
|
||||
}
|
||||
addFooter(out);
|
||||
|
||||
QString ofile = dstPath + "/plugins/" + cl.name.toLower() + ".html";
|
||||
QFile of(ofile);
|
||||
if (!of.open(QIODevice::WriteOnly)) {
|
||||
fprintf(stderr, "open <%s> failed: %s\n", qPrintable(ofile), qPrintable(of.errorString()));
|
||||
exit(-4);
|
||||
}
|
||||
of.write(out.toUtf8());
|
||||
of.close();
|
||||
}
|
||||
|
||||
//
|
||||
// write index
|
||||
//
|
||||
QString out;
|
||||
addHeader(out);
|
||||
out += "<h2>Score Elements</h2>\n";
|
||||
out += "<h3>Quick Guide</h3>\n";
|
||||
out += "<p>Below are all the various classes you can use."
|
||||
"<br>The main class is <a href='musescore.html'>MuseScore</a>."
|
||||
"<br>Use 'New' to create a skeleton plugin."
|
||||
"<br>Plugins are coded in <a href='http://doc.qt.io/qt-5/qmlapplications.html#what-is-qml'>QML</a>"
|
||||
"</p>\n";
|
||||
out += "<ul>\n";
|
||||
qSort(classes);
|
||||
for(const Class& s : classes) {
|
||||
out += QString("<li><a href=\"%1\">%2</a></li>\n")
|
||||
.arg(s.name.toLower() + ".html").arg(s.name);
|
||||
}
|
||||
out += "</ul>\n";
|
||||
addFooter(out);
|
||||
|
||||
QString ofile = dstPath + "/plugins/plugins.html";
|
||||
QFile of(ofile);
|
||||
if (!of.open(QIODevice::WriteOnly)) {
|
||||
fprintf(stderr, "open <%s> failed\n", qPrintable(ofile));
|
||||
exit(-4);
|
||||
}
|
||||
of.write(out.toUtf8());
|
||||
of.close();
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// copyAssets
|
||||
//---------------------------------------------------------
|
||||
|
||||
static void copyAssets(QString& lSrcPath, QString& lDstPath)
|
||||
{
|
||||
QString assetDstPath = lDstPath + "/plugins/";
|
||||
QString assetSrcPath = lSrcPath + "/manual/";
|
||||
// QStringList files = {"manual.css", "manual-dark.css", "mscore.png" };
|
||||
QStringList files = {"mscore.png" };
|
||||
|
||||
// copy files from source to destination path
|
||||
for (QString f : files) {
|
||||
// be sure destination files do not exist
|
||||
QFile dst(assetDstPath + f);
|
||||
dst.remove();
|
||||
|
||||
if (!QFile::copy(assetSrcPath + f, assetDstPath + f))
|
||||
fprintf(stderr, "Cannot copy %s to %s\n",
|
||||
qPrintable(assetSrcPath + f),
|
||||
qPrintable(assetDstPath + f));
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// usage
|
||||
//---------------------------------------------------------
|
||||
|
||||
static void usage(const char* program, const char* hint)
|
||||
{
|
||||
fprintf(stderr, "%s: %s\n", program, hint);
|
||||
fprintf(stderr, "usage: %s srcPath dstPath\n", program);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
// main
|
||||
//---------------------------------------------------------
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc != 3) {
|
||||
usage(argv[0], "bad arguments");
|
||||
return -1;
|
||||
}
|
||||
srcPath = argv[1];
|
||||
dstPath = argv[2];
|
||||
QStringList files;
|
||||
files << "mscore/plugin/qmlplugin.h";
|
||||
files << "mscore/svggenerator.h";
|
||||
|
||||
QDir libdir(srcPath + "/libmscore");
|
||||
QStringList filter;
|
||||
filter << "*.h";
|
||||
QStringList fl = libdir.entryList(filter, QDir::Files);
|
||||
|
||||
for(QString f : fl)
|
||||
files << "libmscore/" + f;
|
||||
|
||||
for(const QString& s : files) {
|
||||
QString infile = srcPath + "/" + s;
|
||||
QFile inFile(infile);
|
||||
if (!inFile.open(QIODevice::ReadOnly)) {
|
||||
fprintf(stderr, "%s: cannot open input file <%s>\n",
|
||||
argv[0], qPrintable(infile));
|
||||
return -2;
|
||||
}
|
||||
//printf("ScanFile %s\n", qPrintable(infile));
|
||||
QString in = inFile.readAll();
|
||||
scanFile(in);
|
||||
inFile.close();
|
||||
}
|
||||
QDir dir;
|
||||
QString opath = dstPath + "/plugins";
|
||||
if (!dir.mkpath(opath)) {
|
||||
fprintf(stderr, "%s: cannot create destination path: <%s>\n",
|
||||
argv[0], qPrintable(dstPath));
|
||||
return -3;
|
||||
}
|
||||
writeOutput();
|
||||
copyAssets(srcPath, dstPath);
|
||||
return 0;
|
||||
}
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 1.8 KiB |
15
manual/plugins3.html
Normal file
15
manual/plugins3.html
Normal file
|
@ -0,0 +1,15 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Plugins manual</title>
|
||||
<meta content="">
|
||||
<style></style>
|
||||
</head>
|
||||
<body>
|
||||
See
|
||||
<a href="https://musescore.org/handbook/developers-handbook/plugins-3x">
|
||||
this Handbook page
|
||||
</a>
|
||||
to find the most recent version of documentation on plugins development.
|
||||
</body>
|
||||
</html>
|
|
@ -119,7 +119,7 @@ PluginCreator::PluginCreator(QWidget* parent)
|
|||
QString PluginCreator::manualPath()
|
||||
{
|
||||
QString _path = mscoreGlobalShare;
|
||||
_path += "/manual/plugins/plugins.html";
|
||||
_path += "/manual/plugins/plugins3.html";
|
||||
return _path;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue