From 45766ac9f8cd782b7711bd45846d3ee81925eca3 Mon Sep 17 00:00:00 2001 From: Carsten Teibes Date: Mon, 18 Apr 2022 02:49:44 +0200 Subject: [PATCH 1/2] Add a search option Will be useful later for the (static) blog and wiki based on https://chodounsky.com/2015/05/14/full-text-search-on-static-website/ --- README.md | 3 + Rules | 4 +- content/about/index.md | 2 +- content/about/website.md | 5 +- content/contribute/artists.md | 2 +- content/contribute/index.md | 4 +- content/contribute/programmers.md | 2 +- content/contribute/testers.md | 2 +- content/contribute/translators.md | 2 +- content/css/easyrpg.scss | 47 +++++++++++++++ content/editor/downloads.md | 2 +- content/editor/index.md | 4 +- content/editor/media.md | 2 +- content/editor/progress.md | 2 +- content/index.html | 1 + content/js/search-index.js | 77 ++++++++++++++++++++++++ content/js/vendor/lunr.min.js | 6 ++ content/player/downloads.html | 2 +- content/player/guide.md | 2 +- content/player/guide/game_translation.md | 2 +- content/player/guide/webplayer.md | 2 +- content/player/index.md | 4 +- content/player/media.md | 2 +- content/player/progress.md | 2 +- content/rtp-replacement/downloads.md | 2 +- content/rtp-replacement/index.md | 4 +- content/rtp-replacement/media.md | 2 +- content/rtp-replacement/progress.md | 2 +- content/search/index.html | 13 ++++ content/tools/downloads.md | 2 +- content/tools/index.md | 4 +- content/tools/media.md | 2 +- layouts/default.slim | 4 +- lib/{tidy_filter.rb => filters/tidy.rb} | 0 lib/{helpers.rb => helpers/links.rb} | 0 lib/{ => helpers}/navigation.rb | 9 ++- lib/helpers/searchindex.rb | 66 ++++++++++++++++++++ lib/{ => helpers}/sitemap.rb | 0 lib/helpers_.rb | 1 + 39 files changed, 259 insertions(+), 35 deletions(-) create mode 100644 content/js/search-index.js create mode 100644 content/js/vendor/lunr.min.js create mode 100644 content/search/index.html rename lib/{tidy_filter.rb => filters/tidy.rb} (100%) rename lib/{helpers.rb => helpers/links.rb} (100%) rename lib/{ => helpers}/navigation.rb (89%) create mode 100644 lib/helpers/searchindex.rb rename lib/{ => helpers}/sitemap.rb (100%) create mode 100644 lib/helpers_.rb diff --git a/README.md b/README.md index 2783097..ed6c91c 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,9 @@ Included are the following 3rd party software: * Magnific Popup - http://dimsemenov.com/plugins/magnific-popup/ - Copyright (c) 2014-2016 Dmitry Semenov, provided under the MIT license +* lunr - https://lunrjs.com - Copyright (c) 2013 by Oliver Nightingale, + provided under the MIT license + * Favicons have been processed by https://realfavicongenerator.net * IRC contact page is provided by https://kiwiirc.com diff --git a/Rules b/Rules index 590a7e7..175d452 100644 --- a/Rules +++ b/Rules @@ -17,9 +17,9 @@ compile '/**/*.scss' do write item.identifier.without_ext + '.css' end -compile '/sitemap.xml' do +compile '/{sitemap.xml,js/search-index.js}' do filter :erb - write '/sitemap.xml' + write item.identifier end compile '/htaccess.txt' do diff --git a/content/about/index.md b/content/about/index.md index ef8e394..b4873e5 100644 --- a/content/about/index.md +++ b/content/about/index.md @@ -1,7 +1,7 @@ --- title: About EasyRPG priority: 0.8 -menu_weight: 5 +menu_weight: 10 ---
diff --git a/content/about/website.md b/content/about/website.md index c88cb29..67b62aa 100644 --- a/content/about/website.md +++ b/content/about/website.md @@ -30,7 +30,8 @@ title: About the EasyRPG Homepage - Nanoc static site generator - - kramdown markdown superset converter - -- Sass +- Sass - +- lunr client search engine - ### 3rd party software @@ -40,6 +41,8 @@ Included are the following 3rd party software: contributors, provided under the MIT license - Magnific Popup - \- Copyright © 2014-2016 Dmitry Semenov, provided under the MIT license +- lunr - Copyright © 2013 by Oliver Nightingale, provided under the + MIT license - Favicons have been processed by - IRC contact page is provided by diff --git a/content/contribute/artists.md b/content/contribute/artists.md index 3283d92..f4608fe 100644 --- a/content/contribute/artists.md +++ b/content/contribute/artists.md @@ -1,5 +1,5 @@ --- -title: How to Contribute +title: "How to Contribute: Artists" menu_weight: 3 ---
diff --git a/content/contribute/index.md b/content/contribute/index.md index 5cb1282..c00240a 100644 --- a/content/contribute/index.md +++ b/content/contribute/index.md @@ -1,7 +1,7 @@ --- -title: How to Contribute +title: "How to Contribute: Introduction" priority: 0.8 -menu_weight: 0 +menu_weight: 1 ---
diff --git a/content/contribute/programmers.md b/content/contribute/programmers.md index 506cfdf..668d5ee 100644 --- a/content/contribute/programmers.md +++ b/content/contribute/programmers.md @@ -1,5 +1,5 @@ --- -title: How to Contribute +title: "How to Contribute: Programmers" menu_weight: 4 ---
diff --git a/content/contribute/testers.md b/content/contribute/testers.md index 261000e..9f1b6e2 100644 --- a/content/contribute/testers.md +++ b/content/contribute/testers.md @@ -1,5 +1,5 @@ --- -title: How to Contribute +title: "How to Contribute: Testers" menu_weight: 2 ---
diff --git a/content/contribute/translators.md b/content/contribute/translators.md index f8e39c7..63de3a6 100644 --- a/content/contribute/translators.md +++ b/content/contribute/translators.md @@ -1,5 +1,5 @@ --- -title: How to Contribute +title: "How to Contribute: Translators" menu_weight: 1 ---
diff --git a/content/css/easyrpg.scss b/content/css/easyrpg.scss index 1bdd67a..b4a113d 100644 --- a/content/css/easyrpg.scss +++ b/content/css/easyrpg.scss @@ -245,6 +245,53 @@ $darkgrey: #202020; } } + /* Search box and results */ + form#search-form { + margin: 1em 0; + + input { + border: 2px solid $normalgreen; + margin: 4px 2px; + padding: 10px 12px; + border-radius: 5px; + } + input[type=text] { + border-collapse: collapse; + width: 300px; + } + input[type=submit] { + background-color: $lightgrey; + color: black; + cursor: pointer; + } + } + ul#search-results { + // entry height + $eheight: 32px; + + margin-top: -1px; + margin-bottom: 0; + padding: 0 0.5em; + + li { + display: inline-block; + line-height: $eheight; + vertical-align: middle; + white-space: nowrap; + + a { + display: inline-block; + height: $eheight; + padding: 0 1em; + text-decoration: none; + + &:hover { + color: $normalgreen; + } + } + } + } + /* Footer */ #footer { font-size: 11px; diff --git a/content/editor/downloads.md b/content/editor/downloads.md index 949b29a..8071093 100644 --- a/content/editor/downloads.md +++ b/content/editor/downloads.md @@ -1,5 +1,5 @@ --- -title: EasyRPG Editor +title: "EasyRPG Editor: Downloads" menu_weight: 2 ---
diff --git a/content/editor/index.md b/content/editor/index.md index 6ccdff4..787d6f1 100644 --- a/content/editor/index.md +++ b/content/editor/index.md @@ -1,8 +1,8 @@ --- -title: EasyRPG Editor +title: "EasyRPG Editor: Overview" priority: 0.7 menu_name: EasyRPG Editor -menu_weight: 1 +menu_weight: 6 ---
diff --git a/content/editor/media.md b/content/editor/media.md index 5912826..e652956 100644 --- a/content/editor/media.md +++ b/content/editor/media.md @@ -1,5 +1,5 @@ --- -title: EasyRPG Editor +title: "EasyRPG Editor: Media" menu_weight: 1 ---
diff --git a/content/editor/progress.md b/content/editor/progress.md index acb7f0d..722fbb3 100644 --- a/content/editor/progress.md +++ b/content/editor/progress.md @@ -1,5 +1,5 @@ --- -title: EasyRPG Editor +title: "EasyRPG Editor: Progress" menu_weight: 3 ---
diff --git a/content/index.html b/content/index.html index b96f8ba..f189323 100644 --- a/content/index.html +++ b/content/index.html @@ -1,5 +1,6 @@ --- has_spotlight: true +title: EasyRPG Homepage ---
diff --git a/content/js/search-index.js b/content/js/search-index.js new file mode 100644 index 0000000..582fb81 --- /dev/null +++ b/content/js/search-index.js @@ -0,0 +1,77 @@ +var pages = <%= make_search_index %> + +document.addEventListener("DOMContentLoaded", function(event) { + var input = document.getElementById("search-input") + var form = document.getElementById("search-form") + var resultsContainer = document.getElementById("search-results") + var resultsHeading = document.getElementById("search-heading") + + var searchIndex = lunr(function () { + this.field('title', { boost: 4 }) + this.field('tags', { boost: 2 }) + this.field('body') + this.ref('id') + // add all pages to search + pages.forEach(function(page) { this.add(page) }, this) + }) + + var clearResults = function() { + resultsContainer.innerHTML = "" + resultsHeading.innerHTML = "" + } + + var search = function(query) { + clearResults(); + + // find + results = searchIndex.search(query).map(function(id) { + for (var i = 0; i < pages.length; i++) { + if (pages[i].id === id.ref) + return pages[i] + } + }) + + // render + resultsHeading.innerHTML = results.length + " results found:" + results.forEach(function(result) { + var li = document.createElement("li") + var a = document.createElement("a") + a.href = result.id + a.innerHTML = result.title + li.appendChild(a) + resultsContainer.appendChild(li) + }) + } + + var searchQueryFromUrl = function() { + var q; + location.search.substr(1).split("&").forEach(function(item) { + if (item[0] === "q") + q = decodeURIComponent(item.substring(2)) + }) + return q; + } + + form.addEventListener("submit", function(e) { + var v = input.value + history.pushState({ q: v }, "", "?q=" + encodeURIComponent(v)) + search(v) + e.preventDefault() + }) + + window.onpopstate = function(event) { + if (event.state !== null) { + input.value = event.state.q + search(input.value) + } else { + // clear + input.value = "" + clearResults() + } + } + + if (searchQueryFromUrl() !== undefined) { + input.value = searchQueryFromUrl() + search(input.value) + } +}) diff --git a/content/js/vendor/lunr.min.js b/content/js/vendor/lunr.min.js new file mode 100644 index 0000000..cdc94cd --- /dev/null +++ b/content/js/vendor/lunr.min.js @@ -0,0 +1,6 @@ +/** + * lunr - http://lunrjs.com - A bit like Solr, but much smaller and not as bright - 2.3.9 + * Copyright (C) 2020 Oliver Nightingale + * @license MIT + */ +!function(){var e=function(t){var r=new e.Builder;return r.pipeline.add(e.trimmer,e.stopWordFilter,e.stemmer),r.searchPipeline.add(e.stemmer),t.call(r,r),r.build()};e.version="2.3.9",e.utils={},e.utils.warn=function(e){return function(t){e.console&&console.warn&&console.warn(t)}}(this),e.utils.asString=function(e){return void 0===e||null===e?"":e.toString()},e.utils.clone=function(e){if(null===e||void 0===e)return e;for(var t=Object.create(null),r=Object.keys(e),i=0;i0){var c=e.utils.clone(r)||{};c.position=[a,l],c.index=s.length,s.push(new e.Token(i.slice(a,o),c))}a=o+1}}return s},e.tokenizer.separator=/[\s\-]+/,e.Pipeline=function(){this._stack=[]},e.Pipeline.registeredFunctions=Object.create(null),e.Pipeline.registerFunction=function(t,r){r in this.registeredFunctions&&e.utils.warn("Overwriting existing registered function: "+r),t.label=r,e.Pipeline.registeredFunctions[t.label]=t},e.Pipeline.warnIfFunctionNotRegistered=function(t){var r=t.label&&t.label in this.registeredFunctions;r||e.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",t)},e.Pipeline.load=function(t){var r=new e.Pipeline;return t.forEach(function(t){var i=e.Pipeline.registeredFunctions[t];if(!i)throw new Error("Cannot load unregistered function: "+t);r.add(i)}),r},e.Pipeline.prototype.add=function(){var t=Array.prototype.slice.call(arguments);t.forEach(function(t){e.Pipeline.warnIfFunctionNotRegistered(t),this._stack.push(t)},this)},e.Pipeline.prototype.after=function(t,r){e.Pipeline.warnIfFunctionNotRegistered(r);var i=this._stack.indexOf(t);if(i==-1)throw new Error("Cannot find existingFn");i+=1,this._stack.splice(i,0,r)},e.Pipeline.prototype.before=function(t,r){e.Pipeline.warnIfFunctionNotRegistered(r);var i=this._stack.indexOf(t);if(i==-1)throw new Error("Cannot find existingFn");this._stack.splice(i,0,r)},e.Pipeline.prototype.remove=function(e){var t=this._stack.indexOf(e);t!=-1&&this._stack.splice(t,1)},e.Pipeline.prototype.run=function(e){for(var t=this._stack.length,r=0;r1&&(se&&(r=n),s!=e);)i=r-t,n=t+Math.floor(i/2),s=this.elements[2*n];return s==e?2*n:s>e?2*n:sa?l+=2:o==a&&(t+=r[u+1]*i[l+1],u+=2,l+=2);return t},e.Vector.prototype.similarity=function(e){return this.dot(e)/this.magnitude()||0},e.Vector.prototype.toArray=function(){for(var e=new Array(this.elements.length/2),t=1,r=0;t0){var o,a=s.str.charAt(0);a in s.node.edges?o=s.node.edges[a]:(o=new e.TokenSet,s.node.edges[a]=o),1==s.str.length&&(o["final"]=!0),n.push({node:o,editsRemaining:s.editsRemaining,str:s.str.slice(1)})}if(0!=s.editsRemaining){if("*"in s.node.edges)var u=s.node.edges["*"];else{var u=new e.TokenSet;s.node.edges["*"]=u}if(0==s.str.length&&(u["final"]=!0),n.push({node:u,editsRemaining:s.editsRemaining-1,str:s.str}),s.str.length>1&&n.push({node:s.node,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)}),1==s.str.length&&(s.node["final"]=!0),s.str.length>=1){if("*"in s.node.edges)var l=s.node.edges["*"];else{var l=new e.TokenSet;s.node.edges["*"]=l}1==s.str.length&&(l["final"]=!0),n.push({node:l,editsRemaining:s.editsRemaining-1,str:s.str.slice(1)})}if(s.str.length>1){var c,h=s.str.charAt(0),d=s.str.charAt(1);d in s.node.edges?c=s.node.edges[d]:(c=new e.TokenSet,s.node.edges[d]=c),1==s.str.length&&(c["final"]=!0),n.push({node:c,editsRemaining:s.editsRemaining-1,str:h+s.str.slice(2)})}}}return i},e.TokenSet.fromString=function(t){for(var r=new e.TokenSet,i=r,n=0,s=t.length;n=e;t--){var r=this.uncheckedNodes[t],i=r.child.toString();i in this.minimizedNodes?r.parent.edges[r["char"]]=this.minimizedNodes[i]:(r.child._str=i,this.minimizedNodes[i]=r.child),this.uncheckedNodes.pop()}},e.Index=function(e){this.invertedIndex=e.invertedIndex,this.fieldVectors=e.fieldVectors,this.tokenSet=e.tokenSet,this.fields=e.fields,this.pipeline=e.pipeline},e.Index.prototype.search=function(t){return this.query(function(r){var i=new e.QueryParser(t,r);i.parse()})},e.Index.prototype.query=function(t){for(var r=new e.Query(this.fields),i=Object.create(null),n=Object.create(null),s=Object.create(null),o=Object.create(null),a=Object.create(null),u=0;u1?this._b=1:this._b=e},e.Builder.prototype.k1=function(e){this._k1=e},e.Builder.prototype.add=function(t,r){var i=t[this._ref],n=Object.keys(this._fields);this._documents[i]=r||{},this.documentCount+=1;for(var s=0;s=this.length)return e.QueryLexer.EOS;var t=this.str.charAt(this.pos);return this.pos+=1,t},e.QueryLexer.prototype.width=function(){return this.pos-this.start},e.QueryLexer.prototype.ignore=function(){this.start==this.pos&&(this.pos+=1),this.start=this.pos},e.QueryLexer.prototype.backup=function(){this.pos-=1},e.QueryLexer.prototype.acceptDigitRun=function(){var t,r;do t=this.next(),r=t.charCodeAt(0);while(r>47&&r<58);t!=e.QueryLexer.EOS&&this.backup()},e.QueryLexer.prototype.more=function(){return this.pos1&&(t.backup(),t.emit(e.QueryLexer.TERM)),t.ignore(),t.more())return e.QueryLexer.lexText},e.QueryLexer.lexEditDistance=function(t){return t.ignore(),t.acceptDigitRun(),t.emit(e.QueryLexer.EDIT_DISTANCE),e.QueryLexer.lexText},e.QueryLexer.lexBoost=function(t){return t.ignore(),t.acceptDigitRun(),t.emit(e.QueryLexer.BOOST),e.QueryLexer.lexText},e.QueryLexer.lexEOS=function(t){t.width()>0&&t.emit(e.QueryLexer.TERM)},e.QueryLexer.termSeparator=e.tokenizer.separator,e.QueryLexer.lexText=function(t){for(;;){var r=t.next();if(r==e.QueryLexer.EOS)return e.QueryLexer.lexEOS;if(92!=r.charCodeAt(0)){if(":"==r)return e.QueryLexer.lexField;if("~"==r)return t.backup(),t.width()>0&&t.emit(e.QueryLexer.TERM),e.QueryLexer.lexEditDistance;if("^"==r)return t.backup(),t.width()>0&&t.emit(e.QueryLexer.TERM),e.QueryLexer.lexBoost;if("+"==r&&1===t.width())return t.emit(e.QueryLexer.PRESENCE),e.QueryLexer.lexText;if("-"==r&&1===t.width())return t.emit(e.QueryLexer.PRESENCE),e.QueryLexer.lexText;if(r.match(e.QueryLexer.termSeparator))return e.QueryLexer.lexTerm}else t.escapeCharacter()}},e.QueryParser=function(t,r){this.lexer=new e.QueryLexer(t),this.query=r,this.currentClause={},this.lexemeIdx=0},e.QueryParser.prototype.parse=function(){this.lexer.run(),this.lexemes=this.lexer.lexemes;for(var t=e.QueryParser.parseClause;t;)t=t(this);return this.query},e.QueryParser.prototype.peekLexeme=function(){return this.lexemes[this.lexemeIdx]},e.QueryParser.prototype.consumeLexeme=function(){var e=this.peekLexeme();return this.lexemeIdx+=1,e},e.QueryParser.prototype.nextClause=function(){var e=this.currentClause;this.query.clause(e),this.currentClause={}},e.QueryParser.parseClause=function(t){var r=t.peekLexeme();if(void 0!=r)switch(r.type){case e.QueryLexer.PRESENCE:return e.QueryParser.parsePresence;case e.QueryLexer.FIELD:return e.QueryParser.parseField;case e.QueryLexer.TERM:return e.QueryParser.parseTerm;default:var i="expected either a field or a term, found "+r.type;throw r.str.length>=1&&(i+=" with value '"+r.str+"'"),new e.QueryParseError(i,r.start,r.end)}},e.QueryParser.parsePresence=function(t){var r=t.consumeLexeme();if(void 0!=r){switch(r.str){case"-":t.currentClause.presence=e.Query.presence.PROHIBITED;break;case"+":t.currentClause.presence=e.Query.presence.REQUIRED;break;default:var i="unrecognised presence operator'"+r.str+"'";throw new e.QueryParseError(i,r.start,r.end)}var n=t.peekLexeme();if(void 0==n){var i="expecting term or field, found nothing";throw new e.QueryParseError(i,r.start,r.end)}switch(n.type){case e.QueryLexer.FIELD:return e.QueryParser.parseField;case e.QueryLexer.TERM:return e.QueryParser.parseTerm;default:var i="expecting term or field, found '"+n.type+"'";throw new e.QueryParseError(i,n.start,n.end)}}},e.QueryParser.parseField=function(t){var r=t.consumeLexeme();if(void 0!=r){if(t.query.allFields.indexOf(r.str)==-1){var i=t.query.allFields.map(function(e){return"'"+e+"'"}).join(", "),n="unrecognised field '"+r.str+"', possible fields: "+i;throw new e.QueryParseError(n,r.start,r.end)}t.currentClause.fields=[r.str];var s=t.peekLexeme();if(void 0==s){var n="expecting term, found nothing";throw new e.QueryParseError(n,r.start,r.end)}switch(s.type){case e.QueryLexer.TERM:return e.QueryParser.parseTerm;default:var n="expecting term, found '"+s.type+"'";throw new e.QueryParseError(n,s.start,s.end)}}},e.QueryParser.parseTerm=function(t){var r=t.consumeLexeme();if(void 0!=r){t.currentClause.term=r.str.toLowerCase(),r.str.indexOf("*")!=-1&&(t.currentClause.usePipeline=!1);var i=t.peekLexeme();if(void 0==i)return void t.nextClause();switch(i.type){case e.QueryLexer.TERM:return t.nextClause(),e.QueryParser.parseTerm;case e.QueryLexer.FIELD:return t.nextClause(),e.QueryParser.parseField;case e.QueryLexer.EDIT_DISTANCE:return e.QueryParser.parseEditDistance;case e.QueryLexer.BOOST:return e.QueryParser.parseBoost;case e.QueryLexer.PRESENCE:return t.nextClause(),e.QueryParser.parsePresence;default:var n="Unexpected lexeme type '"+i.type+"'";throw new e.QueryParseError(n,i.start,i.end)}}},e.QueryParser.parseEditDistance=function(t){var r=t.consumeLexeme();if(void 0!=r){var i=parseInt(r.str,10);if(isNaN(i)){var n="edit distance must be numeric";throw new e.QueryParseError(n,r.start,r.end)}t.currentClause.editDistance=i;var s=t.peekLexeme();if(void 0==s)return void t.nextClause();switch(s.type){case e.QueryLexer.TERM:return t.nextClause(),e.QueryParser.parseTerm;case e.QueryLexer.FIELD:return t.nextClause(),e.QueryParser.parseField;case e.QueryLexer.EDIT_DISTANCE:return e.QueryParser.parseEditDistance;case e.QueryLexer.BOOST:return e.QueryParser.parseBoost;case e.QueryLexer.PRESENCE:return t.nextClause(),e.QueryParser.parsePresence;default:var n="Unexpected lexeme type '"+s.type+"'";throw new e.QueryParseError(n,s.start,s.end)}}},e.QueryParser.parseBoost=function(t){var r=t.consumeLexeme();if(void 0!=r){var i=parseInt(r.str,10);if(isNaN(i)){var n="boost must be numeric";throw new e.QueryParseError(n,r.start,r.end)}t.currentClause.boost=i;var s=t.peekLexeme();if(void 0==s)return void t.nextClause();switch(s.type){case e.QueryLexer.TERM:return t.nextClause(),e.QueryParser.parseTerm;case e.QueryLexer.FIELD:return t.nextClause(),e.QueryParser.parseField;case e.QueryLexer.EDIT_DISTANCE:return e.QueryParser.parseEditDistance;case e.QueryLexer.BOOST:return e.QueryParser.parseBoost;case e.QueryLexer.PRESENCE:return t.nextClause(),e.QueryParser.parsePresence;default:var n="Unexpected lexeme type '"+s.type+"'";throw new e.QueryParseError(n,s.start,s.end)}}},function(e,t){"function"==typeof define&&define.amd?define(t):"object"==typeof exports?module.exports=t():e.lunr=t()}(this,function(){return e})}(); diff --git a/content/player/downloads.html b/content/player/downloads.html index 754d0a4..e4c0795 100644 --- a/content/player/downloads.html +++ b/content/player/downloads.html @@ -1,5 +1,5 @@ --- -title: EasyRPG Player +title: "EasyRPG Player: Downloads" menu_weight: 3 --- <% # The following variables can be quite handy ;) diff --git a/content/player/guide.md b/content/player/guide.md index bd6ed0e..5c187a7 100644 --- a/content/player/guide.md +++ b/content/player/guide.md @@ -1,5 +1,5 @@ --- -title: "EasyRPG Player" +title: "EasyRPG Player: Guide" menu_weight: 1 ---
diff --git a/content/player/guide/game_translation.md b/content/player/guide/game_translation.md index 510e6ea..f94acf9 100644 --- a/content/player/guide/game_translation.md +++ b/content/player/guide/game_translation.md @@ -1,5 +1,5 @@ --- -title: "EasyRPG Player" +title: "EasyRPG Player: Guide game translation" ---
diff --git a/content/player/guide/webplayer.md b/content/player/guide/webplayer.md index e99e4ab..e12df1f 100644 --- a/content/player/guide/webplayer.md +++ b/content/player/guide/webplayer.md @@ -1,5 +1,5 @@ --- -title: "EasyRPG Player" +title: "EasyRPG Player: Guide webplayer" ---
diff --git a/content/player/index.md b/content/player/index.md index 11f7c04..8f6ce8f 100644 --- a/content/player/index.md +++ b/content/player/index.md @@ -1,8 +1,8 @@ --- -title: EasyRPG Player +title: "EasyRPG Player: Overview" priority: 0.7 menu_name: EasyRPG Player -menu_weight: 4 +menu_weight: 8 ---
diff --git a/content/player/media.md b/content/player/media.md index d8ccf10..310066c 100644 --- a/content/player/media.md +++ b/content/player/media.md @@ -1,5 +1,5 @@ --- -title: EasyRPG Player +title: "EasyRPG Player: Media" menu_weight: 2 ---
diff --git a/content/player/progress.md b/content/player/progress.md index c8af51c..66bc822 100644 --- a/content/player/progress.md +++ b/content/player/progress.md @@ -1,5 +1,5 @@ --- -title: EasyRPG Player +title: "EasyRPG Player: Progress" menu_weight: 4 ---
diff --git a/content/rtp-replacement/downloads.md b/content/rtp-replacement/downloads.md index 8272c8d..9a10682 100644 --- a/content/rtp-replacement/downloads.md +++ b/content/rtp-replacement/downloads.md @@ -1,5 +1,5 @@ --- -title: RTP Replacement +title: "RTP Replacement: Downloads" menu_weight: 2 ---
diff --git a/content/rtp-replacement/index.md b/content/rtp-replacement/index.md index 344eb58..8e05f18 100644 --- a/content/rtp-replacement/index.md +++ b/content/rtp-replacement/index.md @@ -1,8 +1,8 @@ --- -title: RTP Replacement +title: "RTP Replacement: Overview" priority: 0.7 menu_name: RTP Replacement -menu_weight: 3 +menu_weight: 4 ---
diff --git a/content/rtp-replacement/media.md b/content/rtp-replacement/media.md index ad5874f..f8d5266 100644 --- a/content/rtp-replacement/media.md +++ b/content/rtp-replacement/media.md @@ -1,5 +1,5 @@ --- -title: RTP Replacement +title: "RTP Replacement: Media" menu_weight: 1 ---
diff --git a/content/rtp-replacement/progress.md b/content/rtp-replacement/progress.md index 884271b..4ab8240 100644 --- a/content/rtp-replacement/progress.md +++ b/content/rtp-replacement/progress.md @@ -1,5 +1,5 @@ --- -title: RTP Replacement +title: "RTP Replacement: Progress" menu_weight: 3 ---
diff --git a/content/search/index.html b/content/search/index.html new file mode 100644 index 0000000..2c91a20 --- /dev/null +++ b/content/search/index.html @@ -0,0 +1,13 @@ +--- +title: Search on this site +menu_name: 🔍 Site search +menu_weight: -1 +--- + +

+
    + + \ No newline at end of file diff --git a/content/tools/downloads.md b/content/tools/downloads.md index 93b833b..14e608c 100644 --- a/content/tools/downloads.md +++ b/content/tools/downloads.md @@ -1,5 +1,5 @@ --- -title: EasyRPG Tools +title: "EasyRPG Tools: Downloads" menu_weight: 2 ---
    diff --git a/content/tools/index.md b/content/tools/index.md index 193a9ff..0f12bf5 100644 --- a/content/tools/index.md +++ b/content/tools/index.md @@ -1,7 +1,7 @@ --- -title: EasyRPG Tools +title: "EasyRPG Tools: Overview" priority: 0.7 -menu_weight: 2 +menu_weight: 3 ---
    diff --git a/content/tools/media.md b/content/tools/media.md index c9e5143..dfc166a 100644 --- a/content/tools/media.md +++ b/content/tools/media.md @@ -1,5 +1,5 @@ --- -title: EasyRPG Tools +title: "EasyRPG Tools: Media" menu_weight: 1 ---
    diff --git a/layouts/default.slim b/layouts/default.slim index 887c33f..d568b05 100644 --- a/layouts/default.slim +++ b/layouts/default.slim @@ -3,7 +3,7 @@ html lang="en" head meta charset="utf-8" - if @item[:title] - title EasyRPG: #{@item[:title]} + title = @item[:title] - else title EasyRPG meta name="generator" content="Nanoc #{Nanoc::VERSION}" @@ -37,7 +37,7 @@ html lang="en" #spotlight .maxwidth #section-title - h1 = @item[:title] + h1 = @item[:title].split(":")[0] .clear #content .maxwidth diff --git a/lib/tidy_filter.rb b/lib/filters/tidy.rb similarity index 100% rename from lib/tidy_filter.rb rename to lib/filters/tidy.rb diff --git a/lib/helpers.rb b/lib/helpers/links.rb similarity index 100% rename from lib/helpers.rb rename to lib/helpers/links.rb diff --git a/lib/navigation.rb b/lib/helpers/navigation.rb similarity index 89% rename from lib/navigation.rb rename to lib/helpers/navigation.rb index f8fadfa..b6fda2e 100644 --- a/lib/navigation.rb +++ b/lib/helpers/navigation.rb @@ -55,7 +55,14 @@ def navigation_for(item) # special case subsection index if subsection == "index" - menu_name = "Overview" + case section + when "/search/" + menu_name = "🔍 Site search" + when "/contribute/" + menu_name = "Introduction" + else + menu_name = "Overview" + end link = section menu_weight = 100 end diff --git a/lib/helpers/searchindex.rb b/lib/helpers/searchindex.rb new file mode 100644 index 0000000..7aafa05 --- /dev/null +++ b/lib/helpers/searchindex.rb @@ -0,0 +1,66 @@ +require 'json' + +module CreateSearchIndex + COMMON_WORDS = %w{ a able about across after all almost also am among an and + any are as at be because been but by can cannot could dear did do does + either else ever every for from get got had has have he her hers him his + how however i if in into is it its just least let like likely may me might + most must my neither no nor not of off often on only or other our own + rather said say says she should since so some than that the their them then + there these they this tis to too twas us wants was we were what when where + which while who whom why will with would yet you your' } + EASYRPG_SPECIALS = %w{ div class info markdown } + + def make_search_index + a = Array.new + + @items.each do |item| + next if item.binary? + next if item[:is_hidden] + next unless ["html", "md"].include? item.identifier.ext + + words = item.raw_content.downcase.split(/\W+/) + keywords = words.uniq - COMMON_WORDS - EASYRPG_SPECIALS + a << { + id: item.path, + title: item[:title], + tags: item[:tags] ? item[:tags].join(" ") : "", + body: keywords.join(" ") + } + end + + # add some static items for content not managed by nanoc + a << { + id: "/player/manual/", + title: "Player manual page", + tags: "player manual linux", + body: "command line options environment variables" + } + a << { + id: "/player/doxydoc/", + title: "Player source documentation", + tags: "player doxygen source", + body: "doxygen lcf struct scenes engine" + } + a << { + id: "https://blog.easyrpg.org", + title: "Blog", + tags: "player editor", + body: "" + } + a << { + id: "https://wiki.easyrpg.org", + title: "Wiki", + tags: "player wiki dokuwiki documentation", + body: "users" + } + a << { + id: "https://community.easyrpg.org", + title: "Community", + tags: "forums discourse communication", + body: "users" + } + + JSON.pretty_generate(a) + end +end diff --git a/lib/sitemap.rb b/lib/helpers/sitemap.rb similarity index 100% rename from lib/sitemap.rb rename to lib/helpers/sitemap.rb diff --git a/lib/helpers_.rb b/lib/helpers_.rb new file mode 100644 index 0000000..172eaf4 --- /dev/null +++ b/lib/helpers_.rb @@ -0,0 +1 @@ +use_helper CreateSearchIndex From 3758138bcf970f892cfa79cda5b9ffb54489fc5e Mon Sep 17 00:00:00 2001 From: Carsten Teibes Date: Tue, 19 Apr 2022 01:23:07 +0200 Subject: [PATCH 2/2] Add search overlay --- content/css/easyrpg.scss | 81 ++++++++++++++++++++++++++++++++++++--- content/js/search.js | 28 ++++++++++++++ content/search/index.html | 7 +--- layouts/default.slim | 1 + layouts/menu.html | 11 ++++++ layouts/searchform.html | 4 ++ lib/helpers/navigation.rb | 17 ++------ lib/helpers_.rb | 2 + 8 files changed, 125 insertions(+), 26 deletions(-) create mode 100644 content/js/search.js create mode 100644 layouts/searchform.html diff --git a/content/css/easyrpg.scss b/content/css/easyrpg.scss index b4a113d..585e0ae 100644 --- a/content/css/easyrpg.scss +++ b/content/css/easyrpg.scss @@ -246,25 +246,94 @@ $darkgrey: #202020; } /* Search box and results */ - form#search-form { - margin: 1em 0; - input { + form.search, #search-overlay { + input, button { border: 2px solid $normalgreen; - margin: 4px 2px; + margin: 4px 0 2px; padding: 10px 12px; border-radius: 5px; } + input[type=text] { border-collapse: collapse; - width: 300px; + width: 400px; } - input[type=submit] { + + button { background-color: $lightgrey; color: black; cursor: pointer; } } + + form.search { + margin: 1em 0; + } + + #show-search { + display: inline-block; + background-color: $darkgrey; + color: $lightgrey; + border: none; + height: 40px; + padding: 0 1em; + font-size: 1em; + cursor: pointer; + opacity: 0.8; + &:hover { + opacity: 1; + } + } + + #search-overlay { + height: 100%; + width: 100%; + position: fixed; + z-index: 2; + top: 0; + left: 0; + background-color: rgba(40, 40, 40, 0.8); + transition: opacity 0.5s ease-in-out; + + &.visible { + visibility: visible; + opacity: 1; + } + + &.hidden { + position: absolute; + visibility: hidden; + opacity: 0; + } + + &.transitioning { + visibility: visible; + } + + #search-bar { + position: relative; + top: 46%; + width: 80%; + text-align: center; + margin: auto; + } + + #hide-search { + position: absolute; + top: 20px; + right: 20px; + opacity: 0.8; + &:hover { + opacity: 1; + } + } + + input, button { + font-size: 2em; + } + } + ul#search-results { // entry height $eheight: 32px; diff --git a/content/js/search.js b/content/js/search.js new file mode 100644 index 0000000..e2d5752 --- /dev/null +++ b/content/js/search.js @@ -0,0 +1,28 @@ +/* + * Adds a toggle-able search overlay + */ +document.addEventListener("DOMContentLoaded", function(event) { + // ignore on search page + if (window.location.href.indexOf("/search/") === -1) { + var overlay = document.getElementById('search-overlay') + var input = document.getElementById("search-input") + + function searchBox(e) { + if (e.target.id === "show-search") { + overlay.className = "visible transitioning" + input.focus(); + } else { + overlay.className = "hidden transitioning" + } + } + + document.getElementById('show-search').addEventListener('click', searchBox) + document.getElementById('hide-search').addEventListener('click', searchBox) + input.addEventListener('keyup', function(e) { + if (e.keyCode == 27) searchBox(e) + }) + overlay.addEventListener('transitionend', function() { + overlay.classList.remove("transitioning") + }) + } +}) diff --git a/content/search/index.html b/content/search/index.html index 2c91a20..0b97a9d 100644 --- a/content/search/index.html +++ b/content/search/index.html @@ -1,12 +1,7 @@ --- title: Search on this site -menu_name: 🔍 Site search -menu_weight: -1 --- - +<%= render '/searchform.*' %>

      diff --git a/layouts/default.slim b/layouts/default.slim index d568b05..21d6239 100644 --- a/layouts/default.slim +++ b/layouts/default.slim @@ -20,6 +20,7 @@ html lang="en" link rel="stylesheet" href="/css/easyrpg.css" link rel="stylesheet" href="/css/rouge-github-dark.css" script src="/js/vendor/jquery-2.2.4.min.js" + script src="/js/search.js" body #header .maxwidth diff --git a/layouts/menu.html b/layouts/menu.html index a24f89a..fc884f2 100644 --- a/layouts/menu.html +++ b/layouts/menu.html @@ -4,5 +4,16 @@ <% navigation_for(@item).each do |index, target| %>
    • <%= link_to_unless_current(target[:text], target[:link]) %>
    • <% end %> + <% if @item.identifier.components[0] != "search" %> +
    • + <% end %> + <% if @item.identifier.components[0] != "search" %> + + <% end %> <% end %> diff --git a/layouts/searchform.html b/layouts/searchform.html new file mode 100644 index 0000000..0ca5f72 --- /dev/null +++ b/layouts/searchform.html @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/lib/helpers/navigation.rb b/lib/helpers/navigation.rb index b6fda2e..7c8c3fa 100644 --- a/lib/helpers/navigation.rb +++ b/lib/helpers/navigation.rb @@ -1,9 +1,4 @@ -# allow partial layouts (menu/submenu) -include Nanoc::Helpers::Rendering -# generate links to specific items -include Nanoc::Helpers::LinkTo - def link_to_upper_page(attributes = {}) p = @item_rep.path @@ -45,7 +40,8 @@ def navigation_for(item) next if not it.identifier.to_s.end_with?(".html", ".md") next if it[:is_hidden] # e.g. 404 next if it[:no_menu] # e.g. contact - next if it.identifier.to_s == "/index.html" # homepage + next if it.identifier =~ "/index.*" # homepage + next if it.identifier =~ '/search/*' # search # defaults subsection = it.identifier.components[part].split(".")[0] @@ -55,14 +51,7 @@ def navigation_for(item) # special case subsection index if subsection == "index" - case section - when "/search/" - menu_name = "🔍 Site search" - when "/contribute/" - menu_name = "Introduction" - else - menu_name = "Overview" - end + menu_name = it[:title].include?(":") ? it[:title].split(":")[1].strip : "Start" link = section menu_weight = 100 end diff --git a/lib/helpers_.rb b/lib/helpers_.rb index 172eaf4..ecca3ab 100644 --- a/lib/helpers_.rb +++ b/lib/helpers_.rb @@ -1 +1,3 @@ use_helper CreateSearchIndex +use_helper Nanoc::Helpers::Rendering +use_helper Nanoc::Helpers::LinkTo