diff --git a/assets/javascripts/templates/pages/about_tmpl.coffee b/assets/javascripts/templates/pages/about_tmpl.coffee index d90c338a..96febbc2 100644 --- a/assets/javascripts/templates/pages/about_tmpl.coffee +++ b/assets/javascripts/templates/pages/about_tmpl.coffee @@ -575,6 +575,11 @@ credits = [ '2009-2017 Kristopher Michael Kowal', 'MIT', 'https://raw.githubusercontent.com/kriskowal/q/master/LICENSE' + ], [ + 'Qt', + '2012-2018 The Qt Company Ltd', + 'GFDL', + 'https://doc.qt.io/qt-5/licensing.html' ], [ 'Ramda', '2013-2016 Scott Sauyet and Michael Hurley', diff --git a/assets/stylesheets/application-dark.css.scss b/assets/stylesheets/application-dark.css.scss index 38346905..821ebc36 100644 --- a/assets/stylesheets/application-dark.css.scss +++ b/assets/stylesheets/application-dark.css.scss @@ -83,6 +83,7 @@ 'pages/postgres', 'pages/pug', 'pages/python', + 'pages/qt', 'pages/ramda', 'pages/rdoc', 'pages/react_native', diff --git a/assets/stylesheets/application.css.scss b/assets/stylesheets/application.css.scss index 64916112..245a8012 100644 --- a/assets/stylesheets/application.css.scss +++ b/assets/stylesheets/application.css.scss @@ -83,6 +83,7 @@ 'pages/postgres', 'pages/pug', 'pages/python', + 'pages/qt', 'pages/ramda', 'pages/rdoc', 'pages/react_native', diff --git a/assets/stylesheets/pages/_qt.scss b/assets/stylesheets/pages/_qt.scss new file mode 100644 index 00000000..8efecaaf --- /dev/null +++ b/assets/stylesheets/pages/_qt.scss @@ -0,0 +1,63 @@ +._qt { + @extend %simple; + + h1 { + margin-top: 0; + @extend %lined-heading; + } + + // Home page + .landingicons { + .icons1of3 { + display: flex; + flex-wrap: wrap; + align-items: center; + margin: 1em 0; + + @if $style == 'dark' { + &:nth-child(3) img { + filter: invert(1) hue-rotate(180deg) brightness(1.5) + } + } + } + + h2 { + flex: 1; + margin: 0; + margin-left: 10px; + } + + h2 + p { + width: 100%; + padding-left: 70px; + } + + .centerAlign, + .centerAlign img { // Icon + width: 60px; + height: 60px; + margin: 0; + } + } + + // Syntax highlighting + .pre { + .operator { @extend .token, .operator; } + .number { @extend .token, .number; } + .keyword { @extend .token, .keyword; } + .type { @extend .token, .function; } + .type a { color: inherit; } + .pun, .comment { @extend .token, .punctuation; } + .kwd, .preprocessor { @extend .token, .keyword; } + .str, .string { @extend .token, .string; } + } + + // Function headers + h3.fn code { + @extend %label; + float: right; + font-size: .8em; + padding: 0; + margin-right: -.5em; + } +} diff --git a/lib/docs/filters/qt/clean_html.rb b/lib/docs/filters/qt/clean_html.rb new file mode 100644 index 00000000..18e57baa --- /dev/null +++ b/lib/docs/filters/qt/clean_html.rb @@ -0,0 +1,21 @@ +module Docs + class Qt + class CleanHtmlFilter < Filter + def call + # Remove unneeded elements + css('.copy-notice, .navigationbar, .headerNavi, .footerNavi, .sidebar, .toc, #ec_toggle').remove + + # QML property/method header + css('.qmlproto').each do |node| + id = node.at_css('tr')['id'] + node.inner_html = node.at_css('td').inner_html + node.name = 'h3' + node.add_class '_qml_header' + node['id'] = id + end + + doc + end + end + end +end diff --git a/lib/docs/filters/qt/entries.rb b/lib/docs/filters/qt/entries.rb new file mode 100644 index 00000000..c9e172d0 --- /dev/null +++ b/lib/docs/filters/qt/entries.rb @@ -0,0 +1,139 @@ +module Docs + class Qt + class EntriesFilter < Docs::EntriesFilter + def get_name + header = at_css('h1.title + .small-subtitle a') || at_css('h1.title') || at_css('.context h2') + name = header.content + name.sub! %r{ Class$}, ' (class)' + name.sub! %r{ QML Type$}, ' (QML type)' + name.sub! %r{ QML Basic Type$}, ' (QML basic type)' + + # Add '(class)' to the class pages where the subtitle name is used (e.g. qset-const-iterator.html) + if at_css('h1.title').content.strip.end_with?(' Class') and !name.include?('(class)') + name = "#{name} (class) " + end + + name + end + + def get_type + breadcrumb = css('#main_title_bar + ul li') + category = if breadcrumb.length < 3 + then 'Qt' + else breadcrumb.at(1).content + end + + if category == 'Qt' + return 'Qt Platforms' if name.include? ' for ' or name == 'Qt Platform Abstraction' + return 'Qt Quick' if name == 'Qt Quick Test' or name == 'Qt Quick Test Reference Documentation' + + alwaysInQt = ["Qt Configure Options", "Qt Image Formats"] + category = name if name.start_with?('Qt ') && !alwaysInQt.include?(name) + end + + qtPlatformsTypes = ['Qt Platform Headers', 'Qt Android Extras', 'Qt Mac Extras', 'Qt Windows Extras', 'Qt X11 Extras'] + return 'Qt Platforms' if qtPlatformsTypes.include? category + + category.sub! ' Manual', '' + category + end + + def include_default_entry? + name != 'All Classes' and name != 'All QML Types' + end + + def additional_entries + entries = [] + titles = [] + + className = at_css('h1.title').content.strip.sub ' Class', '' + displayedClassName = className + alternativeClassName = at_css('h1.title + .small-subtitle a') + displayedClassName = alternativeClassName.content if alternativeClassName + + # Functions signatures + css('h3.fn').each do |node| + header = node.clone + + # Skip typenames + next if header.content.strip.start_with? 'typename ' + + # Remove leading + header.children.css('a[name]').remove + + # Remove leading tag (virtual/static/… attributes) + code = header.children.first + code.remove if code.name == 'code' + + # Remove leading ‘const’ + header.children.first.remove if header.content.strip.start_with? 'const ' + + # Remove return type + returnType = header.children.first + returnType.remove if returnType['class'] == 'type' + + title = header.content.strip + + # Remove leading '&'/'*' + title[0] = '' if title[0] == '&' || title[0] == '*' + + # Ignore operator overloads + next if title.start_with? 'operator' + + # Remove function parameters + title.sub! %r{\(.*\)}, '()' + + # Remove template generics + title.sub! %r{^<.*> }, '' + + # Remove ‘const’ at the end + title.sub! %r{ const$}, '' + + # Enum/typedef formatting + title.sub! %r{(enum|typedef) (.*)}, '\2 (\1)' + + # Remove property type + title = "#{displayedClassName}::#{title}" if title.sub! %r{ : .*$}, '' + + # Replace the class name by the alternative class name if available + title.sub! className, displayedClassName if alternativeClassName + + unless titles.include? title # Remove duplicates (function overloading) + entries << [title, header['id']] + titles.push title + end + end + + # QML properties/functions + qmlTypeName = at_css('h1.title').content.sub ' QML Type', '' + css('.qmlproto').each do |node| + title = node.content.strip + id = node.at_css('tr')['id'] + + # Remove options + title.sub! %r{^\[.*\] }, '' + + # Remove function parameters + title.sub! %r{\(.*\)}, '()' + + # Remove property type + title.sub! %r{ : .*$}, '' + + # Remove return type + title.sub! %r{.* }, '' + + # Remove return type + title.sub! %r{.* }, '' + + title = "#{qmlTypeName}.#{title.strip}" + unless titles.include? title # Remove duplicates (function overloading) + entries << [title, id] + titles.push title + end + end + + entries + end + end + end +end diff --git a/lib/docs/scrapers/qt.rb b/lib/docs/scrapers/qt.rb new file mode 100644 index 00000000..c4ff2db9 --- /dev/null +++ b/lib/docs/scrapers/qt.rb @@ -0,0 +1,121 @@ +module Docs + class Qt < UrlScraper + self.name = 'Qt' + self.type = 'qt' + self.initial_paths = %w(classes.html qmltypes.html) + self.root_path = 'index.html' + self.links = { + home: 'https://www.qt.io', + code: 'https://code.qt.io/cgit/' + } + + html_filters.push 'qt/entries', 'qt/clean_html' + + options[:container] = '.main' + + options[:skip_patterns] = [ + # License, copyright attributions + /3rdparty/, + /attribution/, + /license/, + /licensing/, + + # Examples, guides, tutorials + /example/, + /guide$/, + /tutorial/, + /porting/, + /usecase/, + /topic/, + /^modelview/, + /deploy(ing|ment)/, + /building/, + + # Old versions, changelog + /obsolete/, + /compatibility/, + /^whatsnew/, + /^newclasses/, + + # Deprecated modules + /(qtopengl|qgl)/, + /qt?script/, + + # Indexes + /members/, + /module/, + /overview/, + /^qopenglfunctions/, + + # Tooling + /^(qt)?(linguist|assistant|qdbusviewer)/, + ] + + options[:skip] = [ + "qt5-intro.html", + "compatmap.html", + + # Indexes + "classes.html", + "qtmodules.html", + "modules-qml.html", + "modules-cpp.html", + "functions.html", + "namespaces.html", + "qmltypes.html", + "qt3d-qml.html", + "qmlbasictypes.html", + "guibooks.html", + "annotated.html", + "overviews-main.html", + "reference-overview.html", + + # Tutorials + "qtvirtualkeyboard-build.html", + + # Copyright + "trademarks.html", + "lgpl.html", + "bughowto.html", + + # Changelogs + "changes.html", + "qtlocation-changes.html", + "sourcebreaks.html", + + # Best practice guides + "accessible.html", + "accessible-qtquick.html", + "sharedlibrary.html", + "exceptionsafety.html", + "scalability.html", + "session.html", + "appicon.html", + "accelerators.html", + + # Other + "ecmascript.html", + "qtremoteobjects-interaction.html", + ] + + options[:attribution] = <<-HTML + © The Qt Company Ltd
+ Licensed under the GNU Free Documentation License, Version 1.3. + HTML + + version '5.11' do + self.release = '5.11' + self.base_url = 'https://doc.qt.io/qt-5/' + end + + version '5.9' do + self.release = '5.9' + self.base_url = 'https://doc.qt.io/qt-5.9/' + end + + version '5.6' do + self.release = '5.6' + self.base_url = 'https://doc.qt.io/qt-5.6/' + end + end +end diff --git a/public/icons/docs/qt/16.png b/public/icons/docs/qt/16.png new file mode 100644 index 00000000..9d601d73 Binary files /dev/null and b/public/icons/docs/qt/16.png differ diff --git a/public/icons/docs/qt/16@2x.png b/public/icons/docs/qt/16@2x.png new file mode 100644 index 00000000..5140eb23 Binary files /dev/null and b/public/icons/docs/qt/16@2x.png differ diff --git a/public/icons/docs/qt/SOURCE b/public/icons/docs/qt/SOURCE new file mode 100644 index 00000000..ff6ed43f --- /dev/null +++ b/public/icons/docs/qt/SOURCE @@ -0,0 +1 @@ +https://commons.wikimedia.org/wiki/File:Qt_logo_2016.svg