From ba1850a294cf223fe55a0a9c797686f329c093a7 Mon Sep 17 00:00:00 2001 From: Erik Osterman Date: Sun, 6 May 2018 01:30:07 -0700 Subject: [PATCH] Implement glossary (#13) * Implement glossary * use proper datatype for term * more glossary work * define cloudposse * use term in sentence --- .editorconfig | 6 + Makefile | 3 +- config.toml | 6 + content/glossary/_index.md | 9 + content/glossary/aws.md | 12 + content/glossary/cloudposse.md | 12 + content/glossary/infrastructure.md | 8 + layouts/_default/list.glossary.json | 5 + static/.gitignore | 0 static/js/custom.js | 2 +- static/js/glossary.json | 42 ---- static/js/jquery.glossarize.js | 332 +++++++++++++++++----------- 12 files changed, 270 insertions(+), 167 deletions(-) create mode 100644 content/glossary/_index.md create mode 100644 content/glossary/aws.md create mode 100644 content/glossary/cloudposse.md create mode 100644 content/glossary/infrastructure.md create mode 100644 layouts/_default/list.glossary.json delete mode 100644 static/.gitignore delete mode 100644 static/js/glossary.json diff --git a/.editorconfig b/.editorconfig index 9518dad0c..22b7907fa 100644 --- a/.editorconfig +++ b/.editorconfig @@ -11,4 +11,10 @@ indent_size = 4 indent_style = space indent_size = 2 +[*.js] +indent_style = space +indent_size = 2 + + + diff --git a/Makefile b/Makefile index 96cc358db..48a220e06 100644 --- a/Makefile +++ b/Makefile @@ -17,4 +17,5 @@ run: ## Generate all static content (outputs to public/) build: - @$(HUGO) + rm -rf public/ + $(HUGO) diff --git a/config.toml b/config.toml index c7fac8e4b..c447a1416 100644 --- a/config.toml +++ b/config.toml @@ -33,6 +33,12 @@ highlightClientSide = false # set true to use highlight.pack.js instead of the d menushortcutsnewtab = false # set true to open shortcuts links to a new tab/window enableGitInfo = true +[outputFormats.glossary] +baseName = "glossary" +isPlainText = true +mediaType = "application/json" +notAlternative = true + [outputs] home = [ "HTML", "RSS", "JSON"] diff --git a/content/glossary/_index.md b/content/glossary/_index.md new file mode 100644 index 000000000..7f7de6961 --- /dev/null +++ b/content/glossary/_index.md @@ -0,0 +1,9 @@ +--- +title: "Glossary" +slug: glossary +excerpt: "Glossary of definitions" +outputs: +- HTML +- RSS +- glossary +--- diff --git a/content/glossary/aws.md b/content/glossary/aws.md new file mode 100644 index 000000000..71236b2d6 --- /dev/null +++ b/content/glossary/aws.md @@ -0,0 +1,12 @@ +--- +title: AWS +terms: +- "Amazon Web Services" +- "AWS" +- "aws cli" +- "awscli" +- "aws-cli" +excerpt: "Amazon Web Services" +--- +Amazon Web Services is a public cloud offering from Amazon. It's also a command line tool (`aws`) use to control services running on the platform. + diff --git a/content/glossary/cloudposse.md b/content/glossary/cloudposse.md new file mode 100644 index 000000000..85331facc --- /dev/null +++ b/content/glossary/cloudposse.md @@ -0,0 +1,12 @@ +--- +title: Cloud Posse, LLC +terms: +- "cloudposse" +- "cloud posse" +- "cloud posse llc" +- "cloud posse, llc" +- "cloudposse, llc" +- "!cloudposse.com" +excerpt: "Cloud Posse is a DevOps professional services company" +--- +Cloud Posse is a DevOps professional services company. Let us know how we can help. Reach us at . diff --git a/content/glossary/infrastructure.md b/content/glossary/infrastructure.md new file mode 100644 index 000000000..1117a3f6b --- /dev/null +++ b/content/glossary/infrastructure.md @@ -0,0 +1,8 @@ +--- +title: Infrastructure +terms: +- infrastructure +- !AWS Infrastructure +excerpt: "Infrastructure is everything that supports running your software" +--- +Infrastructure is everything that supports running your software. diff --git a/layouts/_default/list.glossary.json b/layouts/_default/list.glossary.json new file mode 100644 index 000000000..ffc4c82a9 --- /dev/null +++ b/layouts/_default/list.glossary.json @@ -0,0 +1,5 @@ +{{- $.Scratch.Add "glossary" slice -}} +{{ range $index, $element := .Data.Pages }} + {{- $.Scratch.Add "glossary" (dict "term" (delimit $element.Params.terms ", ") "description" ($element.Content|markdownify)) -}} +{{ end }} +{{- $.Scratch.Get "glossary" | jsonify -}} diff --git a/static/.gitignore b/static/.gitignore deleted file mode 100644 index e69de29bb..000000000 diff --git a/static/js/custom.js b/static/js/custom.js index 3db50958c..a5242965c 100644 --- a/static/js/custom.js +++ b/static/js/custom.js @@ -1,6 +1,6 @@ $(function(){ $('.page').glossarizer({ - sourceURL: '/js/glossary.json', + sourceURL: '/glossary.json', callback: function(){ // Callback fired after glossarizer finishes its job new tooltip(); diff --git a/static/js/glossary.json b/static/js/glossary.json deleted file mode 100644 index 81047159a..000000000 --- a/static/js/glossary.json +++ /dev/null @@ -1,42 +0,0 @@ -[ - { - "term" : "infrastructure", - "description" : "A living being, especially an animal" - }, - { - "term" : "death, !death star", - "description" : "A living being, especially an animal" - }, - { - "term": "genetic, hereditary, !genetic testing", - "description": "relating to genes or heredity: genetic abnormalities." - }, - { - "term": "treatment, !evidence based treatment", - "description": "the manner in which someone behaves towards or deals with someone or something: the directive required equal treatment for men and women in social security schemes." - }, - { - "term" : "creature, !creature kind", - "description" : "A living being, especially an animal" - }, - { - "term" : "Power of Attorney (POA)", - "description" : "A Lasting Power of Attorney (\"LPA\") is a legal document which allows a person who is at least 21 years of age ('donor'), to voluntarily appoint one or more persons ('donee(s)'), to make decisions and act on his behalf as his proxy decision maker if he should lose mental capacity one day. A donee(s) can be appointed to act in two broad areas: personal welfare as well as property & affairs matters." - }, - { - "term" : "replenish", - "description" : "To fill or make complete again; add a new stock or supply to" - }, - { - "term" : "whales", - "description" : "An inlet of the Ross Sea in the Ross Ice Shelf of Antarctica. It has been used as a base for Antarctic expeditions since 1911." - }, - { - "term" : "winged", - "description" : "Having wings or winglike appendages." - }, - { - "term" : "midst", - "description" : "The condition of being surrounded or beset by something" - } -] diff --git a/static/js/jquery.glossarize.js b/static/js/jquery.glossarize.js index 670549aee..76f06ed5e 100644 --- a/static/js/jquery.glossarize.js +++ b/static/js/jquery.glossarize.js @@ -6,45 +6,31 @@ * 1. Fixed IE8 bug where whitespace get removed - Had to change `abbr` tag to a block element `div` */ -// Expose plugin as an AMD module if AMD loader is present: -(function (factory) { - "use strict"; - if (typeof define === 'function' && define.amd) { - // AMD. Register as an anonymous module. - define(['jquery'], factory); - } else if (typeof exports === 'object' && typeof require === 'function') { - // Browserify - factory(require('jquery')); - } else { - // Browser globals - factory(jQuery); - } -}(function ($) { - 'use strict'; +;(function($){ + /** * Defaults */ var pluginName = 'glossarizer', defaults = { - sourceURL: '', /* URL of the JSON file with format {"term": "", "description": ""} */ - replaceTag: 'abbr', /* Matching words will be wrapped with abbr tags by default */ - lookupTagName: 'p, ul, a, div', /* Lookup in either paragraphs or lists. Do not replace in headings */ - callback: null, /* Callback once all tags are replaced: Call or tooltip or anything you like */ - replaceOnce: false, /* Replace only once in a TextNode */ - replaceClass: 'glossarizer_replaced', - caseSensitive: false, - exactMatch: false - } + sourceURL : '', /* URL of the JSON file with format {"term": "", "description": ""} */ + replaceTag : 'abbr', /* Matching words will be wrapped with abbr tags by default */ + lookupTagName : 'p, ul, a, div', /* Lookup in either paragraphs or lists. Do not replace in headings */ + callback : null, /* Callback once all tags are replaced: Call or tooltip or anything you like */ + replaceOnce : false /* Replace only once in a TextNode */, + replaceClass: 'glossarizer_replaced' + } /** * Constructor */ - function Glossarizer (el, options) { + function Glossarizer(el, options){ + var base = this - base.el = el + base.el = el; /* Element */ base.$el = $(el) @@ -55,102 +41,153 @@ /* Terms */ - base.terms = [] + base.terms = []; /* Excludes array */ - base.excludes = [] + base.excludes = []; /* Replaced words array */ - base.replaced = [] + base.replaced = []; + /* Regex Tags */ - base.regexOption = (base.options.caseSensitive ? '' : 'i') + (base.options.replaceOnce ? '' : 'g') + base.regexOption = base.options.replaceOnce? 'i': 'ig'; + /* Fetch glossary JSON */ - $.getJSON(this.options.sourceURL).then(function (data) { - base.glossary = data + $.getJSON(this.options.sourceURL).then(function(data){ + + base.glossary = data; - if (!base.glossary.length || base.glossary.length == 0) return + if(!base.glossary.length || base.glossary.length == 0) return; /** * Get all terms */ - for (var i = 0; i < base.glossary.length; i++) { - var terms = base.glossary[i].term.split(',') + for(var i =0; i< base.glossary.length; i++){ + + var terms = base.glossary[i].term.split(','); + + for(var j = 0; j < terms.length; j++){ - for (var j = 0; j < terms.length; j++) { /* Trim */ var trimmed = terms[j].replace(/^\s+|\s+$/g, ''), - isExclusion = trimmed.indexOf('!') + isExclusion = trimmed.indexOf('!'); + + if(isExclusion == -1 || isExclusion != 0){ - if (isExclusion == -1 || isExclusion != 0) { /* Glossary terms array */ base.terms.push(trimmed) - } else { + + }else{ + /* Excluded terms array */ - base.excludes.push(trimmed.substr(1)) + base.excludes.push(trimmed.substr(1)); } } + + } + //Set all the terms to lower case + for(var word in base.glossary) + base.glossary[word].term = base.glossary[word].term.toLowerCase(); + + // Sort Terms -- move longer terms to the front + base.terms.sort(function(a, b){ + return b.length - a.length; + }); /** * Wrap terms */ + console.log(base); + base.wrapTerms(); + - base.wrapTerms() }) + + + } /** * Prototypes */ Glossarizer.prototype = { - getDescription: function (term) { - var regex = new RegExp('(\,|\s*)' + this.clean(term) + '\\s*|\\,$', 'i') - /** - * Matches - * 1. Starts with \s* (zero or more spaces) - * 2. Ends with zero or more spaces - * 3. Ends with comma - */ + getDescription: function(term){ + + // var regex = new RegExp('(\,|\s*)'+this.clean(term)+'\\s*|\\,$', 'i'); + // + // /** + // * Matches + // * 1. Starts with \s* (zero or more spaces) + // * 2. Ends with zero or more spaces + // * 3. Ends with comma + // */ + // + // for(var i =0; i< this.glossary.length; i++){ + // + // if(this.glossary[i].term.match(regex)){ + // return this.glossary[i].description.replace(/\"/gi, '"') + // } + // } + + // My code for finding the right definition + term = term.toLowerCase(); + //Loop through Glossary Obj + for (var i = 0; i < this.glossary.length; i++) { + //If the there's a term with alias + if(this.glossary[i].term.indexOf(',') > -1){ + //Break that term into an array + var temp = this.glossary[i].term.split(','); + //Trim and find the def + for(var j = 0; j < temp.length; j++){ + temp[j] = temp[j].trim().toLowerCase(); + if(temp[j] == this.clean(term)){ + + return this.glossary[i].description.replace(/\"/gi, '"') + } + } + } + //Else find term + else{ + + if(this.glossary[i].term == term){ + return this.glossary[i].description.replace(/\"/gi, '"') + } + } - for (var i = 0; i < this.glossary.length; i++) { - if (this.options.exactMatch) { - if (this.glossary[i].term == this.clean(term)) { - return this.glossary[i].description.replace(/\"/gi, '"') - } - } else { - if (this.glossary[i].term.match(regex)) { - return this.glossary[i].description.replace(/\"/gi, '"') - } } - } + }, - clean: function (text) { + clean: function(text){ + var reEscape = new RegExp('(\\' + ['/', '.', '*', '+', '?', '(', ')', '[', ']', '{', '}', '\\'].join('|\\') + ')', 'g') return text.replace(reEscape, '\\$1') + }, /** * Wraps the matched terms by calling traverser */ - wrapTerms: function () { + wrapTerms: function(){ + this.cleanedTerms = this.clean(this.terms.join('|')) this.excludedTerms = this.clean(this.excludes.join('|')) var nodes = this.el.querySelectorAll(this.options.lookupTagName) - for (var i = 0; i < nodes.length; i++) { + for(var i =0; i < nodes.length; i++){ this.traverser(nodes[i]) } @@ -158,77 +195,101 @@ * Callback */ - if (this.options.callback) this.options.callback.call(this.$el) + if(this.options.callback) this.options.callback.call(this.$el) + }, /** * Traverses through nodes to find the matching terms in TEXTNODES */ - traverser: function (node) { + traverser: function(node){ + var next, - base = this + base = this; if (node.nodeType === 1) { + /* Element Node */ if (node = node.firstChild) { - do { - // Recursively call traverseChildNodes - // on each child node - next = node.nextSibling + do { + // Recursively call traverseChildNodes + // on each child node + next = node.nextSibling - /** - * Check if the node is not glossarized - */ + /** + * Check if the node is not glossarized + */ - if (node.className != this.options.replaceClass) { - this.traverser(node) - } - } while (node = next) + if( node.className != this.options.replaceClass) + { + + this.traverser(node) + + } + + } while(node = next) } + } else if (node.nodeType === 3) { + /* Text Node */ var temp = document.createElement('div'), - data = node.data + data = node.data; + + var re = new RegExp('(?:^|\\b)('+this.cleanedTerms+ ')(?!\\w)', base.regexOption), + reEx = new RegExp('(?:^|\\b)('+this.excludedTerms+ ')(?!\\w)', base.regexOption); + - var re = new RegExp('(?:^|\\b)(' + this.cleanedTerms + ')(?!\\w)', base.regexOption), - reEx = new RegExp('(?:^|\\b)(' + this.excludedTerms + ')(?!\\w)', base.regexOption) + if(re.test(data)){ - if (re.test(data)) { - var excl = reEx.exec(data) + var excl = reEx.exec(data); - data = data.replace(re, function (match, item , offset, string) { - if (base.options.replaceOnce && inArrayIn(match, base.replaced) >= 0) { - return match + data = data.replace(re,function(match, item , offset, string){ + + if(base.options.replaceOnce && inArrayIn(match, base.replaced) >= 0){ + + return match; } - base.replaced.push(match) + base.replaced.push(match); - var ir = new RegExp('(?:^|\\b)' + base.clean(match) + '(?!\\w)'), + var ir = new RegExp('(?:^|\\b)'+base.clean(match)+'(?!\\w)'), result = ir.exec(data) - if (result) { - if (excl && base.excludes.length) { + + if(result){ + + if(excl && base.excludes.length){ + var id = offset, exid = excl.index, - exl = excl.index + excl[0].length + exl = excl.index + excl[0].length; + + if(exid <= id && id <= exl){ + + return match; + + }else{ + + return '<'+base.options.replaceTag+' class="'+base.options.replaceClass+'" title="'+base.getDescription(match)+'">'+ match + '' - if (exid <= id && id <= exl) { - return match - } else { - return '<' + base.options.replaceTag + ' class="' + base.options.replaceClass + '" title="' + base.getDescription(match) + '">' + match + '' } - } else { - return '<' + base.options.replaceTag + ' class="' + base.options.replaceClass + '" title="' + base.getDescription(match) + '">' + match + '' + } + else{ + + return '<'+base.options.replaceTag+' class="'+base.options.replaceClass+'" title="'+base.getDescription(match)+'">'+ match + '' } } - }) + + + }); /** * Only replace when a match is found @@ -239,35 +300,48 @@ $(temp).html(data) + + while (temp.firstChild) { node.parentNode.insertBefore(temp.firstChild, node) } node.parentNode.removeChild(node) + } + } + }, - } + }; + /** * Public Methods */ var methods = { - destroy: function () { - this.$el.removeData('plugin_' + pluginName) + + destroy: function(){ + + this.$el.removeData('plugin_' + pluginName); /* Remove abbr tag */ - this.$el.find('.' + this.options.replaceClass).each(function () { + this.$el.find('.' + this.options.replaceClass).each(function(){ + var $this = $(this), - text = $this.text() + text = $this.text(); + $this.replaceWith(text) + }) + } } + /** * Extend Prototype */ @@ -278,48 +352,60 @@ * Plugin * @param {[type]} options */ - $.fn[pluginName] = function (options) { - return this.each(function () { + $.fn[pluginName] =function(options){ + + return this.each(function(){ + + var $this = $(this), - glossarizer = $this.data('plugin_' + pluginName) + glossarizer = $this.data('plugin_' + pluginName); /* Check if its a method */ - if (typeof options == 'string' && glossarizer && methods.hasOwnProperty(options)) { + if(typeof options == "string" && glossarizer && methods.hasOwnProperty(options) ){ + glossarizer[options].apply(glossarizer) - } else { + + }else{ + /* Destroy if exists */ - if (glossarizer) glossarizer['destroy'].apply(glossarizer) + if(glossarizer) glossarizer['destroy'].apply(glossarizer); + /* Initialize */ $.data(this, 'plugin_' + pluginName, new Glossarizer(this, options)) } - }) + }); + } + /** * In Array */ - function inArrayIn (elem, arr, i) { - if (typeof elem !== 'string') { - return $.inArray.apply(this, arguments) - } + function inArrayIn(elem, arr, i){ - if (arr) { - var len = arr.length - i = i ? (i < 0 ? Math.max(0, len + i) : i) : 0 - elem = elem.toLowerCase() - for (; i < len; i++) { - if (i in arr && arr[i].toLowerCase() == elem) { - return i + if (typeof elem !== 'string'){ + return $.inArray.apply(this, arguments); } - } + + if (arr){ + var len = arr.length; + i = i ? (i < 0 ? Math.max(0, len + i) : i) : 0; + elem = elem.toLowerCase(); + for (; i < len; i++){ + if (i in arr && arr[i].toLowerCase() == elem){ + return i; + } + } + } + return -1; } - return -1 - } -})); + + +})(jQuery);