Skip to content

Commit

Permalink
Docs: add basic search feature for install and API
Browse files Browse the repository at this point in the history
  • Loading branch information
lovell committed Apr 14, 2020
1 parent 1d6ef63 commit 70e730b
Show file tree
Hide file tree
Showing 6 changed files with 179 additions and 6 deletions.
5 changes: 3 additions & 2 deletions docs/firebase.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
"public": ".",
"ignore": [
".*",
"*.json",
"firebase.json",
"*.md",
"image/**"
"image/**",
"search-index/**"
],
"headers": [
{
Expand Down
38 changes: 35 additions & 3 deletions docs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,11 @@
<script src="https://cdn.jsdelivr.net/npm/docute@4/dist/docute.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/docute-google-analytics@1/dist/index.min.js"></script>
<script>
var docuteApiTitlePlugin = {
const docuteApiTitlePlugin = {
name: 'apiTitle',
extend(api) {
api.processMarkdown(function (md) {
var title = api.store.getters.sidebarLinks
const title = api.store.getters.sidebarLinks
.filter(function (sidebarLink) {
return sidebarLink.link === api.router.history.current.path
})
Expand All @@ -72,6 +72,37 @@
});
}
};
const docuteApiSearchPlugin = {
name: 'apiSearch',
extend(api) {
api.enableSearch({
handler: function (keyword) {
if (keyword.trim().length > 2) {
return fetch('/search-index.json')
.then(function (res) {
return res.json();
})
.then(function (entries) {
const results = [];
entries.forEach(function (entry) {
if (entry.k.includes(keyword)) {
results.push({
title: entry.t,
link: entry.l,
description: entry.d,
label: entry.l.startsWith("/api") ? "API" : "Install"
});
}
})
return results.slice(0, 3);
})
} else {
return [];
}
}
});
}
};
new Docute({
router: { mode: 'history' },
logo: '<div style="display:flex;align-items:center">'
Expand All @@ -85,7 +116,8 @@
footer: '<a href="https://pixelplumbing.com/" target="_blank">pixelplumbing.com<a>',
plugins: [
docuteGoogleAnalytics('UA-13034748-12'),
docuteApiTitlePlugin
docuteApiTitlePlugin,
docuteApiSearchPlugin
],
sourcePath: 'https://cdn.jsdelivr.net/gh/lovell/sharp@v0.25.2/docs',
nav: [
Expand Down
1 change: 1 addition & 0 deletions docs/search-index.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[{"t":"Prerequisites","d":"Node.js v10","k":"prerequisites node","l":"/install#prerequisites"},{"t":"Prebuilt binaries","d":"Ready-compiled sharp and libvips binaries are provided for use with Node.js v10 on the most common platforms macOS x64 10.13 Linux x64 glibc","k":"prebuilt binaries ready compiled sharp libvips binaries provided node most common platforms macos linux glibc","l":"/install#prebuilt-binaries"},{"t":"Common problems","d":"The architecture and platform of Node.js used for npm install must be the same as the architecture and platform of Node.js used at runtime.","k":"common problems architecture platform node used npm install must same architecture platform node used runtime","l":"/install#common-problems"},{"t":"Custom libvips","d":"To use a custom, globally-installed version of libvips instead of the provided binaries, make sure it is at least the version listed under c","k":"custom libvips custom globally installed version libvips instead provided binaries make sure least version listed under","l":"/install#custom-libvips"},{"t":"Building from source","d":"This module will be compiled from source at npm install time when a globally-installed libvips is detected set the SHARP_IGNORE_GLOBAL_LIBVI","k":"building source module compiled source npm install time globally installed libvips detected sharpignoregloballibvi","l":"/install#building-from-source"},{"t":"Custom prebuilt binaries","d":"This is an advanced approach that most people will not require. To install the prebuilt libvips binaries from a custom URL, set the sharp_di","k":"custom prebuilt binaries advanced approach most people require install prebuilt libvips binaries custom url sharpdi","l":"/install#custom-prebuilt-binaries"},{"t":"FreeBSD","d":"The vips package must be installed before npm install is run. sh pkg install -y pkgconf vips sh cd /usr/ports/graphics/vips/ make install cl","k":"freebsd vips package must installed before npm install run pkg install pkgconf vips usr ports graphics vips make install","l":"/install#freebsd"},{"t":"Heroku","d":"Add the jemalloc buildpack to reduce the effects of memory fragmentation. Set NODE_MODULES_CACHE","k":"heroku add jemalloc buildpack reduce effects memory fragmentation nodemodulescache","l":"/install#heroku"},{"t":"AWS Lambda","d":"Set the Lambda runtime to nodejs12.x. The binaries in the node_modules directory of the deployment package must be for the Linux x64 platfor","k":"aws lambda lambda runtime nodejs binaries nodemodules directory deployment package must linux platfor","l":"/install#aws-lambda"},{"t":"Electron","d":"Electron provides versions of the V8 JavaScript engine that are incompatible with Node.js. To ensure the correct binaries are used, run the","k":"electron electron provides versions javascript engine incompatible node ensure correct binaries used run","l":"/install#electron"},{"t":"Sharp","d":"Constructor","k":"sharp constructor","l":"/api-constructor#sharp"},{"t":"clone","d":"Take a snapshot of the Sharp instance, returning a new instance. Cloned instances inherit the input of their parent instance. This allows mu","k":"clone take snapshot sharp instance returning new instance cloned instances inherit input parent instance allows","l":"/api-constructor#clone"},{"t":"metadata","d":"Fast access to uncached image metadata without decoding any compressed image data. A Promise is returned when callback is not provided.","k":"metadata fast access uncached image metadata without decoding compressed image data promise returned callback provided","l":"/api-input#metadata"},{"t":"stats","d":"Access to pixel-derived image statistics for every channel in the image. A Promise is returned when callback is not provided.","k":"stats access pixel derived image statistics every channel image promise returned callback provided","l":"/api-input#stats"},{"t":"toFile","d":"Write output image data to a file.","k":"tofile write output image data file","l":"/api-output#tofile"},{"t":"toBuffer","d":"Write output to a Buffer. JPEG, PNG, WebP, TIFF and RAW output are supported.","k":"tobuffer write output buffer jpeg png webp tiff raw output supported","l":"/api-output#tobuffer"},{"t":"withMetadata","d":"Include all metadata EXIF, XMP, IPTC from the input image in the output image. The default behaviour, when withMetadata is not used, is to s","k":"withmetadata include metadata exif xmp iptc input image output image default behaviour withmetadata used","l":"/api-output#withmetadata"},{"t":"toFormat","d":"Force output to a given format.","k":"toformat force output given format","l":"/api-output#toformat"},{"t":"jpeg","d":"Use these JPEG options for output image.","k":"jpeg jpeg options output image","l":"/api-output#jpeg"},{"t":"png","d":"Use these PNG options for output image.","k":"png png options output image","l":"/api-output#png"},{"t":"webp","d":"Use these WebP options for output image.","k":"webp webp options output image","l":"/api-output#webp"},{"t":"tiff","d":"Use these TIFF options for output image.","k":"tiff tiff options output image","l":"/api-output#tiff"},{"t":"heif","d":"Use these HEIF options for output image.","k":"heif heif options output image","l":"/api-output#heif"},{"t":"raw","d":"Force output to be raw, uncompressed, 8-bit unsigned integer unit8 pixel data. Pixel ordering is left-to-right, top-to-bottom, without paddi","k":"raw force output raw uncompressed bit unsigned integer unit pixel data pixel ordering left right top bottom without paddi","l":"/api-output#raw"},{"t":"tile","d":"Use tile-based deep zoom image pyramid output. Set the format and options for tile images via the toFormat, jpeg, png or webp functions. Use","k":"tile tile based deep zoom image pyramid output format options tile images via toformat jpeg png webp functions","l":"/api-output#tile"},{"t":"resize","d":"Resize image to width, height or width x height.","k":"resize resize image width height width height","l":"/api-resize#resize"},{"t":"extend","d":"Extends/pads the edges of the image with the provided background colour. This operation will always occur after resizing and extraction, if","k":"extend extends pads edges image provided background colour operation occur after resizing extraction","l":"/api-resize#extend"},{"t":"extract","d":"Extract/crop a region of the image.","k":"extract extract crop region image","l":"/api-resize#extract"},{"t":"trim","d":"Trim boring pixels from all edges that contain values similar to the top-left pixel. Images consisting entirely of a single colour will calc","k":"trim trim boring pixels edges contain values similar top left pixel images consisting entirely single colour calc","l":"/api-resize#trim"},{"t":"composite","d":"Composite images over the processed resized, extracted etc. image.","k":"composite composite images processed resized extracted image","l":"/api-composite#composite"},{"t":"rotate","d":"Rotate the output image by either an explicit angle or auto-orient based on the EXIF Orientation tag.","k":"rotate rotate output image explicit angle auto orient based exif orientation tag","l":"/api-operation#rotate"},{"t":"flip","d":"Flip the image about the vertical Y axis. This always occurs after rotation, if any. The use of flip implies the removal of the EXIF Orienta","k":"flip flip image vertical axis occurs after rotation flip implies removal exif orienta","l":"/api-operation#flip"},{"t":"flop","d":"Flop the image about the horizontal X axis. This always occurs after rotation, if any. The use of flop implies the removal of the EXIF Orien","k":"flop flop image horizontal axis occurs after rotation flop implies removal exif orien","l":"/api-operation#flop"},{"t":"sharpen","d":"Sharpen the image. When used without parameters, performs a fast, mild sharpen of the output image. When a sigma is provided, performs a slo","k":"sharpen sharpen image used without parameters performs fast mild sharpen output image sigma provided performs slo","l":"/api-operation#sharpen"},{"t":"median","d":"Apply median filter. When used without parameters the default window is 3x3.","k":"median apply median filter used without parameters default window","l":"/api-operation#median"},{"t":"blur","d":"Blur the image. When used without parameters, performs a fast, mild blur of the output image. When a sigma is provided, performs a slower, m","k":"blur blur image used without parameters performs fast mild blur output image sigma provided performs slower","l":"/api-operation#blur"},{"t":"flatten","d":"Merge alpha transparency channel, if any, with a background.","k":"flatten merge alpha transparency channel background","l":"/api-operation#flatten"},{"t":"gamma","d":"Apply a gamma correction by reducing the encoding darken pre-resize at a factor of 1/gamma then increasing the encoding brighten post-resize","k":"gamma apply gamma correction reducing encoding darken pre resize factor gamma then increasing encoding brighten post resize","l":"/api-operation#gamma"},{"t":"negate","d":"Produce the negative of the image.","k":"negate produce negative image","l":"/api-operation#negate"},{"t":"normalise","d":"Enhance output image contrast by stretching its luminance to cover the full dynamic range.","k":"normalise enhance output image contrast stretching luminance cover full dynamic range","l":"/api-operation#normalise"},{"t":"normalize","d":"Alternative spelling of normalise.","k":"normalize alternative spelling normalise","l":"/api-operation#normalize"},{"t":"convolve","d":"Convolve the image with the specified kernel.","k":"convolve convolve image specified kernel","l":"/api-operation#convolve"},{"t":"threshold","d":"Any pixel value greather than or equal to the threshold value will be set to 255, otherwise it will be set to 0.","k":"threshold pixel value greather than equal threshold value otherwise","l":"/api-operation#threshold"},{"t":"boolean","d":"Perform a bitwise boolean operation with operand image.","k":"boolean perform bitwise boolean operation operand image","l":"/api-operation#boolean"},{"t":"linear","d":"Apply the linear formula a input b to the image levels adjustment","k":"linear apply linear formula input image levels adjustment","l":"/api-operation#linear"},{"t":"recomb","d":"Recomb the image with the specified matrix.","k":"recomb recomb image specified matrix","l":"/api-operation#recomb"},{"t":"modulate","d":"Transforms the image using brightness, saturation and hue rotation.","k":"modulate transforms image brightness saturation hue rotation","l":"/api-operation#modulate"},{"t":"removeAlpha","d":"Remove alpha channel, if any. This is a no-op if the image does not have an alpha channel.","k":"removealpha remove alpha channel image alpha channel","l":"/api-channel#removealpha"},{"t":"ensureAlpha","d":"Ensure alpha channel, if missing. The added alpha channel will be fully opaque. This is a no-op if the image already has an alpha channel.","k":"ensurealpha ensure alpha channel missing added alpha channel fully opaque image alpha channel","l":"/api-channel#ensurealpha"},{"t":"extractChannel","d":"Extract a single channel from a multi-channel image.","k":"extractchannel extract single channel multi channel image","l":"/api-channel#extractchannel"},{"t":"joinChannel","d":"Join one or more channels to the image. The meaning of the added channels depends on the output colourspace, set with toColourspace. By defa","k":"joinchannel join one channels image meaning added channels depends output colourspace tocolourspace defa","l":"/api-channel#joinchannel"},{"t":"bandbool","d":"Perform a bitwise boolean operation on all input image channels bands to produce a single channel output image.","k":"bandbool perform bitwise boolean operation input image channels bands produce single channel output image","l":"/api-channel#bandbool"},{"t":"tint","d":"Tint the image using the provided chroma while preserving the image luminance. An alpha channel may be present and will be unchanged by the","k":"tint tint image provided chroma while preserving image luminance alpha channel present unchanged","l":"/api-colour#tint"},{"t":"greyscale","d":"Convert to 8-bit greyscale 256 shades of grey. This is a linear operation. If the input image is in a non-linear colour space such as sRGB,","k":"greyscale convert bit greyscale shades grey linear operation input image non linear colour space such srgb","l":"/api-colour#greyscale"},{"t":"grayscale","d":"Alternative spelling of greyscale.","k":"grayscale alternative spelling greyscale","l":"/api-colour#grayscale"},{"t":"toColourspace","d":"Set the output colourspace. By default output image will be web-friendly sRGB, with additional channels interpreted as alpha channels.","k":"tocolourspace output colourspace default output image web friendly srgb additional channels interpreted alpha channels","l":"/api-colour#tocolourspace"},{"t":"toColorspace","d":"Alternative spelling of toColourspace.","k":"tocolorspace alternative spelling tocolourspace","l":"/api-colour#tocolorspace"},{"t":"format","d":"An Object containing nested boolean values representing the available input and output formats/methods.","k":"format object containing nested boolean values representing available input output formats methods","l":"/api-utility#format"},{"t":"versions","d":"An Object containing the version numbers of libvips and its dependencies.","k":"versions object containing version numbers libvips dependencies","l":"/api-utility#versions"},{"t":"cache","d":"Gets or, when options are provided, sets the limits of _libvips_ operation cache. Existing entries in the cache will be trimmed after any ch","k":"cache options provided limits libvips operation cache existing entries cache trimmed after","l":"/api-utility#cache"},{"t":"concurrency","d":"Gets or, when a concurrency is provided, sets the number of threads _libvips_ should create to process each image. The default value is the","k":"concurrency concurrency provided number threads libvips create process image default value","l":"/api-utility#concurrency"},{"t":"queue","d":"An EventEmitter that emits a change event when a task is either","k":"queue eventemitter emits change event task","l":"/api-utility#queue"},{"t":"counters","d":"Provides access to internal task counters.","k":"counters provides access internal task counters","l":"/api-utility#counters"},{"t":"simd","d":"Get and set use of SIMD vector unit instructions. Requires libvips to have been compiled with liborc support.","k":"simd simd vector unit instructions requires libvips compiled liborc support","l":"/api-utility#simd"}]
59 changes: 59 additions & 0 deletions docs/search-index/build.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
'use strict';

const fs = require('fs');
const { extractDescription, extractKeywords } = require('./extract');

const searchIndex = [];

// Install
const contents = fs.readFileSync(`${__dirname}/../install.md`, 'utf8');
const matches = contents.matchAll(
/## (?<title>[A-Za-z ]+)\n\n(?<body>[^#]+)/gs
);
for (const match of matches) {
const { title, body } = match.groups;
const description = extractDescription(body);

searchIndex.push({
t: title,
d: description,
k: extractKeywords(`${title} ${description}`),
l: `/install#${title.toLowerCase().replace(/ /g, '-')}`
});
}

// API
[
'constructor',
'input',
'output',
'resize',
'composite',
'operation',
'channel',
'colour',
'utility'
].forEach((section) => {
const contents = fs.readFileSync(`${__dirname}/../api-${section}.md`, 'utf8');
const matches = contents.matchAll(
/\n## (?<title>[A-Za-z]+)\n\n(?<firstparagraph>.+?)\n\n/gs
);
for (const match of matches) {
const { title, firstparagraph } = match.groups;
const description = firstparagraph.startsWith('###')
? 'Constructor'
: extractDescription(firstparagraph);

searchIndex.push({
t: title,
d: description,
k: extractKeywords(`${title} ${description}`),
l: `/api-${section}#${title.toLowerCase()}`
});
}
});

fs.writeFileSync(
`${__dirname}/../search-index.json`,
JSON.stringify(searchIndex)
);
80 changes: 80 additions & 0 deletions docs/search-index/extract.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
'use strict';

const stopWords = [
'a',
'about',
'all',
'already',
'always',
'an',
'and',
'any',
'are',
'as',
'at',
'be',
'been',
'by',
'can',
'do',
'does',
'each',
'either',
'etc',
'for',
'from',
'get',
'gets',
'has',
'have',
'how',
'if',
'in',
'is',
'it',
'its',
'may',
'more',
'much',
'no',
'not',
'of',
'on',
'or',
'over',
'set',
'sets',
'should',
'that',
'the',
'their',
'there',
'therefore',
'these',
'this',
'to',
'use',
'using',
'when',
'which',
'will',
'with'
];

const extractDescription = (str) =>
str
.replace(/\(http[^)]+/g, '')
.replace(/\s+/g, ' ')
.replace(/[^A-Za-z0-9_/\-,. ]/g, '')
.replace(/\s+/g, ' ')
.substr(0, 140)
.trim();

const extractKeywords = (str) =>
str
.split(/[ -/]/)
.map((word) => word.toLowerCase().replace(/[^a-z]/g, ''))
.filter((word) => word.length > 2 && !stopWords.includes(word))
.join(' ');

module.exports = { extractDescription, extractKeywords };
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@
"test-licensing": "license-checker --production --summary --onlyAllow=\"Apache-2.0;BSD;ISC;MIT\"",
"test-coverage": "./test/coverage/report.sh",
"test-leak": "./test/leak/leak.sh",
"docs-build": "for m in constructor input resize composite operation colour channel output utility; do documentation build --shallow --format=md --markdown-toc=false lib/$m.js >docs/api-$m.md; done",
"docs-build": "for m in constructor input resize composite operation colour channel output utility; do documentation build --shallow --format=md --markdown-toc=false lib/$m.js >docs/api-$m.md; done && node docs/search-index/build",
"docs-serve": "cd docs && npx serve",
"docs-publish": "cd docs && npx firebase-tools deploy --project pixelplumbing --only hosting:pixelplumbing-sharp"
},
Expand Down

0 comments on commit 70e730b

Please sign in to comment.