Simple-Jekyll-Search
Simple-Jekyll-Search
A JavaScript library to add search functionality to any Jekyll blog.
Use case
You have a blog, built with Jekyll, and want a lightweight search functionality on your blog, purely client-side?
No server configurations or databases to maintain.
Just 5 minutes to have a fully working searchable blog.
Installation
npm
1
npm install simple-jekyll-search
Getting started
Create search.json
Place the following code in a file called search.json
in the root of your Jekyll blog. (You can also get a copy from here)
This file will be used as a small data source to perform the searches on the client side:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
---
layout: none
---
[
{
"title" : "Introduction to character animation",
"category" : "",
"tags" : "yellow",
"url" : "/Skinned_Meshes/",
"date" : "2022-07-06 00:00:00 +0000"
} ,
{
"title" : "skeleton animation cpu skinning",
"category" : "",
"tags" : "yellow",
"url" : "/skeleton_animation_cpu_skinning/",
"date" : "2022-07-05 00:00:00 +0000"
} ,
{
"title" : "skeleton animation bind pose",
"category" : "",
"tags" : "yellow",
"url" : "/skeleton_animation_bind_pose/",
"date" : "2022-07-05 00:00:00 +0000"
} ,
{
"title" : "skeleton animation binding pose",
"category" : "",
"tags" : "yellow",
"url" : "/introduction_to_character_animation/",
"date" : "2022-07-05 00:00:00 +0000"
} ,
{
"title" : "Metaprogramming",
"category" : "",
"tags" : "",
"url" : "/metaprogramming/",
"date" : "2021-10-12 00:00:00 +0000"
} ,
{
"title" : "math vector",
"category" : "",
"tags" : "red, yellow",
"url" : "/vector/",
"date" : "2021-10-12 00:00:00 +0000"
} ,
{
"title" : "urp begining",
"category" : "",
"tags" : "red, yellow",
"url" : "/urp-begining/",
"date" : "2021-10-11 00:00:00 +0000"
} ,
{
"title" : "gameplay debug",
"category" : "",
"tags" : "red, yellow",
"url" : "/gameplay-replay/",
"date" : "2021-10-10 00:00:00 +0000"
} ,
{
"title" : "gameplay debug",
"category" : "",
"tags" : "red, yellow",
"url" : "/Script-Binding/",
"date" : "2021-10-10 00:00:00 +0000"
} ,
{
"title" : "Game Hacking",
"category" : "",
"tags" : "red, yellow",
"url" : "/Introduction-to-game-hackiing/",
"date" : "2021-09-13 00:00:00 +0000"
} ,
{
"title" : "thirties(致30岁)",
"category" : "",
"tags" : "yellow",
"url" : "/thirties/",
"date" : "2021-09-11 00:00:00 +0000"
} ,
{
"title" : "thirties",
"category" : "",
"tags" : "red, yellow",
"url" : "/never_settle_down/",
"date" : "2021-09-11 00:00:00 +0000"
} ,
{
"title" : "IlluminationMode",
"category" : "",
"tags" : "red, yellow",
"url" : "/Lighting-Mode/",
"date" : "2020-10-01 00:00:00 +0000"
} ,
{
"title" : "my chaper",
"category" : "",
"tags" : "red, yellow",
"url" : "/preface/",
"date" : "2019-01-01 00:00:00 +0000"
} ,
{
"title" : "Powerful things you can do with the Markdown editor",
"category" : "",
"tags" : "",
"url" : "/powerful-things-markdown-editor/",
"date" : "2018-06-12 00:00:00 +0000"
} ,
{
"title" : "The first mass-produced book to deviate from a rectilinear format",
"category" : "",
"tags" : "",
"url" : "/first-mass-produced/",
"date" : "2018-06-12 00:00:00 +0000"
} ,
{
"title" : "Education must also train one for quick, resolute and effective thinking.",
"category" : "",
"tags" : "",
"url" : "/education/",
"date" : "2018-06-12 00:00:00 +0000"
} ,
{
"title" : "Accumulated experience of social living",
"category" : "",
"tags" : "",
"url" : "/acumulated-experience/",
"date" : "2018-06-12 00:00:00 +0000"
} ,
{
"title" : "About Bundler",
"category" : "",
"tags" : "",
"url" : "/about-bundler/",
"date" : "2018-05-12 00:00:00 +0000"
} ,
{
"title" : "We all wait for summer",
"category" : "",
"tags" : "",
"url" : "/we-all-wait-for-summer/",
"date" : "2018-01-12 00:00:00 +0000"
} ,
{
"title" : "Tree of Codes",
"category" : "",
"tags" : "",
"url" : "/tree-of-codes/",
"date" : "2018-01-12 00:00:00 +0000"
} ,
{
"title" : "Red Riding Hood",
"category" : "",
"tags" : "",
"url" : "/red-riding/",
"date" : "2018-01-12 00:00:00 +0000"
} ,
{
"title" : "Press and education",
"category" : "",
"tags" : "",
"url" : "/press-and-education/",
"date" : "2018-01-12 00:00:00 +0000"
} ,
{
"title" : "Options for creating a new site with Jekyll",
"category" : "",
"tags" : "",
"url" : "/options-for-creating-new-site-with-jekyll/",
"date" : "2018-01-12 00:00:00 +0000"
} ,
{
"title" : "Never stopped worrying or loving the bomb",
"category" : "",
"tags" : "",
"url" : "/never-stopped-worrying-never-loved-bomb/",
"date" : "2018-01-12 00:00:00 +0000"
} ,
{
"title" : "External Featured Image",
"category" : "",
"tags" : "",
"url" : "/is-intelligence-enough/",
"date" : "2018-01-12 00:00:00 +0000"
} ,
{
"title" : "Let's test spoilers",
"category" : "",
"tags" : "",
"url" : "/quick-start-guide/",
"date" : "2018-01-11 00:00:00 +0000"
} ,
{
"title" : "hello Movie",
"category" : "",
"tags" : "red, yellow",
"url" : "/customer-service/",
"date" : "2018-01-11 00:00:00 +0000"
}
]
Preparing the plugin
Add DOM elements
SimpleJekyllSearch needs two DOM
elements to work:
- a search input field
- a result container to display the results
Give me the code
Here is the code you can use with the default configuration:
You need to place the following code within the layout where you want the search to appear. (See the configuration section below to customize it)
For example in _layouts/default.html:
1
2
3
4
5
6
<!-- HTML elements for search -->
<input type="text" id="search-input" placeholder="Search blog posts..">
<ul id="results-container"></ul>
<!-- or without installing anything -->
<script src="https://unpkg.com/simple-jekyll-search@latest/dest/simple-jekyll-search.min.js"></script>
Usage
Customize SimpleJekyllSearch by passing in your configuration options:
1
2
3
4
5
var sjs = SimpleJekyllSearch({
searchInput: document.getElementById('search-input'),
resultsContainer: document.getElementById('results-container'),
json: '/search.json'
})
returns { search }
A new instance of SimpleJekyllSearch returns an object, with the only property search
.
search
is a function used to simulate a user input and display the matching results.
E.g.:
1
2
var sjs = SimpleJekyllSearch({ ...options })
sjs.search('Hello')
💡 it can be used to filter posts by tags or categories!
Options
Here is a list of the available options, usage questions, troubleshooting & guides.
searchInput (Element) [required]
The input element on which the plugin should listen for keyboard event and trigger the searching and rendering for articles.
resultsContainer (Element) [required]
The container element in which the search results should be rendered in. Typically a <ul>
.
json (String|JSON) [required]
You can either pass in an URL to the search.json
file, or the results in form of JSON directly, to save one round trip to get the data.
searchResultTemplate (String) [optional]
The template of a single rendered search result.
The templating syntax is very simple: You just enclose the properties you want to replace with curly braces.
E.g.
The template
1
2
3
4
5
6
var sjs = SimpleJekyllSearch({
searchInput: document.getElementById('search-input'),
resultsContainer: document.getElementById('results-container'),
json: '/search.json',
searchResultTemplate: '<li><a href="https://theworld.life{url}">{title}</a></li>'
})
will render to the following
1
<li><a href="/jekyll/update/2014/11/01/welcome-to-jekyll.html">Welcome to Jekyll!</a></li>
If the search.json
contains this data
1
2
3
4
5
6
7
8
9
[
{
"title" : "Welcome to Jekyll!",
"category" : "",
"tags" : "",
"url" : "/jekyll/update/2014/11/01/welcome-to-jekyll.html",
"date" : "2014-11-01 21:07:22 +0100"
}
]
templateMiddleware (Function) [optional]
A function that will be called whenever a match in the template is found.
It gets passed the current property name, property value, and the template.
If the function returns a non-undefined value, it gets replaced in the template.
This can be potentially useful for manipulating URLs etc.
Example:
1
2
3
4
5
6
7
8
9
SimpleJekyllSearch({
...
templateMiddleware: function(prop, value, template) {
if (prop === 'bar') {
return value.replace(/^\//, '')
}
}
...
})
See the tests for an in-depth code example
sortMiddleware (Function) [optional]
A function that will be used to sort the filtered results.
It can be used for example to group the sections together.
Example:
1
2
3
4
5
6
7
8
9
SimpleJekyllSearch({
...
sortMiddleware: function(a, b) {
var astr = String(a.section) + "-" + String(a.caption);
var bstr = String(b.section) + "-" + String(b.caption);
return astr.localeCompare(bstr)
}
...
})
noResultsText (String) [optional]
The HTML that will be shown if the query didn’t match anything.
limit (Number) [optional]
You can limit the number of posts rendered on the page.
fuzzy (Boolean) [optional]
Enable fuzzy search to allow less restrictive matching.
exclude (Array) [optional]
Pass in a list of terms you want to exclude (terms will be matched against a regex, so URLs, words are allowed).
success (Function) [optional]
A function called once the data has been loaded.
debounceTime (Number) [optional]
Limit how many times the search function can be executed over the given time window. This is especially useful to improve the user experience when searching over a large dataset (either with rare terms or because the number of posts to display is large). If no debounceTime
(milliseconds) is provided a search will be triggered on each keystroke.
If search isn’t working due to invalid JSON
- There is a filter plugin in the _plugins folder which should remove most characters that cause invalid JSON. To use it, add the simple_search_filter.rb file to your _plugins folder, and use
remove_chars
as a filter.
For example: in search.json, replace
1
"content": "# [Simple-Jekyll-Search](https://www.npmjs.com/package/simple-jekyll-search)[](https://travis-ci.org/christian-fei/Simple-Jekyll-Search)[](https://david-dm.org/christian-fei/Simple-Jekyll-Search)[](https://david-dm.org/christian-fei/Simple-Jekyll-Search?type=dev)A JavaScript library to add search functionality to any Jekyll blog.## Use caseYou have a blog, built with Jekyll, and want a **lightweight search functionality** on your blog, purely client-side?*No server configurations or databases to maintain*.Just **5 minutes** to have a **fully working searchable blog**.---## Installation### npm```shnpm install simple-jekyll-search```## Getting started### Create `search.json`Place the following code in a file called `search.json` in the **root** of your Jekyll blog. (You can also get a copy [from here](/example/search.json))This file will be used as a small data source to perform the searches on the client side:```yaml---layout: none---[ {% for post in site.posts %} { "title" : "{{ post.title | escape }}", "category" : "{{ post.category }}", "tags" : "{{ post.tags | join: ', ' }}", "url" : "{{ site.baseurl }}{{ post.url }}", "date" : "{{ post.date }}" } {% unless forloop.last %},{% endunless %} {% endfor %}]```## Preparing the plugin### Add DOM elementsSimpleJekyllSearch needs two `DOM` elements to work:- a search input field- a result container to display the results#### Give me the codeHere is the code you can use with the default configuration:You need to place the following code within the layout where you want the search to appear. (See the configuration section below to customize it)For example in **_layouts/default.html**:```html```## UsageCustomize SimpleJekyllSearch by passing in your configuration options:```jsvar sjs = SimpleJekyllSearch({ searchInput: document.getElementById('search-input'), resultsContainer: document.getElementById('results-container'), json: '/search.json'})```### returns { search }A new instance of SimpleJekyllSearch returns an object, with the only property `search`.`search` is a function used to simulate a user input and display the matching results. E.g.:```jsvar sjs = SimpleJekyllSearch({ ...options })sjs.search('Hello')```💡 it can be used to filter posts by tags or categories!## OptionsHere is a list of the available options, usage questions, troubleshooting & guides.### searchInput (Element) [required]The input element on which the plugin should listen for keyboard event and trigger the searching and rendering for articles.### resultsContainer (Element) [required]The container element in which the search results should be rendered in. Typically a ``.### json (String|JSON) [required]You can either pass in an URL to the `search.json` file, or the results in form of JSON directly, to save one round trip to get the data.### searchResultTemplate (String) [optional]The template of a single rendered search result.The templating syntax is very simple: You just enclose the properties you want to replace with curly braces.E.g.The template```jsvar sjs = SimpleJekyllSearch({ searchInput: document.getElementById('search-input'), resultsContainer: document.getElementById('results-container'), json: '/search.json', searchResultTemplate: '{title}'})```will render to the following```htmlWelcome to Jekyll!```If the `search.json` contains this data```json[ { "title" : "Welcome to Jekyll!", "category" : "", "tags" : "", "url" : "/jekyll/update/2014/11/01/welcome-to-jekyll.html", "date" : "2014-11-01 21:07:22 +0100" }]```### templateMiddleware (Function) [optional]A function that will be called whenever a match in the template is found.It gets passed the current property name, property value, and the template.If the function returns a non-undefined value, it gets replaced in the template.This can be potentially useful for manipulating URLs etc.Example:```jsSimpleJekyllSearch({ ... templateMiddleware: function(prop, value, template) { if (prop === 'bar') { return value.replace(/^\//, '') } } ...})```See the [tests](https://github.com/christian-fei/Simple-Jekyll-Search/blob/master/tests/Templater.test.js) for an in-depth code example### sortMiddleware (Function) [optional]A function that will be used to sort the filtered results.It can be used for example to group the sections together.Example:```jsSimpleJekyllSearch({ ... sortMiddleware: function(a, b) { var astr = String(a.section) + "-" + String(a.caption); var bstr = String(b.section) + "-" + String(b.caption); return astr.localeCompare(bstr) } ...})```### noResultsText (String) [optional]The HTML that will be shown if the query didn't match anything.### limit (Number) [optional]You can limit the number of posts rendered on the page.### fuzzy (Boolean) [optional]Enable fuzzy search to allow less restrictive matching.### exclude (Array) [optional]Pass in a list of terms you want to exclude (terms will be matched against a regex, so URLs, words are allowed).### success (Function) [optional]A function called once the data has been loaded.### debounceTime (Number) [optional]Limit how many times the search function can be executed over the given time window. This is especially useful to improve the user experience when searching over a large dataset (either with rare terms or because the number of posts to display is large). If no `debounceTime` (milliseconds) is provided a search will be triggered on each keystroke.---## If search isn't working due to invalid JSON- There is a filter plugin in the _plugins folder which should remove most characters that cause invalid JSON. To use it, add the simple_search_filter.rb file to your _plugins folder, and use `remove_chars` as a filter.For example: in search.json, replace```json"content": "{{ page.content | strip_html | strip_newlines }}"```with```json"content": "{{ page.content | strip_html | strip_newlines | remove_chars | escape }}"```If this doesn't work when using Github pages you can try `jsonify` to make sure the content is json compatible:```js"content": {{ page.content | jsonify }}```**Note: you don't need to use quotes `"` in this since `jsonify` automatically inserts them.**## Enabling full-text searchReplace `search.json` with the following code:```yaml---layout: none---[ {% for post in site.posts %} { "title" : "{{ post.title | escape }}", "category" : "{{ post.category }}", "tags" : "{{ post.tags | join: ', ' }}", "url" : "{{ site.baseurl }}{{ post.url }}", "date" : "{{ post.date }}", "content" : "{{ post.content | strip_html | strip_newlines }}" } {% unless forloop.last %},{% endunless %} {% endfor %} , {% for page in site.pages %} { {% if page.title != nil %} "title" : "{{ page.title | escape }}", "category" : "{{ page.category }}", "tags" : "{{ page.tags | join: ', ' }}", "url" : "{{ site.baseurl }}{{ page.url }}", "date" : "{{ page.date }}", "content" : "{{ page.content | strip_html | strip_newlines }}" {% endif %} } {% unless forloop.last %},{% endunless %} {% endfor %}]```## Development- `npm install`- `npm test`#### Acceptance tests```bashcd example; jekyll serve# in another tabnpm run cypress -- run```## ContributorsThanks to all [contributors](https://github.com/christian-fei/Simple-Jekyll-Search/graphs/contributors) over the years! You are the best :)> [@daviddarnes](https://github.com/daviddarnes)[@XhmikosR](https://github.com/XhmikosR)[@PeterDaveHello](https://github.com/PeterDaveHello)[@mikeybeck](https://github.com/mikeybeck)[@egladman](https://github.com/egladman)[@midzer](https://github.com/midzer)[@eduardoboucas](https://github.com/eduardoboucas)[@kremalicious](https://github.com/kremalicious)[@tibotiber](https://github.com/tibotiber)and many others!## Stargazers over time[](https://starchart.cc/christian-fei/Simple-Jekyll-Search)"
with
1
"content": "# [Simple-Jekyll-Search](https://www.npmjs.com/package/simple-jekyll-search)[](https://travis-ci.org/christian-fei/Simple-Jekyll-Search)[](https://david-dm.org/christian-fei/Simple-Jekyll-Search)[](https://david-dm.org/christian-fei/Simple-Jekyll-Search?type=dev)A JavaScript library to add search functionality to any Jekyll blog.## Use caseYou have a blog, built with Jekyll, and want a **lightweight search functionality** on your blog, purely client-side?*No server configurations or databases to maintain*.Just **5 minutes** to have a **fully working searchable blog**.---## Installation### npm```shnpm install simple-jekyll-search```## Getting started### Create `search.json`Place the following code in a file called `search.json` in the **root** of your Jekyll blog. (You can also get a copy [from here](/example/search.json))This file will be used as a small data source to perform the searches on the client side:```yaml---layout: none---[ {% for post in site.posts %} { "title" : "{{ post.title | escape }}", "category" : "{{ post.category }}", "tags" : "{{ post.tags | join: ', ' }}", "url" : "{{ site.baseurl }}{{ post.url }}", "date" : "{{ post.date }}" } {% unless forloop.last %},{% endunless %} {% endfor %}]```## Preparing the plugin### Add DOM elementsSimpleJekyllSearch needs two `DOM` elements to work:- a search input field- a result container to display the results#### Give me the codeHere is the code you can use with the default configuration:You need to place the following code within the layout where you want the search to appear. (See the configuration section below to customize it)For example in **_layouts/default.html**:```html```## UsageCustomize SimpleJekyllSearch by passing in your configuration options:```jsvar sjs = SimpleJekyllSearch({ searchInput: document.getElementById('search-input'), resultsContainer: document.getElementById('results-container'), json: '/search.json'})```### returns { search }A new instance of SimpleJekyllSearch returns an object, with the only property `search`.`search` is a function used to simulate a user input and display the matching results. E.g.:```jsvar sjs = SimpleJekyllSearch({ ...options })sjs.search('Hello')```💡 it can be used to filter posts by tags or categories!## OptionsHere is a list of the available options, usage questions, troubleshooting & guides.### searchInput (Element) [required]The input element on which the plugin should listen for keyboard event and trigger the searching and rendering for articles.### resultsContainer (Element) [required]The container element in which the search results should be rendered in. Typically a ``.### json (String|JSON) [required]You can either pass in an URL to the `search.json` file, or the results in form of JSON directly, to save one round trip to get the data.### searchResultTemplate (String) [optional]The template of a single rendered search result.The templating syntax is very simple: You just enclose the properties you want to replace with curly braces.E.g.The template```jsvar sjs = SimpleJekyllSearch({ searchInput: document.getElementById('search-input'), resultsContainer: document.getElementById('results-container'), json: '/search.json', searchResultTemplate: '{title}'})```will render to the following```htmlWelcome to Jekyll!```If the `search.json` contains this data```json[ { "title" : "Welcome to Jekyll!", "category" : "", "tags" : "", "url" : "/jekyll/update/2014/11/01/welcome-to-jekyll.html", "date" : "2014-11-01 21:07:22 +0100" }]```### templateMiddleware (Function) [optional]A function that will be called whenever a match in the template is found.It gets passed the current property name, property value, and the template.If the function returns a non-undefined value, it gets replaced in the template.This can be potentially useful for manipulating URLs etc.Example:```jsSimpleJekyllSearch({ ... templateMiddleware: function(prop, value, template) { if (prop === 'bar') { return value.replace(/^\//, '') } } ...})```See the [tests](https://github.com/christian-fei/Simple-Jekyll-Search/blob/master/tests/Templater.test.js) for an in-depth code example### sortMiddleware (Function) [optional]A function that will be used to sort the filtered results.It can be used for example to group the sections together.Example:```jsSimpleJekyllSearch({ ... sortMiddleware: function(a, b) { var astr = String(a.section) + "-" + String(a.caption); var bstr = String(b.section) + "-" + String(b.caption); return astr.localeCompare(bstr) } ...})```### noResultsText (String) [optional]The HTML that will be shown if the query didn't match anything.### limit (Number) [optional]You can limit the number of posts rendered on the page.### fuzzy (Boolean) [optional]Enable fuzzy search to allow less restrictive matching.### exclude (Array) [optional]Pass in a list of terms you want to exclude (terms will be matched against a regex, so URLs, words are allowed).### success (Function) [optional]A function called once the data has been loaded.### debounceTime (Number) [optional]Limit how many times the search function can be executed over the given time window. This is especially useful to improve the user experience when searching over a large dataset (either with rare terms or because the number of posts to display is large). If no `debounceTime` (milliseconds) is provided a search will be triggered on each keystroke.---## If search isn't working due to invalid JSON- There is a filter plugin in the _plugins folder which should remove most characters that cause invalid JSON. To use it, add the simple_search_filter.rb file to your _plugins folder, and use `remove_chars` as a filter.For example: in search.json, replace```json"content": "{{ page.content | strip_html | strip_newlines }}"```with```json"content": "{{ page.content | strip_html | strip_newlines | remove_chars | escape }}"```If this doesn't work when using Github pages you can try `jsonify` to make sure the content is json compatible:```js"content": {{ page.content | jsonify }}```**Note: you don't need to use quotes `"` in this since `jsonify` automatically inserts them.**## Enabling full-text searchReplace `search.json` with the following code:```yaml---layout: none---[ {% for post in site.posts %} { "title" : "{{ post.title | escape }}", "category" : "{{ post.category }}", "tags" : "{{ post.tags | join: ', ' }}", "url" : "{{ site.baseurl }}{{ post.url }}", "date" : "{{ post.date }}", "content" : "{{ post.content | strip_html | strip_newlines }}" } {% unless forloop.last %},{% endunless %} {% endfor %} , {% for page in site.pages %} { {% if page.title != nil %} "title" : "{{ page.title | escape }}", "category" : "{{ page.category }}", "tags" : "{{ page.tags | join: ', ' }}", "url" : "{{ site.baseurl }}{{ page.url }}", "date" : "{{ page.date }}", "content" : "{{ page.content | strip_html | strip_newlines }}" {% endif %} } {% unless forloop.last %},{% endunless %} {% endfor %}]```## Development- `npm install`- `npm test`#### Acceptance tests```bashcd example; jekyll serve# in another tabnpm run cypress -- run```## ContributorsThanks to all [contributors](https://github.com/christian-fei/Simple-Jekyll-Search/graphs/contributors) over the years! You are the best :)> [@daviddarnes](https://github.com/daviddarnes)[@XhmikosR](https://github.com/XhmikosR)[@PeterDaveHello](https://github.com/PeterDaveHello)[@mikeybeck](https://github.com/mikeybeck)[@egladman](https://github.com/egladman)[@midzer](https://github.com/midzer)[@eduardoboucas](https://github.com/eduardoboucas)[@kremalicious](https://github.com/kremalicious)[@tibotiber](https://github.com/tibotiber)and many others!## Stargazers over time[](https://starchart.cc/christian-fei/Simple-Jekyll-Search)"
If this doesn’t work when using Github pages you can try jsonify
to make sure the content is json compatible:
1
"content": "# [Simple-Jekyll-Search](https://www.npmjs.com/package/simple-jekyll-search)\n\n[](https://travis-ci.org/christian-fei/Simple-Jekyll-Search)\n[](https://david-dm.org/christian-fei/Simple-Jekyll-Search)\n[](https://david-dm.org/christian-fei/Simple-Jekyll-Search?type=dev)\n\nA JavaScript library to add search functionality to any Jekyll blog.\n\n## Use case\n\nYou have a blog, built with Jekyll, and want a **lightweight search functionality** on your blog, purely client-side?\n\n*No server configurations or databases to maintain*.\n\nJust **5 minutes** to have a **fully working searchable blog**.\n\n---\n\n## Installation\n\n### npm\n\n```sh\nnpm install simple-jekyll-search\n```\n\n## Getting started\n\n### Create `search.json`\n\nPlace the following code in a file called `search.json` in the **root** of your Jekyll blog. (You can also get a copy [from here](/example/search.json))\n\nThis file will be used as a small data source to perform the searches on the client side:\n\n```yaml\n---\nlayout: none\n---\n[\n {% for post in site.posts %}\n {\n \"title\" : \"{{ post.title | escape }}\",\n \"category\" : \"{{ post.category }}\",\n \"tags\" : \"{{ post.tags | join: ', ' }}\",\n \"url\" : \"{{ site.baseurl }}{{ post.url }}\",\n \"date\" : \"{{ post.date }}\"\n } {% unless forloop.last %},{% endunless %}\n {% endfor %}\n]\n```\n\n\n## Preparing the plugin\n\n### Add DOM elements\n\nSimpleJekyllSearch needs two `DOM` elements to work:\n\n- a search input field\n- a result container to display the results\n\n#### Give me the code\n\nHere is the code you can use with the default configuration:\n\nYou need to place the following code within the layout where you want the search to appear. (See the configuration section below to customize it)\n\nFor example in **_layouts/default.html**:\n\n```html\n<!-- HTML elements for search -->\n<input type=\"text\" id=\"search-input\" placeholder=\"Search blog posts..\">\n<ul id=\"results-container\"></ul>\n\n<!-- or without installing anything -->\n<script src=\"https://unpkg.com/simple-jekyll-search@latest/dest/simple-jekyll-search.min.js\"></script>\n```\n\n\n## Usage\n\nCustomize SimpleJekyllSearch by passing in your configuration options:\n\n```js\nvar sjs = SimpleJekyllSearch({\n searchInput: document.getElementById('search-input'),\n resultsContainer: document.getElementById('results-container'),\n json: '/search.json'\n})\n```\n\n### returns { search }\n\nA new instance of SimpleJekyllSearch returns an object, with the only property `search`.\n\n`search` is a function used to simulate a user input and display the matching results. \n\nE.g.:\n\n```js\nvar sjs = SimpleJekyllSearch({ ...options })\nsjs.search('Hello')\n```\n\n💡 it can be used to filter posts by tags or categories!\n\n## Options\n\nHere is a list of the available options, usage questions, troubleshooting & guides.\n\n### searchInput (Element) [required]\n\nThe input element on which the plugin should listen for keyboard event and trigger the searching and rendering for articles.\n\n\n### resultsContainer (Element) [required]\n\nThe container element in which the search results should be rendered in. Typically a `<ul>`.\n\n\n### json (String|JSON) [required]\n\nYou can either pass in an URL to the `search.json` file, or the results in form of JSON directly, to save one round trip to get the data.\n\n\n### searchResultTemplate (String) [optional]\n\nThe template of a single rendered search result.\n\nThe templating syntax is very simple: You just enclose the properties you want to replace with curly braces.\n\nE.g.\n\nThe template\n\n```js\nvar sjs = SimpleJekyllSearch({\n searchInput: document.getElementById('search-input'),\n resultsContainer: document.getElementById('results-container'),\n json: '/search.json',\n searchResultTemplate: '<li><a href=\"{{ site.url }}{url}\">{title}</a></li>'\n})\n```\n\nwill render to the following\n\n```html\n<li><a href=\"/jekyll/update/2014/11/01/welcome-to-jekyll.html\">Welcome to Jekyll!</a></li>\n```\n\nIf the `search.json` contains this data\n\n```json\n[\n {\n \"title\" : \"Welcome to Jekyll!\",\n \"category\" : \"\",\n \"tags\" : \"\",\n \"url\" : \"/jekyll/update/2014/11/01/welcome-to-jekyll.html\",\n \"date\" : \"2014-11-01 21:07:22 +0100\"\n }\n]\n```\n\n\n### templateMiddleware (Function) [optional]\n\nA function that will be called whenever a match in the template is found.\n\nIt gets passed the current property name, property value, and the template.\n\nIf the function returns a non-undefined value, it gets replaced in the template.\n\nThis can be potentially useful for manipulating URLs etc.\n\nExample:\n\n```js\nSimpleJekyllSearch({\n ...\n templateMiddleware: function(prop, value, template) {\n if (prop === 'bar') {\n return value.replace(/^\\//, '')\n }\n }\n ...\n})\n```\n\nSee the [tests](https://github.com/christian-fei/Simple-Jekyll-Search/blob/master/tests/Templater.test.js) for an in-depth code example\n\n### sortMiddleware (Function) [optional]\n\nA function that will be used to sort the filtered results.\n\nIt can be used for example to group the sections together.\n\nExample:\n\n```js\nSimpleJekyllSearch({\n ...\n sortMiddleware: function(a, b) {\n var astr = String(a.section) + \"-\" + String(a.caption);\n var bstr = String(b.section) + \"-\" + String(b.caption);\n return astr.localeCompare(bstr)\n }\n ...\n})\n```\n\n### noResultsText (String) [optional]\n\nThe HTML that will be shown if the query didn't match anything.\n\n\n### limit (Number) [optional]\n\nYou can limit the number of posts rendered on the page.\n\n\n### fuzzy (Boolean) [optional]\n\nEnable fuzzy search to allow less restrictive matching.\n\n### exclude (Array) [optional]\n\nPass in a list of terms you want to exclude (terms will be matched against a regex, so URLs, words are allowed).\n\n### success (Function) [optional]\n\nA function called once the data has been loaded.\n\n### debounceTime (Number) [optional]\n\nLimit how many times the search function can be executed over the given time window. This is especially useful to improve the user experience when searching over a large dataset (either with rare terms or because the number of posts to display is large). If no `debounceTime` (milliseconds) is provided a search will be triggered on each keystroke.\n\n---\n\n## If search isn't working due to invalid JSON\n\n- There is a filter plugin in the _plugins folder which should remove most characters that cause invalid JSON. To use it, add the simple_search_filter.rb file to your _plugins folder, and use `remove_chars` as a filter.\n\nFor example: in search.json, replace\n\n```json\n\"content\": \"{{ page.content | strip_html | strip_newlines }}\"\n```\n\nwith\n\n```json\n\"content\": \"{{ page.content | strip_html | strip_newlines | remove_chars | escape }}\"\n```\n\nIf this doesn't work when using Github pages you can try `jsonify` to make sure the content is json compatible:\n\n```js\n\"content\": {{ page.content | jsonify }}\n```\n\n**Note: you don't need to use quotes `\"` in this since `jsonify` automatically inserts them.**\n\n\n## Enabling full-text search\n\nReplace `search.json` with the following code:\n\n```yaml\n---\nlayout: none\n---\n[\n {% for post in site.posts %}\n {\n \"title\" : \"{{ post.title | escape }}\",\n \"category\" : \"{{ post.category }}\",\n \"tags\" : \"{{ post.tags | join: ', ' }}\",\n \"url\" : \"{{ site.baseurl }}{{ post.url }}\",\n \"date\" : \"{{ post.date }}\",\n \"content\" : \"{{ post.content | strip_html | strip_newlines }}\"\n } {% unless forloop.last %},{% endunless %}\n {% endfor %}\n ,\n {% for page in site.pages %}\n {\n {% if page.title != nil %}\n \"title\" : \"{{ page.title | escape }}\",\n \"category\" : \"{{ page.category }}\",\n \"tags\" : \"{{ page.tags | join: ', ' }}\",\n \"url\" : \"{{ site.baseurl }}{{ page.url }}\",\n \"date\" : \"{{ page.date }}\",\n \"content\" : \"{{ page.content | strip_html | strip_newlines }}\"\n {% endif %}\n } {% unless forloop.last %},{% endunless %}\n {% endfor %}\n]\n```\n\n\n\n## Development\n\n- `npm install`\n- `npm test`\n\n#### Acceptance tests\n\n```bash\ncd example; jekyll serve\n\n# in another tab\n\nnpm run cypress -- run\n```\n\n## Contributors\n\nThanks to all [contributors](https://github.com/christian-fei/Simple-Jekyll-Search/graphs/contributors) over the years! You are the best :)\n\n> [@daviddarnes](https://github.com/daviddarnes)\n[@XhmikosR](https://github.com/XhmikosR)\n[@PeterDaveHello](https://github.com/PeterDaveHello)\n[@mikeybeck](https://github.com/mikeybeck)\n[@egladman](https://github.com/egladman)\n[@midzer](https://github.com/midzer)\n[@eduardoboucas](https://github.com/eduardoboucas)\n[@kremalicious](https://github.com/kremalicious)\n[@tibotiber](https://github.com/tibotiber)\nand many others!\n\n## Stargazers over time\n\n[](https://starchart.cc/christian-fei/Simple-Jekyll-Search)\n"
Note: you don’t need to use quotes "
in this since jsonify
automatically inserts them.
Enabling full-text search
Replace search.json
with the following code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
---
layout: none
---
[
{
"title" : "Introduction to character animation",
"category" : "",
"tags" : "yellow",
"url" : "/Skinned_Meshes/",
"date" : "2022-07-06 00:00:00 +0000",
"content" : "hello root onlyIntroduction to character animation什么是角色动画让角色自然运动的方式Techniques such as skeletal animation, morphing,ragdoll physic simulation, and inverse kinematics have already existed for a long time skeletalanimation for overall movement, and morphing animation for more subtlethings like facial expressions. Tool that captures state from actors and then displays it visually in game or editor. 读取游戏中的Actor中的状态数据,然后可视化的显示在UnityEditor里 替换DLL,Hook,实时修改Runtime数据 https://docs.unrealengine.com/4.27/en-US/TestingAndOptimization/VisualLogger/ 帧同步Log Gameplay Debugger(虚幻调试器)对于开发者查看运行时数据非常有用为实现可视化调试如何设计游戏代码 逻辑和表现分离? 龙之谷为什么不能直接进入场景调试GamePlay ?"
} ,
{
"title" : "skeleton animation cpu skinning",
"category" : "",
"tags" : "yellow",
"url" : "/skeleton_animation_cpu_skinning/",
"date" : "2022-07-05 00:00:00 +0000",
"content" : "skeleton animation骨骼蒙皮从上图可以看出Hips骨骼对顶点的影响权重,一个顶点可以被多个骨骼影响。蒙皮绑定权重在gltf的数据如下JOINTS_0存储了骨骼索引WEIGHTS_0存储了对应的骨骼权重计算Mesh顶点在模型空间中的位置12345678910111213141516171819202122232425262728293031323334353637383940414243layout (location = 0) in vec3 inPos;layout (location = 1) in vec3 inNormal;layout (location = 2) in vec2 inUV;layout (location = 3) in vec3 inColor;layout (location = 4) in vec4 inJointIndices;layout (location = 5) in vec4 inJointWeights;layout (set = 0, binding = 0) uniform UBOScene{ mat4 projection; mat4 view; vec4 lightPos;} uboScene;layout(push_constant) uniform PushConsts { mat4 model;} primitive;layout(std430, set = 1, binding = 0) readonly buffer JointMatrices { mat4 jointMatrices[];};layout (location = 0) out vec3 outNormal;layout (location = 1) out vec3 outColor;layout (location = 2) out vec2 outUV;layout (location = 3) out vec3 outViewVec;layout (location = 4) out vec3 outLightVec;void main() { outNormal = inNormal; outColor = inColor; outUV = inUV; // Calculate skinned matrix from weights and joint indices of the current vertex mat4 skinMat = inJointWeights.x * jointMatrices[int(inJointIndices.x)] + inJointWeights.y * jointMatrices[int(inJointIndices.y)] + inJointWeights.z * jointMatrices[int(inJointIndices.z)] + inJointWeights.w * jointMatrices[int(inJointIndices.w)]; gl_Position = uboScene.projection * uboScene.view * primitive.model * skinMat * vec4(inPos.xyz, 1.0);}gltf中的绑定矩阵数据如下inPos是顶点在BindPose下模型空间中的位置,inverseBindMatrices矩阵对应某一骨骼空间到模型空间的变换矩阵的逆矩阵,可将inPos顶点变换到骨骼的局部空间中的位置Bone_local_pos,然后将动画某一帧所确定的骨骼空间到模型空间的变换矩阵乘以Bone_local_pos,得到新的模型空间下的顶点位置。123456789101112131415glm::mat4 vkglTF::Model::getNodeMatrix(vkglTF::Node* node){ glm::mat4 nodeMatrix = node->localMatrix(); vkglTF::Node* currentParent = node->parent; while (currentParent) { nodeMatrix = currentParent->localMatrix() * nodeMatrix; currentParent = currentParent->parent; } return nodeMatrix;}glm::mat4 vkglTF::Node::localMatrix() { return glm::translate(glm::mat4(1.0f), translation) * glm::mat4(rotation) * glm::scale(glm::mat4(1.0f), scale) * matrix;}getNodeMatrix()函数计算出骨骼空间到模型空间的变换矩阵。由localMatrix()函数中的translation,rotation,scale从动画信息中各channel中关键帧中采样即可得到,代码如下12345678910111213141516171819202122232425262728293031323334353637383940for (auto& channel : animation.channels) { vkglTF::AnimationSampler &sampler = animation.samplers[channel.samplerIndex]; if (sampler.inputs.size() > sampler.outputsVec4.size()) { continue; } for (auto i = 0; i < sampler.inputs.size() - 1; i++) { if ((animation.currentTime >= sampler.inputs[i]) && (animation.currentTime <= sampler.inputs[i + 1])) { float u = std::max(0.0f, animation.currentTime - sampler.inputs[i]) / (sampler.inputs[i + 1] - sampler.inputs[i]); if (u <= 1.0f) { switch (channel.path) { case vkglTF::AnimationChannel::PathType::TRANSLATION: { glm::vec4 trans = glm::mix(sampler.outputsVec4[i], sampler.outputsVec4[i + 1], u); channel.node->translation = glm::vec3(trans); break; } case vkglTF::AnimationChannel::PathType::SCALE: { glm::vec4 trans = glm::mix(sampler.outputsVec4[i], sampler.outputsVec4[i + 1], u); channel.node->scale = glm::vec3(trans); break; } case vkglTF::AnimationChannel::PathType::ROTATION: { glm::quat q1; q1.x = sampler.outputsVec4[i].x; q1.y = sampler.outputsVec4[i].y; q1.z = sampler.outputsVec4[i].z; q1.w = sampler.outputsVec4[i].w; glm::quat q2; q2.x = sampler.outputsVec4[i + 1].x; q2.y = sampler.outputsVec4[i + 1].y; q2.z = sampler.outputsVec4[i + 1].z; q2.w = sampler.outputsVec4[i + 1].w; channel.node->rotation = glm::normalize(glm::slerp(q1, q2, u)); break; } } } } } }JointMatrices = getNodeMatrix() * inverseBindMatrices将JointMatrices数据传入顶点着色器中,渲染效果如下:"
} ,
{
"title" : "skeleton animation bind pose",
"category" : "",
"tags" : "yellow",
"url" : "/skeleton_animation_bind_pose/",
"date" : "2022-07-05 00:00:00 +0000",
"content" : "skeleton animation骨骼动画之前向动力学把大摆锤上的游客当成动画角色网格上的顶点,每个游客的位置就是摆锤末端的位置加上游客相对摆锤末端的位移。Bind Pose确定游客相对摆锤末端的位移前向动力学确定摆锤末端的位置从上图可以看出关节(摆锤末端)坐标系到模型空间(root节点为中心的空间)的变换,就是根节点到该关节的变换矩阵之乘积计算骨骼节点初始状态的位置inverseBindMatrices用来快速计算顶点在对应骨骼中的相对位置(所谓的骨骼空间),后面章节会用到我们将从动画根骨骼(Hips)开始计算各个骨骼节点的位置,注意Hips骨骼的父节点才是根节点(在模型空间的位置为vector3.zero)。代码流程gltf中的”nodes”节点中包含了骨骼节点的初始变换矩阵1234getLocalMatrix(){ return glm::translate(glm::mat4(1.0f), translation) * glm::mat4(rotation) * glm::scale(glm::mat4(1.0f), scale);}从根节点开始广度遍历,计算出各个骨骼节点在模型空间中的位置123456789101112131415161718void GetNodePos(glm::mat4 parentMat/*,glm::vec4 pos*/, std::vector<ShaderVertex>& pos,std::vector<uint16_t>& indices){ auto matrix = getLocalMatrix(); parentMat = parentMat * matrix; auto nodePos = parentMat * glm::vec4(0, 0, 0, 1); ShaderVertex vertex{ {nodePos[0],nodePos[1],nodePos[2]} }; //vertex.color = glm::vec3(1.0f, 0.0f, 0.0f); vertex.color = glm::vec3(pos.size() / 20.0f, 0.0f, 0.0f); pos.push_back(vertex); auto parentIndex = pos.size() - 1; for (size_t i = 0; i < children.size(); i++) { indices.push_back(parentIndex); indices.push_back(parentIndex + 1); children[i]->GetNodePos(parentMat,pos,indices); }}将骨骼节点的位置以线的模式渲染效果如下:"
} ,
{
"title" : "skeleton animation binding pose",
"category" : "",
"tags" : "yellow",
"url" : "/introduction_to_character_animation/",
"date" : "2022-07-05 00:00:00 +0000",
"content" : "Introduction to character animation角色动画之前向动力学让角色自然运动的方式Techniques such as skeletal animation, morphing,ragdoll physic simulation, and inverse kinematics have already existed for a long time skeletalanimation for overall movement, and morphing animation for more subtlethings like facial expressions. Tool that captures state from actors and then displays it visually in game or editor. 读取游戏中的Actor中的状态数据,然后可视化的显示在UnityEditor里 替换DLL,Hook,实时修改Runtime数据 https://docs.unrealengine.com/4.27/en-US/TestingAndOptimization/VisualLogger/ 帧同步Log Gameplay Debugger(虚幻调试器)对于开发者查看运行时数据非常有用为实现可视化调试如何设计游戏代码 逻辑和表现分离? 龙之谷为什么不能直接进入场景调试GamePlay ?"
} ,
{
"title" : "Metaprogramming",
"category" : "",
"tags" : "",
"url" : "/metaprogramming/",
"date" : "2021-10-12 00:00:00 +0000",
"content" : ""
} ,
{
"title" : "math vector",
"category" : "",
"tags" : "red, yellow",
"url" : "/vector/",
"date" : "2021-10-12 00:00:00 +0000",
"content" : "球形差值"
} ,
{
"title" : "urp begining",
"category" : "",
"tags" : "red, yellow",
"url" : "/urp-begining/",
"date" : "2021-10-11 00:00:00 +0000",
"content" : "渲染要处理的对象 摄像机 场景物体 光照 [输出]屏幕、颜色空间 lightMode?"
} ,
{
"title" : "gameplay debug",
"category" : "",
"tags" : "red, yellow",
"url" : "/gameplay-replay/",
"date" : "2021-10-10 00:00:00 +0000",
"content" : "https://docs.unrealengine.com/4.27/en-US/TestingAndOptimization/ReplaySystem/"
} ,
{
"title" : "gameplay debug",
"category" : "",
"tags" : "red, yellow",
"url" : "/Script-Binding/",
"date" : "2021-10-10 00:00:00 +0000",
"content" : "不同编程语言的程序可不可以通过接口相互调用?https://www.zhihu.com/question/20542360https://zhuanlan.zhihu.com/p/281059891lua c++ commucate with stackc# c++FFI(Foreign Function Interface)机制"
} ,
{
"title" : "Game Hacking",
"category" : "",
"tags" : "red, yellow",
"url" : "/Introduction-to-game-hackiing/",
"date" : "2021-09-13 00:00:00 +0000",
"content" : "Review products, books, movies, restaurant and anything you like on your Jekyll blog with Mediumish! JSON-LD ready for review property.How to use?It’s actually really simple! Add the rating in your YAML front matter. It also supports halfs:hello root only12345678910---layout: posttitle: "Inception Movie"author: johncategories: [ Jekyll, tutorial ]tags: [red, yellow]image: assets/images/11.jpgdescription: "My review of Inception movie. Actors, directing and more."rating: 4.5---"
} ,
{
"title" : "thirties(致30岁)",
"category" : "",
"tags" : "yellow",
"url" : "/thirties/",
"date" : "2021-09-11 00:00:00 +0000",
"content" : "曾经的你演唱:许巍曾梦想仗剑走天涯看一看世界的繁华年少的心总有些轻狂如今你四海为家曾让你心疼的姑娘如今已悄然无踪影爱情总让你渴望又感到烦恼曾让你遍体鳞伤DiLiLi… DiLiLi… DiLiLi…走在勇往直前的路上DiLiLi…DiLiLi…DiLiLi…有难过也有精彩每一次难过的时候就独自看一看大海总想起身边走在路上的朋友 有多少正在疗伤DiLiLi…DiLiLi…DiLiLi…不知多少孤独的夜晚DiLiLi…DiLiLi…DiLiLi…从昨夜酒醉醒来每一次难过的时候就独自看一看大海总想起身边走在路上的朋友有多少正在醒来让我们干了这杯酒好男儿胸怀像大海经历了人生百态世间的冷暖这笑容温暖纯真每一次难过的时候就独自看一看大海总想起身边走在路上的朋友有多少正在醒来让我们干了这杯酒好男儿胸怀像大海经历了人生百态世间的冷暖这笑容温暖纯真"
} ,
{
"title" : "thirties",
"category" : "",
"tags" : "red, yellow",
"url" : "/never_settle_down/",
"date" : "2021-09-11 00:00:00 +0000",
"content" : "曾经的你演唱:许巍曾梦想仗剑走天涯看一看世界的繁华年少的心总有些轻狂如今你四海为家曾让你心疼的姑娘如今已悄然无踪影爱情总让你渴望又感到烦恼曾让你遍体鳞伤DiLiLi… DiLiLi… DiLiLi…走在勇往直前的路上DiLiLi…DiLiLi…DiLiLi…有难过也有精彩每一次难过的时候就独自看一看大海总想起身边走在路上的朋友 有多少正在疗伤DiLiLi…DiLiLi…DiLiLi…不知多少孤独的夜晚DiLiLi…DiLiLi…DiLiLi…从昨夜酒醉醒来每一次难过的时候就独自看一看大海总想起身边走在路上的朋友有多少正在醒来让我们干了这杯酒好男儿胸怀像大海经历了人生百态世间的冷暖这笑容温暖纯真每一次难过的时候就独自看一看大海总想起身边走在路上的朋友有多少正在醒来让我们干了这杯酒好男儿胸怀像大海经历了人生百态世间的冷暖这笑容温暖纯真"
} ,
{
"title" : "IlluminationMode",
"category" : "",
"tags" : "red, yellow",
"url" : "/Lighting-Mode/",
"date" : "2020-10-01 00:00:00 +0000",
"content" : "三.光照模型(illumination model)当光照射到物体表面时,物体对光会发生反射、透射、吸收、衍射、折射、和干涉,其中被物体吸收的部分转化为热,反射、透射的光进入人的视觉系统,使我们能看见物体。为模拟这一现象,我们建立一些数学模型来替代复杂的物理模型,这些模型就称为明暗效应模型或者光照明模型。 局部光照 处理光源直接照射物体表面的光照明模型被称为局部光照明模型 全局光照 全局光照模型是基于光学物理原理的,光照强度的计算依赖于光能在现实世界中的传播情况,考虑光线与整个场景中各物体表面及物体表面间的相互影响,包括多次反射 、透射 、散射等Blin-Phone Lighting diffuse + spectular 变量(光线方向,物体表面法线,视角方向)如何解决自然现象 菲涅尔现象 次表面反射 How to use?It’s actually really simple! Add the rating in your YAML front matter. It also supports halfs:hello root only12345678910---layout: posttitle: "Inception Movie"author: johncategories: [ Jekyll, tutorial ]tags: [red, yellow]image: assets/images/11.jpgdescription: "My review of Inception movie. Actors, directing and more."rating: 4.5---"
} ,
{
"title" : "my chaper",
"category" : "",
"tags" : "red, yellow",
"url" : "/preface/",
"date" : "2019-01-01 00:00:00 +0000",
"content" : "beforesupports halfs:in chaptersupports halfs:"
} ,
{
"title" : "Powerful things you can do with the Markdown editor",
"category" : "",
"tags" : "",
"url" : "/powerful-things-markdown-editor/",
"date" : "2018-06-12 00:00:00 +0000",
"content" : "There are lots of powerful things you can do with the Markdown editor. If you’ve gotten pretty comfortable with writing in Markdown, then you may enjoy some more advanced tips about the types of things you can do with Markdown!As with the last post about the editor, you’ll want to be actually editing this post as you read it so that you can see all the Markdown code we’re using.Special formattingAs well as bold and italics, you can also use some other special formatting in Markdown when the need arises, for example: strike through ==highlight== *escaped characters*Writing code blocksThere are two types of code elements which can be inserted in Markdown, the first is inline, and the other is block. Inline code is formatted by wrapping any word or words in back-ticks, like this. Larger snippets of code can be displayed across multiple lines using triple back ticks:123.my-link { text-decoration: underline;}HTML12345<li class="ml-1 mr-1"> <a target="_blank" href="#"> <i class="fab fa-twitter"></i> </a></li>CSS12345678.highlight .c { color: #999988; font-style: italic; }.highlight .err { color: #a61717; background-color: #e3d2d2; }JS123456789// alertbar later$(document).scroll(function () { var y = $(this).scrollTop(); if (y > 280) { $('.alertbar').fadeIn(); } else { $('.alertbar').fadeOut(); }});Python1print("Hello World")Ruby123require 'redcarpet'markdown = Redcarpet.new("Hello World!")puts markdown.to_htmlC1printf("Hello World");Reference listsThe quick brown jumped over the lazy.Another way to insert links in markdown is using reference lists. You might want to use this style of linking to cite reference material in a Wikipedia-style. All of the links are listed at the end of the document, so you can maintain full separation between content and its source or reference.Full HTMLPerhaps the best part of Markdown is that you’re never limited to just Markdown. You can write HTML directly in the Markdown editor and it will just work as HTML usually does. No limits! Here’s a standard YouTube embed code as an example:"
} ,
{
"title" : "The first mass-produced book to deviate from a rectilinear format",
"category" : "",
"tags" : "",
"url" : "/first-mass-produced/",
"date" : "2018-06-12 00:00:00 +0000",
"content" : "The first mass-produced book to deviate from a rectilinear format, at least in the United States, is thought to be this 1863 edition of Red Riding Hood, cut into the shape of the protagonist herself with the troublesome wolf curled at her feet. Produced by the Boston-based publisher Louis Prang, this is the first in their “Doll Series”, a set of five “die-cut” books, known also as shape books — the other titles being Robinson Crusoe, Goody Two-Shoes (also written by Red Riding Hood author Lydia Very), Cinderella, and King Winter.An 1868 Prang catalogue would later claim that such “books in the shape of a regular paper Doll… originated with us”. It would seem the claim could also extend to die cut books in general, as we can’t find anything sooner, but do let us know in the comments if you have further light to shed on this! Such books are, of course, still popular in children’s publishing today, though the die cutting is not now limited to mere outlines, as evidenced in a beautiful 2014 version of the same Little Red Riding Hood story.The die cut has also been employed in the non-juvenile sphere as well, a recent example being Jonathan Safran Foer’s ambitious Tree of Codes.As for this particular rendition of Charles Perrault’s classic tale, the text and design is by Lydia Very (1823-1901), sister of Transcendentalist poet Jones Very. The gruesome ending of the original - which sees Little Red Riding Hood being gobbled up as well as her grandmother - is avoided here, the gore giving way to the less bloody aims of the morality tale, and the lesson that one should not disobey one’s mother."
} ,
{
"title" : "Education must also train one for quick, resolute and effective thinking.",
"category" : "",
"tags" : "",
"url" : "/education/",
"date" : "2018-06-12 00:00:00 +0000",
"content" : "There are lots of powerful things you can do with the Markdown editorIf you’ve gotten pretty comfortable with writing in Markdown, then you may enjoy some more advanced tips about the types of things you can do with Markdown!As with the last post about the editor, you’ll want to be actually editing this post as you read it so that you can see all the Markdown code we’re using.Special formattingAs well as bold and italics, you can also use some other special formatting in Markdown when the need arises, for example: strike through ==highlight== *escaped characters*Writing code blocksThere are two types of code elements which can be inserted in Markdown, the first is inline, and the other is block. Inline code is formatted by wrapping any word or words in back-ticks, like this. Larger snippets of code can be displayed across multiple lines using triple back ticks:123.my-link { text-decoration: underline;}If you want to get really fancy, you can even add syntax highlighting using Rouge.Reference listsThe quick brown jumped over the lazy.Another way to insert links in markdown is using reference lists. You might want to use this style of linking to cite reference material in a Wikipedia-style. All of the links are listed at the end of the document, so you can maintain full separation between content and its source or reference.Full HTMLPerhaps the best part of Markdown is that you’re never limited to just Markdown. You can write HTML directly in the Markdown editor and it will just work as HTML usually does. No limits! Here’s a standard YouTube embed code as an example:"
} ,
{
"title" : "Accumulated experience of social living",
"category" : "",
"tags" : "",
"url" : "/acumulated-experience/",
"date" : "2018-06-12 00:00:00 +0000",
"content" : "The die cut has also been employed in the non-juvenile sphere as well, a recent example being Jonathan Safran Foer’s ambitious Tree of Codes.As for this particular rendition of Charles Perrault’s classic tale, the text and design is by Lydia Very (1823-1901), sister of Transcendentalist poet Jones Very. The gruesome ending of the original - which sees Little Red Riding Hood being gobbled up as well as her grandmother - is avoided here, the gore giving way to the less bloody aims of the morality tale, and the lesson that one should not disobey one’s mother.The first mass-produced book to deviate from a rectilinear format, at least in the United States, is thought to be this 1863 edition of Red Riding Hood, cut into the shape of the protagonist herself with the troublesome wolf curled at her feet. Produced by the Boston-based publisher Louis Prang, this is the first in their “Doll Series”, a set of five “die-cut” books, known also as shape books — the other titles being Robinson Crusoe, Goody Two-Shoes (also written by Red Riding Hood author Lydia Very), Cinderella, and King Winter.An 1868 Prang catalogue would later claim that such “books in the shape of a regular paper Doll… originated with us”. It would seem the claim could also extend to die cut books in general, as we can’t find anything sooner, but do let us know in the comments if you have further light to shed on this! Such books are, of course, still popular in children’s publishing today, though the die cutting is not now limited to mere outlines, as evidenced in a beautiful 2014 version of the same Little Red Riding Hood story."
} ,
{
"title" : "About Bundler",
"category" : "",
"tags" : "",
"url" : "/about-bundler/",
"date" : "2018-05-12 00:00:00 +0000",
"content" : "gem install bundler installs the bundler gem through RubyGems. You only need to install it once - not every time you create a new Jekyll project. Here are some additional details:bundler is a gem that manages other Ruby gems. It makes sure your gems and gem versions are compatible, and that you have all necessary dependencies each gem requires.The Gemfile and Gemfile.lock files inform Bundler about the gem requirements in your site. If your site doesn’t have these Gemfiles, you can omit bundle exec and just run jekyll serve.When you run bundle exec jekyll serve, Bundler uses the gems and versions as specified in Gemfile.lock to ensure your Jekyll site builds with no compatibility or dependency conflicts.For more information about how to use Bundler in your Jekyll project, this tutorial should provide answers to the most common questions and explain how to get up and running quickly."
} ,
{
"title" : "We all wait for summer",
"category" : "",
"tags" : "",
"url" : "/we-all-wait-for-summer/",
"date" : "2018-01-12 00:00:00 +0000",
"content" : "As I engage in the so-called “bull sessions” around and about the school, I too often find that most college men have a misconception of the purpose of education. Most of the “brethren” think that education should equip them with the proper instruments of exploitation so that they can forever trample over the masses. Still others think that education should furnish them with noble ends rather than means to an end.It seems to me that education has a two-fold function to perform in the life of man and in society: the one is utility and the other is culture. Education must enable a man to become more efficient, to achieve with increasing facility the ligitimate goals of his life."
} ,
{
"title" : "Tree of Codes",
"category" : "",
"tags" : "",
"url" : "/tree-of-codes/",
"date" : "2018-01-12 00:00:00 +0000",
"content" : "The first mass-produced book to deviate from a rectilinear format, at least in the United States, is thought to be this 1863 edition of Red Riding Hood, cut into the shape of the protagonist herself with the troublesome wolf curled at her feet. Produced by the Boston-based publisher Louis Prang, this is the first in their “Doll Series”, a set of five “die-cut” books, known also as shape books — the other titles being Robinson Crusoe, Goody Two-Shoes (also written by Red Riding Hood author Lydia Very), Cinderella, and King Winter.As for this particular rendition of Charles Perrault’s classic tale, the text and design is by Lydia Very (1823-1901), sister of Transcendentalist poet Jones Very. The gruesome ending of the original — which sees Little Red Riding Hood being gobbled up as well as her grandmother — is avoided here, the gore giving way to the less bloody aims of the morality tale, and the lesson that one should not disobey one’s mother. It would seem the claim could also extend to die cut books in general, as we can’t find anything sooner, but do let us know in the comments if you have further light to shed on this! Such books are, of course, still popular in children’s publishing today, though the die cutting is not now limited to mere outlines, as evidenced in a beautiful 2014 version of the same Little Red Riding Hood story.An 1868 Prang catalogue would later claim that such “books in the shape of a regular paper Doll… originated with us”.The die cut has also been employed in the non-juvenile sphere as well, a recent example being Jonathan Safran Foer’s ambitious Tree of Codes."
} ,
{
"title" : "Red Riding Hood",
"category" : "",
"tags" : "",
"url" : "/red-riding/",
"date" : "2018-01-12 00:00:00 +0000",
"content" : "The first mass-produced book to deviate from a rectilinear format, at least in the United States, is thought to be this 1863 edition of Red Riding Hood, cut into the shape of the protagonist herself with the troublesome wolf curled at her feet. Produced by the Boston-based publisher Louis Prang, this is the first in their “Doll Series”, a set of five “die-cut” books, known also as shape books — the other titles being Robinson Crusoe, Goody Two-Shoes (also written by Red Riding Hood author Lydia Very), Cinderella, and King Winter.An 1868 Prang catalogue would later claim that such “books in the shape of a regular paper Doll… originated with us”. It would seem the claim could also extend to die cut books in general, as we can’t find anything sooner, but do let us know in the comments if you have further light to shed on this! Such books are, of course, still popular in children’s publishing today, though the die cutting is not now limited to mere outlines, as evidenced in a beautiful 2014 version of the same Little Red Riding Hood story.The die cut has also been employed in the non-juvenile sphere as well, a recent example being Jonathan Safran Foer’s ambitious Tree of Codes.As for this particular rendition of Charles Perrault’s classic tale, the text and design is by Lydia Very (1823-1901), sister of Transcendentalist poet Jones Very. The gruesome ending of the original — which sees Little Red Riding Hood being gobbled up as well as her grandmother — is avoided here, the gore giving way to the less bloody aims of the morality tale, and the lesson that one should not disobey one’s mother."
} ,
{
"title" : "Press and education",
"category" : "",
"tags" : "",
"url" : "/press-and-education/",
"date" : "2018-01-12 00:00:00 +0000",
"content" : "Even the press, the classroom, the platform, and the pulpit in many instances do not give us objective and unbiased truths. To save man from the morass of propaganda, in my opinion, is one of the chief aims of education. Education must enable one to sift and weigh evidence, to discern the true from the false, the real from the unreal, and the facts from the fiction.Education must also train one for quick, resolute and effective thinking. To think incisively and to think for one’s self is very difficult. We are prone to let our mental life become invaded by legions of half truths, prejudices, and propaganda. At this point, I often wonder whether or not education is fulfilling its purpose. A great majority of the so-called educated people do not think logically and scientifically.The function of education, therefore, is to teach one to think intensively and to think critically. But education which stops with efficiency may prove the greatest menace to society. The most dangerous criminal may be the man gifted with reason, but with no morals.The late Eugene Talmadge, in my opinion, possessed one of the better minds of Georgia, or even America. Moreover, he wore the Phi Beta Kappa key. By all measuring rods, Mr. Talmadge could think critically and intensively; yet he contends that I am an inferior being. Are those the types of men we call educated?We must remember that intelligence is not enough. Intelligence plus character–that is the goal of true education. The complete education gives one not only power of concentration, but worthy objectives upon which to concentrate. The broad education will, therefore, transmit to one not only the accumulated knowledge of the race but also the accumulated experience of social living."
} ,
{
"title" : "Options for creating a new site with Jekyll",
"category" : "",
"tags" : "",
"url" : "/options-for-creating-new-site-with-jekyll/",
"date" : "2018-01-12 00:00:00 +0000",
"content" : "jekyll new <PATH> installs a new Jekyll site at the path specified (relative to current directory). In this case, Jekyll will be installed in a directory called myblog. Here are some additional details: To install the Jekyll site into the directory you’re currently in, run jekyll new . If the existing directory isn’t empty, you can pass the –force option with jekyll new . –force. jekyll new automatically initiates bundle install to install the dependencies required. (If you don’t want Bundler to install the gems, use jekyll new myblog --skip-bundle.) By default, the Jekyll site installed by jekyll new uses a gem-based theme called Minima. With gem-based themes, some of the directories and files are stored in the theme-gem, hidden from your immediate view. We recommend setting up Jekyll with a gem-based theme but if you want to start with a blank slate, use jekyll new myblog --blank To learn about other parameters you can include with jekyll new, type jekyll new --help."
} ,
{
"title" : "Never stopped worrying or loving the bomb",
"category" : "",
"tags" : "",
"url" : "/never-stopped-worrying-never-loved-bomb/",
"date" : "2018-01-12 00:00:00 +0000",
"content" : " I’ve been through fire and water, I tell you! From my earliest pebblehood the wildest things you could imagine have been happening to this world of ours, and I have been right in the midst of them.So begins Hallam Hawksworth’s The Strange Adventures of a Pebble. Written in the 1920s, the book was part of a series which also included The Adventures of a Grain of Dust and A Year in the Wonderland of Trees, all of which were supposed to introduce children to the world of Natural Sciences. In each of them, Hawksworth personifies the natural object he is exploring, and using a mixture of folk tales, scientific facts and colloquial, friendly explanations guides the reader through the history of the natural world. It’s a real thrill of a ride, dramatizing the life cycle of supposedly dull things. The Adventures of a Grain of Dust begins even more loudly than Pebble:I don’t want you to think that I’m boasting, but I do believe I’m one of the greatest travellers that ever was; and if anybody, living or dead, has ever gone through with more than I have I’d like to hear about it.Hallam Hawksworth was the pen-name of teacher Francis Blake Atkinson. He was married to the author Eleanor Stackhouse Atkinson, author of the children’s classic Greyfriars Bobby, which was based on the (supposedly) true story of a Scottish dog who spent fourteen years guarding his masters grave. The couple were both committed to education and published a weekly magazine for Chicago high school students called The Little Chronicle, as well as working for Encyclopaedia companies later in life."
} ,
{
"title" : "External Featured Image",
"category" : "",
"tags" : "",
"url" : "/is-intelligence-enough/",
"date" : "2018-01-12 00:00:00 +0000",
"content" : "Education must also train one for quick, resolute and effective thinking. To think incisively and to think for one’s self is very difficult. We are prone to let our mental life become invaded by legions of half truths, prejudices, and propaganda. At this point, I often wonder whether or not education is fulfilling its purpose. A great majority of the so-called educated people do not think logically and scientifically.Even the press, the classroom, the platform, and the pulpit in many instances do not give us objective and unbiased truths. To save man from the morass of propaganda, in my opinion, is one of the chief aims of education. Education must enable one to sift and weigh evidence, to discern the true from the false, the real from the unreal, and the facts from the fiction.The function of education, therefore, is to teach one to think intensively and to think critically. But education which stops with efficiency may prove the greatest menace to society. The most dangerous criminal may be the man gifted with reason, but with no morals.The late Eugene Talmadge, in my opinion, possessed one of the better minds of Georgia, or even America. Moreover, he wore the Phi Beta Kappa key. By all measuring rods, Mr. Talmadge could think critically and intensively; yet he contends that I am an inferior being. Are those the types of men we call educated?We must remember that intelligence is not enough. Intelligence plus character–that is the goal of true education. The complete education gives one not only power of concentration, but worthy objectives upon which to concentrate. The broad education will, therefore, transmit to one not only the accumulated knowledge of the race but also the accumulated experience of social living."
} ,
{
"title" : "Let's test spoilers",
"category" : "",
"tags" : "",
"url" : "/quick-start-guide/",
"date" : "2018-01-11 00:00:00 +0000",
"content" : "Director Roland Suso Richter’s enigmatic psychological thriller (direct to video/DVD) was based upon screenwriter Michael Cooney’s own play “Point of Death” - a title that gave away the film’s entire plot twist premise.As in many similar films, such as Jacob’s Ladder (1990), Soul Survivors (2001), and The Butterfly Effect (2004), events and people were thoroughly distorted and confused because the protagonist was at the point of death. The tagline was misleading:“When You Don’t Have a Memory, How Can You Remember Who to Trust?”The mind-warping film opened with a hospital patient Simon Cable (Ryan Phillippe) awakening in a hospital with little knowledge (amnesia perhaps?) of what had happened, and why he was there, etc. He was told by attending Dr. Jeremy Newman (Stephen Rea) that it was July 29, 2002 (Simon thought it was the year 2000 - he was confused - he heard a doctor say 20:00 hours!) and that he had died for two minutes from cardiac arrest following the near-fatal accident – but he had been revived (“You’re as good as new”). Dr. Newman: “Simon, this is the 29th of July. The year is 2002. And your wife, whose name is Anna, is waiting outside.”(The doctor left off four crucial additional words, revealed in the film’s ending.) (Spoiler: Simon had died and was not resuscitated!).A major clue to everything that truly happened was the scene that played next under the credits - hospital staff failed to bring a patient back to life with a defibrillator after a car accident. Chest compressions failed and there was no pulse. A second major clue was provided by hospital orderly Travis (Stephen Graham): Everybody dies. No mystery there. But why and how everyone dies. Now, there’s a mystery worth solving. Probably the biggest mystery there is.So how do we do spoilers?1<span class="spoiler">My hidden paragraph here.</span>"
} ,
{
"title" : "hello Movie",
"category" : "",
"tags" : "red, yellow",
"url" : "/customer-service/",
"date" : "2018-01-11 00:00:00 +0000",
"content" : "Review products, books, movies, restaurant and anything you like on your Jekyll blog with Mediumish! JSON-LD ready for review property.How to use?It’s actually really simple! Add the rating in your YAML front matter. It also supports halfs:hello root only12345678910---layout: posttitle: "Inception Movie"author: johncategories: [ Jekyll, tutorial ]tags: [red, yellow]image: assets/images/11.jpgdescription: "My review of Inception movie. Actors, directing and more."rating: 4.5---"
}
,
{
"title" : "404",
"category" : "",
"tags" : "",
"url" : "/404.html",
"date" : "",
"content" : "404 Page does not exist!Please use the search bar at the top or visit our homepage!"
} ,
{
"title" : "Mediumish Template for Jekyll",
"category" : "",
"tags" : "",
"url" : "/about",
"date" : "",
"content" : "This website is built with Jekyll and Mediumish template for Jekyll. It's for demonstration purposes, no real content can be found. Mediumish template for Jekyll is compatible with Github pages, in fact even this demo is created with Github Pages and hosted with Github.DocumentationPlease, read the docs here.Questions or bug reports?Head over to our Github repository!Buy me a coffeeThank you for your support! Your donation helps me to maintain and improve Mediumish .Buy me a coffee Documentation"
} ,
{
"title" : "Categories",
"category" : "",
"tags" : "",
"url" : "/categories",
"date" : "",
"content" : ""
} ,
{
} ,
{
"title" : "Home",
"category" : "",
"tags" : "",
"url" : "/",
"date" : "",
"content" : " Featured Introduction to character animation hello root only Introduction to character animation 什么是角色动画 让角色自然运动的方式 Techniques such as skeletal animation, morphing, ragdoll physic simulation, and inverse kinematics have already existed for... 06 Jul 2022 skeleton animation cpu skinning skeleton animation骨骼蒙皮从上图可以看出Hips骨骼对顶点的影响权重,一个顶点可以被多个骨骼影响。蒙皮绑定权重在gltf的数据如下JOINTS_0存储了骨骼索引WEIGHTS_0存储了对应的骨骼权重 05 Jul 2022 skeleton animation bind pose skeleton animation骨骼动画之前向动力学 05 Jul 2022 skeleton animation binding pose Introduction to character animation 角色动画之前向动力学 让角色自然运动的方式 Techniques such as skeletal animation, morphing, ragdoll physic simulation, and inverse kinematics have already existed for a long time... 05 Jul 2022 math vector 1 2 3 4 5 球形差值 12 Oct 2021 urp begining 1 2 3 4 5 渲染要处理的对象 摄像机 场景物体 光照 [输出]屏幕、颜色空间 lightMode? 11 Oct 2021 gameplay debug 1 2 3 4 5 https://docs.unrealengine.com/4.27/en-US/TestingAndOptimization/ReplaySystem/ 10 Oct 2021 gameplay debug 1 2 3 4 5 不同编程语言的程序可不可以通过接口相互调用?https://www.zhihu.com/question/20542360 10 Oct 2021 Game Hacking 1 2 3 4 5 Review products, books, movies, restaurant and anything you like on your Jekyll blog with Mediumish! JSON-LD ready for review property. John 13 Sep 2021 thirties(致30岁) 曾经的你 演唱:许巍 曾梦想仗剑走天涯 看一看世界的繁华 年少的心总有些轻狂 如今你四海为家 曾让你心疼的姑娘 如今已悄然无踪影 爱情总让你渴望又感到烦恼 曾让你遍体鳞伤 DiLiLi… DiLiLi… DiLiLi… 走在勇往直前的路上 DiLiLi… DiLiLi… DiLiLi… 有难过也有精彩 每一次难过的时候 就独自看一看大海 总想起身边走在路上的朋友 有多少正在疗伤 DiLiLi… DiLiLi… DiLiLi…... 11 Sep 2021 thirties 曾经的你 演唱:许巍 曾梦想仗剑走天涯 看一看世界的繁华 年少的心总有些轻狂 如今你四海为家 曾让你心疼的姑娘 如今已悄然无踪影 爱情总让你渴望又感到烦恼 曾让你遍体鳞伤 DiLiLi… DiLiLi… DiLiLi… 走在勇往直前的路上 DiLiLi… DiLiLi… DiLiLi… 有难过也有精彩 每一次难过的时候 就独自看一看大海 总想起身边走在路上的朋友 有多少正在疗伤 DiLiLi… DiLiLi… DiLiLi…... 11 Sep 2021 IlluminationMode 1 2 3 4 5 三.光照模型(illumination model)当光照射到物体表面时,物体对光会发生反射、透射、吸收、衍射、折射、和干涉,其中被物体吸收的部分转化为热,反射、透射的光进入人的视觉系统,使我们能看见物体。为模拟这一现象,我们建立一些数学模型来替代复杂的物理模型,这些模型就称为明暗效应模型或者光照明模型。 John 01 Oct 2020 my chaper 1 2 3 4 5 beforesupports halfs:in chaptersupports halfs: 01 Jan 2019 Let's test spoilers Director Roland Suso Richter’s enigmatic psychological thriller (direct to video/DVD) was based upon screenwriter Michael Cooney’s own play “Point of Death” - a title that... Sal 11 Jan 2018 hello Movie 1 2 3 4 5 Review products, books, movies, restaurant and anything you like on your Jekyll blog with Mediumish! JSON-LD ready for review property. John 11 Jan 2018 All Stories Metaprogramming 12 Oct 2021 Powerful things you can do with the Markdown editor There are lots of powerful things you can do with the Markdown editor. If you’ve gotten pretty comfortable with writing in Markdown, then you may enjoy some more advanced tips... Sal 12 Jun 2018 The first mass-produced book to deviate from a rectilinear format The first mass-produced book to deviate from a rectilinear format, at least in the United States, is thought to be this 1863 edition of Red Riding Hood, cut into the... Sal 12 Jun 2018 Education must also train one for quick, resolute and effective thinking. There are lots of powerful things you can do with the Markdown editor John 12 Jun 2018 Accumulated experience of social living The die cut has also been employed in the non-juvenile sphere as well, a recent example being Jonathan Safran Foer’s ambitious Tree of Codes. Sal 12 Jun 2018 About Bundler 1 2 3 4 5 gem install bundler installs the bundler gem through RubyGems. You only need to install it once - not every time you create a new Jekyll project. Here are some additional... Sal 12 May 2018 « Prev 1 2 3 Next » "
} ,
{
} ,
{
} ,
{
"title" : "Tags",
"category" : "",
"tags" : "",
"url" : "/tags",
"date" : "",
"content" : ""
} ,
{
} ,
{
"title" : "Mediumish Jekyll Theme - Change Log",
"category" : "",
"tags" : "",
"url" : "/CHANGELOG/",
"date" : "",
"content" : "Mediumish Jekyll Theme - Change Log2019-05-16, v1.0.36 docker-composer.yml better responsiveness for 1920x1080 resolution2019-04-02, v1.0.35 Fixed Github pages issue with ratings under 1 Added support for local avatars2019-03-22, v1.0.34 Deferred font awesome and google fonts2019-03-22, v1.0.33 Added image lazy load (config.yml - lazyimages: “enabled/disabled”) Added object cover images instead of background images for home featured cards Removed disqus count from homepage for better performance2019-03-20, v1.0.32 Centered avatar image on smaller devices Removed .html endings in cats/tags Added Linkedin share Added Table of Contents (toc:true) Added Paragraph before TOC (beforetoc: “My short description here”)2019-03-20, v1.0.31 Added adsense support (activate via _config.yml) Fixed share for large headers2019-03-20, v1.0.30 Added Tags support Removed Google + sharing, no longer needed2019-03-01, v1.0.29 Fixed Jumbotron categories link2019-03-01, v1.0.28 Added blurred text on spoilers Added half stars for ratings2019-03-01, v1.0.27 Reveal hidden spoilers on click Syntax line numbers Post rating stars Fixed category links with more than 1 word2019-02-14 Fixed Feed site title not showing Added 404 page2019-02-10 Fixed CSS Jumbotron categories2019-02-09 Fixed Category links are now compatible with Github pages. Archive still available for non Github pages. Added Search Added SEO2018-11-08 Fixed reponsive footer jumbotron for tags2018-11-07 Added external image support2018-09-12 Added option to disable comments in a specific post with comments: false in YAML front matter"
} ,
{
"title" : "v1.0.3 Short Fuse",
"category" : "",
"tags" : "",
"url" : "/node_modules/fuzzysearch/CHANGELOG/",
"date" : "",
"content" : "v1.0.3 Short Fuse Improved circuit-breaker when needle and haystack length are equalv1.0.2 Vodka Tonic Slightly updated circuit-breaker that tests for equal length first Doubled method performance (see jsperf tests)v1.0.1 Circuit Breaker Introduced a circuit-breaker where queries longer than the searched string will return false Introduced a circuit-breaker where queries identical to the searched string will return true Introduced a circuit-breaker where text containing the entire query will return truev1.0.0 IPO Initial Public Release"
} ,
{
"title" : "Lunr Languages",
"category" : "",
"tags" : "",
"url" : "/assets/js/lunr-languages/",
"date" : "",
"content" : "Lunr Languages Lunr Languages is a Lunr addon that helps you search in documents written in the following languages: German French Spanish Italian Japanese Dutch Danish Portuguese Finnish Romanian Hungarian Russian Norwegian Thai Vietnamese Arabic Hindi Chinese Tamil Contribute with a new languageLunr Languages is compatible with Lunr version 0.6, 0.7, 1.0 and 2.X.How to useLunr-languages works well with script loaders (Webpack, requirejs) and can be used in the browser and on the server.In a web browserThe following example is for the German language (de).Add the following JS files to the page:123<script src="lunr.js"></script> <!-- lunr.js library --><script src="lunr.stemmer.support.js"></script><script src="lunr.de.js"></script> <!-- or any other language you want -->then, use the language in when initializing lunr:12345678var idx = lunr(function () { // use the language (de) this.use(lunr.de); // then, the normal lunr index initialization this.field('title', { boost: 10 }); this.field('body'); // now you can call this.add(...) to add documents written in German});That’s it. Just add the documents and you’re done. When searching, the language stemmer and stopwords list will be the one you used.In a web browser, with RequireJSAdd require.js to the page:1<script src="lib/require.js"></script>then, use the language in when initializing lunr:12345678910111213141516require(['lib/lunr.js', '../lunr.stemmer.support.js', '../lunr.de.js'], function(lunr, stemmerSupport, de) { // since the stemmerSupport and de add keys on the lunr object, we'll pass it as reference to them // in the end, we will only need lunr. stemmerSupport(lunr); // adds lunr.stemmerSupport de(lunr); // adds lunr.de key // at this point, lunr can be used var idx = lunr(function () { // use the language (de) this.use(lunr.de); // then, the normal lunr index initialization this.field('title', { boost: 10 }) this.field('body') // now you can call this.add(...) to add documents written in German });});With node.js123456789101112var lunr = require('./lib/lunr.js');require('./lunr.stemmer.support.js')(lunr);require('./lunr.de.js')(lunr); // or any other language you wantvar idx = lunr(function () { // use the language (de) this.use(lunr.de); // then, the normal lunr index initialization this.field('title', { boost: 10 }) this.field('body') // now you can call this.add(...) to add documents written in German});Indexing multi-language contentIf your documents are written in more than one language, you can enable multi-language indexing. This ensures every word is properly trimmed and stemmed, every stopword is removed, and no words are lost (indexing in just one language would remove words from every other one.)1234567891011var lunr = require('./lib/lunr.js');require('./lunr.stemmer.support.js')(lunr);require('./lunr.ru.js')(lunr);require('./lunr.multi.js')(lunr);var idx = lunr(function () { // the reason "en" does not appear above is that "en" is built in into lunr js this.use(lunr.multiLanguage('en', 'ru')); // then, the normal lunr index initialization // ...});You can combine any number of supported languages this way. The corresponding lunr language scripts must be loaded (English is built in).If you serialize the index and load it in another script, you’ll have to initialize the multi-language support in that script, too, like this:12lunr.multiLanguage('en', 'ru');var idx = lunr.Index.load(serializedIndex);How to add a new languageCheck the Contributing sectionHow does Lunr Languages work?Searching inside documents is not as straight forward as using indexOf(), since there are many things to consider in order to get quality search results: Tokenization Given a string like “Hope you like using Lunr Languages!”, the tokenizer would split it into individual words, becoming an array like ['Hope', 'you', 'like', 'using', 'Lunr', 'Languages!'] Though it seems a trivial task for Latin characters (just splitting by the space), it gets more complicated for languages like Japanese. Lunr Languages has this included for the Japanese language. Trimming After tokenization, trimming ensures that the words contain just what is needed in them. In our example above, the trimmer would convert Languages! into Languages So, the trimmer basically removes special characters that do not add value for the search purpose. Stemming What happens if our text contains the word consignment but we want to search for consigned? It should find it, since its meaning is the same, only the form is different. A stemmer extracts the root of words that can have many forms and stores it in the index. Then, any search is also stemmed and searched in the index. Lunr Languages does stemming for all the included languages, so you can capture all the forms of words in your documents. Stop words There’s no point in adding or searching words like the, it, so, etc. These words are called Stop words Stop words are removed so your index will only contain meaningful words. Lunr Languages includes stop words for all the included languages. Technical details & CreditsI’ve created this project by compiling and wrapping stemmers toghether with stop words from various sources (including users contributions) so they can be directly used with all the current versions of Lunr. https://github.com/fortnightlabs/snowball-js (the stemmers for all languages, ported from snowball-js) https://github.com/brenes/stopwords-filter (the stop words list for the other languages) http://chasen.org/~taku/software/TinySegmenter/ (the tinyseg Tiny Segmente Japanese tokenizer)I am providing code in the repository to you under an open source license. Because this is my personal repository, the license you receive to my code is from me and not my employer (Facebook)"
} ,
{
} ,
{
"title" : "Stopwords Filter",
"category" : "",
"tags" : "",
"url" : "/assets/js/lunr-languages/build/stopwords-filter/",
"date" : "",
"content" : "Stopwords FilterThis project is a very simple and naive implementation of a stopwords filter that remove a list of banned words (stopwords) from a sentence.Quick guide Installjust type1gem install stopwords-filteror1gem 'stopwords-filter'in your Gemfile. Use it Simple version 12345678stopwords = ['by', 'written', 'from']filter = Stopwords::Filter.new stopwordsfilter.filter 'guide by douglas adams'.split# ['guide', 'douglas', 'adams']filter.stopword? 'by'# true Snowball version123456filter = Stopwords::Snowball::Filter.new "en"filter.filter 'guide by douglas adams'.split# ['guide', 'douglas', 'adams']filter.stopword? 'by'# true2.1 Snowball version with Sieve class (thanks to @s2gatev)1234567sieve = Stopwords::Snowball::WordSieve.newfiltered = sieve.filter lang: :en, words: 'guide by douglas adams'.split# filtered = ['guide', 'douglas', 'adams']sieve.stopword? lang: :en, word: 'by'# trueWhat is a Stopword?According to Wikipedia In computing, stop words are words which are filtered out prior to, or after, processing of natural language data (text).And that’s it. Words that are removed before you perform some task on the rest of them.Why would I want to remove anything?Imagine you have a database of products and you want your customers to search on them. You can’t use a proper search engine (such as Solr, Sphinx or even Google) neither full search systems from popular database systems such as PostgreSQL. You are left alone with LIKEs and %.You have your fake search engine working. Someone searches ‘Guide Douglas Adams’ and you find ‘Douglas Adams - Hitchhiker’s guide to the galaxy’ everything is perfect.But then someone searches ‘guide by douglas adams’ and you don’t find anything. You don’t have any ‘by’ in the description or title of the book! Most importantly, you don’t need that ‘by’!You wish you could get rid of all those ‘by’ or ‘written’ or ‘from’, huh? That’s why we are here!How this thing works?Main class of this ‘library’ is Stopwords::Filter You just create a new object with an array of stopwords12stopwords = ['by', 'written', 'from']filter = Stopwords::Filter.new stopwordsAnd then you have it, you just can filter1filter.filter 'guide by douglas adams'.split #-> ['guide', 'douglas', 'adams']That’s all?I know what you’re thinking, it takes a line of ruby code to filter one array from other. That’s why we have added an extra functionality, Snowball stopwords lists, already built for you and ready to use.How do I use that snowball thing?You just create the filter with the locale you want to use1filter = Stopwords::Snowball::Filter.new "en"And then you filter without worrying about the exact stopwords used1filter.filter 'guide by douglas adams'.split #-> ['guide', 'douglas', 'adams']Anything else?In a future version I would like to include a chaining filter where you include a series of operations and they are executed in a lineal order, just like the Pipes and Filters design patternAckonowledgmentsThanks to @s2gatev who added the stopword? method and the sieve class to this gem"
} ,
{
"title" : "fuzzysearch",
"category" : "",
"tags" : "",
"url" : "/node_modules/fuzzysearch/",
"date" : "",
"content" : "fuzzysearch Tiny and blazing-fast fuzzy search in JavaScriptFuzzy searching allows for flexibly matching a string with partial input, useful for filtering data very quickly based on lightweight user input.DemoTo see fuzzysearch in action, head over to bevacqua.github.io/horsey, which is a demo of an autocomplete component that uses fuzzysearch to filter out results based on user input.InstallFrom npm1npm install --save fuzzysearchfuzzysearch(needle, haystack)Returns true if needle matches haystack using a fuzzy-searching algorithm. Note that this program doesn’t implement levenshtein distance, but rather a simplified version where there’s no approximation. The method will return true only if each character in the needle can be found in the haystack and occurs after the preceding character.1234567fuzzysearch('twl', 'cartwheel') // <- truefuzzysearch('cart', 'cartwheel') // <- truefuzzysearch('cw', 'cartwheel') // <- truefuzzysearch('ee', 'cartwheel') // <- truefuzzysearch('art', 'cartwheel') // <- truefuzzysearch('eeel', 'cartwheel') // <- falsefuzzysearch('dog', 'cartwheel') // <- falseAn exciting application for this kind of algorithm is to filter options from an autocomplete menu, check out horsey for an example on how that might look like.But! RegExps…!LicenseMIT"
} ,
{
"title" : "Lunr Languages",
"category" : "",
"tags" : "",
"url" : "/node_modules/lunr-languages/",
"date" : "",
"content" : "Lunr Languages Lunr Languages is a Lunr addon that helps you search in documents written in the following languages: German French Spanish Italian Japanese Dutch Danish Portuguese Finnish Romanian Hungarian Russian Norwegian Thai Vietnamese Arabic Hindi Chinese Tamil Contribute with a new languageLunr Languages is compatible with Lunr version 0.6, 0.7, 1.0 and 2.X.How to useLunr-languages works well with script loaders (Webpack, requirejs) and can be used in the browser and on the server.In a web browserThe following example is for the German language (de).Add the following JS files to the page:123<script src="lunr.js"></script> <!-- lunr.js library --><script src="lunr.stemmer.support.js"></script><script src="lunr.de.js"></script> <!-- or any other language you want -->then, use the language in when initializing lunr:12345678var idx = lunr(function () { // use the language (de) this.use(lunr.de); // then, the normal lunr index initialization this.field('title', { boost: 10 }); this.field('body'); // now you can call this.add(...) to add documents written in German});That’s it. Just add the documents and you’re done. When searching, the language stemmer and stopwords list will be the one you used.In a web browser, with RequireJSAdd require.js to the page:1<script src="lib/require.js"></script>then, use the language in when initializing lunr:12345678910111213141516require(['lib/lunr.js', '../lunr.stemmer.support.js', '../lunr.de.js'], function(lunr, stemmerSupport, de) { // since the stemmerSupport and de add keys on the lunr object, we'll pass it as reference to them // in the end, we will only need lunr. stemmerSupport(lunr); // adds lunr.stemmerSupport de(lunr); // adds lunr.de key // at this point, lunr can be used var idx = lunr(function () { // use the language (de) this.use(lunr.de); // then, the normal lunr index initialization this.field('title', { boost: 10 }) this.field('body') // now you can call this.add(...) to add documents written in German });});With node.js123456789101112var lunr = require('./lib/lunr.js');require('./lunr.stemmer.support.js')(lunr);require('./lunr.de.js')(lunr); // or any other language you wantvar idx = lunr(function () { // use the language (de) this.use(lunr.de); // then, the normal lunr index initialization this.field('title', { boost: 10 }) this.field('body') // now you can call this.add(...) to add documents written in German});Indexing multi-language contentIf your documents are written in more than one language, you can enable multi-language indexing. This ensures every word is properly trimmed and stemmed, every stopword is removed, and no words are lost (indexing in just one language would remove words from every other one.)1234567891011var lunr = require('./lib/lunr.js');require('./lunr.stemmer.support.js')(lunr);require('./lunr.ru.js')(lunr);require('./lunr.multi.js')(lunr);var idx = lunr(function () { // the reason "en" does not appear above is that "en" is built in into lunr js this.use(lunr.multiLanguage('en', 'ru')); // then, the normal lunr index initialization // ...});You can combine any number of supported languages this way. The corresponding lunr language scripts must be loaded (English is built in).If you serialize the index and load it in another script, you’ll have to initialize the multi-language support in that script, too, like this:12lunr.multiLanguage('en', 'ru');var idx = lunr.Index.load(serializedIndex);How to add a new languageCheck the Contributing sectionHow does Lunr Languages work?Searching inside documents is not as straight forward as using indexOf(), since there are many things to consider in order to get quality search results: Tokenization Given a string like “Hope you like using Lunr Languages!”, the tokenizer would split it into individual words, becoming an array like ['Hope', 'you', 'like', 'using', 'Lunr', 'Languages!'] Though it seems a trivial task for Latin characters (just splitting by the space), it gets more complicated for languages like Japanese. Lunr Languages has this included for the Japanese language. Trimming After tokenization, trimming ensures that the words contain just what is needed in them. In our example above, the trimmer would convert Languages! into Languages So, the trimmer basically removes special characters that do not add value for the search purpose. Stemming What happens if our text contains the word consignment but we want to search for consigned? It should find it, since its meaning is the same, only the form is different. A stemmer extracts the root of words that can have many forms and stores it in the index. Then, any search is also stemmed and searched in the index. Lunr Languages does stemming for all the included languages, so you can capture all the forms of words in your documents. Stop words There’s no point in adding or searching words like the, it, so, etc. These words are called Stop words Stop words are removed so your index will only contain meaningful words. Lunr Languages includes stop words for all the included languages. Technical details & CreditsI’ve created this project by compiling and wrapping stemmers toghether with stop words from various sources (including users contributions) so they can be directly used with all the current versions of Lunr. https://github.com/fortnightlabs/snowball-js (the stemmers for all languages, ported from snowball-js) https://github.com/brenes/stopwords-filter (the stop words list for the other languages) http://chasen.org/~taku/software/TinySegmenter/ (the tinyseg Tiny Segmente Japanese tokenizer)I am providing code in the repository to you under an open source license. Because this is my personal repository, the license you receive to my code is from me and not my employer (Facebook)"
} ,
{
} ,
{
"title" : "Stopwords Filter",
"category" : "",
"tags" : "",
"url" : "/node_modules/lunr-languages/build/stopwords-filter/",
"date" : "",
"content" : "Stopwords FilterThis project is a very simple and naive implementation of a stopwords filter that remove a list of banned words (stopwords) from a sentence.Quick guide Installjust type1gem install stopwords-filteror1gem 'stopwords-filter'in your Gemfile. Use it Simple version 12345678stopwords = ['by', 'written', 'from']filter = Stopwords::Filter.new stopwordsfilter.filter 'guide by douglas adams'.split# ['guide', 'douglas', 'adams']filter.stopword? 'by'# true Snowball version123456filter = Stopwords::Snowball::Filter.new "en"filter.filter 'guide by douglas adams'.split# ['guide', 'douglas', 'adams']filter.stopword? 'by'# true2.1 Snowball version with Sieve class (thanks to @s2gatev)1234567sieve = Stopwords::Snowball::WordSieve.newfiltered = sieve.filter lang: :en, words: 'guide by douglas adams'.split# filtered = ['guide', 'douglas', 'adams']sieve.stopword? lang: :en, word: 'by'# trueWhat is a Stopword?According to Wikipedia In computing, stop words are words which are filtered out prior to, or after, processing of natural language data (text).And that’s it. Words that are removed before you perform some task on the rest of them.Why would I want to remove anything?Imagine you have a database of products and you want your customers to search on them. You can’t use a proper search engine (such as Solr, Sphinx or even Google) neither full search systems from popular database systems such as PostgreSQL. You are left alone with LIKEs and %.You have your fake search engine working. Someone searches ‘Guide Douglas Adams’ and you find ‘Douglas Adams - Hitchhiker’s guide to the galaxy’ everything is perfect.But then someone searches ‘guide by douglas adams’ and you don’t find anything. You don’t have any ‘by’ in the description or title of the book! Most importantly, you don’t need that ‘by’!You wish you could get rid of all those ‘by’ or ‘written’ or ‘from’, huh? That’s why we are here!How this thing works?Main class of this ‘library’ is Stopwords::Filter You just create a new object with an array of stopwords12stopwords = ['by', 'written', 'from']filter = Stopwords::Filter.new stopwordsAnd then you have it, you just can filter1filter.filter 'guide by douglas adams'.split #-> ['guide', 'douglas', 'adams']That’s all?I know what you’re thinking, it takes a line of ruby code to filter one array from other. That’s why we have added an extra functionality, Snowball stopwords lists, already built for you and ready to use.How do I use that snowball thing?You just create the filter with the locale you want to use1filter = Stopwords::Snowball::Filter.new "en"And then you filter without worrying about the exact stopwords used1filter.filter 'guide by douglas adams'.split #-> ['guide', 'douglas', 'adams']Anything else?In a future version I would like to include a chaining filter where you include a series of operations and they are executed in a lineal order, just like the Pipes and Filters design patternAckonowledgmentsThanks to @s2gatev who added the stopword? method and the sieve class to this gem"
} ,
{
"title" : "Simple-Jekyll-Search",
"category" : "",
"tags" : "",
"url" : "/node_modules/simple-jekyll-search/",
"date" : "",
"content" : "# [Simple-Jekyll-Search](https://www.npmjs.com/package/simple-jekyll-search)[](https://travis-ci.org/christian-fei/Simple-Jekyll-Search)[](https://david-dm.org/christian-fei/Simple-Jekyll-Search)[](https://david-dm.org/christian-fei/Simple-Jekyll-Search?type=dev)A JavaScript library to add search functionality to any Jekyll blog.## Use caseYou have a blog, built with Jekyll, and want a **lightweight search functionality** on your blog, purely client-side?*No server configurations or databases to maintain*.Just **5 minutes** to have a **fully working searchable blog**.---## Installation### npm```shnpm install simple-jekyll-search```## Getting started### Create `search.json`Place the following code in a file called `search.json` in the **root** of your Jekyll blog. (You can also get a copy [from here](/example/search.json))This file will be used as a small data source to perform the searches on the client side:```yaml---layout: none---[ {% for post in site.posts %} { "title" : "{{ post.title | escape }}", "category" : "{{ post.category }}", "tags" : "{{ post.tags | join: ', ' }}", "url" : "{{ site.baseurl }}{{ post.url }}", "date" : "{{ post.date }}" } {% unless forloop.last %},{% endunless %} {% endfor %}]```## Preparing the plugin### Add DOM elementsSimpleJekyllSearch needs two `DOM` elements to work:- a search input field- a result container to display the results#### Give me the codeHere is the code you can use with the default configuration:You need to place the following code within the layout where you want the search to appear. (See the configuration section below to customize it)For example in **_layouts/default.html**:```html```## UsageCustomize SimpleJekyllSearch by passing in your configuration options:```jsvar sjs = SimpleJekyllSearch({ searchInput: document.getElementById('search-input'), resultsContainer: document.getElementById('results-container'), json: '/search.json'})```### returns { search }A new instance of SimpleJekyllSearch returns an object, with the only property `search`.`search` is a function used to simulate a user input and display the matching results. E.g.:```jsvar sjs = SimpleJekyllSearch({ ...options })sjs.search('Hello')```💡 it can be used to filter posts by tags or categories!## OptionsHere is a list of the available options, usage questions, troubleshooting & guides.### searchInput (Element) [required]The input element on which the plugin should listen for keyboard event and trigger the searching and rendering for articles.### resultsContainer (Element) [required]The container element in which the search results should be rendered in. Typically a ``.### json (String|JSON) [required]You can either pass in an URL to the `search.json` file, or the results in form of JSON directly, to save one round trip to get the data.### searchResultTemplate (String) [optional]The template of a single rendered search result.The templating syntax is very simple: You just enclose the properties you want to replace with curly braces.E.g.The template```jsvar sjs = SimpleJekyllSearch({ searchInput: document.getElementById('search-input'), resultsContainer: document.getElementById('results-container'), json: '/search.json', searchResultTemplate: '{title}'})```will render to the following```htmlWelcome to Jekyll!```If the `search.json` contains this data```json[ { "title" : "Welcome to Jekyll!", "category" : "", "tags" : "", "url" : "/jekyll/update/2014/11/01/welcome-to-jekyll.html", "date" : "2014-11-01 21:07:22 +0100" }]```### templateMiddleware (Function) [optional]A function that will be called whenever a match in the template is found.It gets passed the current property name, property value, and the template.If the function returns a non-undefined value, it gets replaced in the template.This can be potentially useful for manipulating URLs etc.Example:```jsSimpleJekyllSearch({ ... templateMiddleware: function(prop, value, template) { if (prop === 'bar') { return value.replace(/^\//, '') } } ...})```See the [tests](https://github.com/christian-fei/Simple-Jekyll-Search/blob/master/tests/Templater.test.js) for an in-depth code example### sortMiddleware (Function) [optional]A function that will be used to sort the filtered results.It can be used for example to group the sections together.Example:```jsSimpleJekyllSearch({ ... sortMiddleware: function(a, b) { var astr = String(a.section) + "-" + String(a.caption); var bstr = String(b.section) + "-" + String(b.caption); return astr.localeCompare(bstr) } ...})```### noResultsText (String) [optional]The HTML that will be shown if the query didn't match anything.### limit (Number) [optional]You can limit the number of posts rendered on the page.### fuzzy (Boolean) [optional]Enable fuzzy search to allow less restrictive matching.### exclude (Array) [optional]Pass in a list of terms you want to exclude (terms will be matched against a regex, so URLs, words are allowed).### success (Function) [optional]A function called once the data has been loaded.### debounceTime (Number) [optional]Limit how many times the search function can be executed over the given time window. This is especially useful to improve the user experience when searching over a large dataset (either with rare terms or because the number of posts to display is large). If no `debounceTime` (milliseconds) is provided a search will be triggered on each keystroke.---## If search isn't working due to invalid JSON- There is a filter plugin in the _plugins folder which should remove most characters that cause invalid JSON. To use it, add the simple_search_filter.rb file to your _plugins folder, and use `remove_chars` as a filter.For example: in search.json, replace```json"content": "{{ page.content | strip_html | strip_newlines }}"```with```json"content": "{{ page.content | strip_html | strip_newlines | remove_chars | escape }}"```If this doesn't work when using Github pages you can try `jsonify` to make sure the content is json compatible:```js"content": {{ page.content | jsonify }}```**Note: you don't need to use quotes `"` in this since `jsonify` automatically inserts them.**## Enabling full-text searchReplace `search.json` with the following code:```yaml---layout: none---[ {% for post in site.posts %} { "title" : "{{ post.title | escape }}", "category" : "{{ post.category }}", "tags" : "{{ post.tags | join: ', ' }}", "url" : "{{ site.baseurl }}{{ post.url }}", "date" : "{{ post.date }}", "content" : "{{ post.content | strip_html | strip_newlines }}" } {% unless forloop.last %},{% endunless %} {% endfor %} , {% for page in site.pages %} { {% if page.title != nil %} "title" : "{{ page.title | escape }}", "category" : "{{ page.category }}", "tags" : "{{ page.tags | join: ', ' }}", "url" : "{{ site.baseurl }}{{ page.url }}", "date" : "{{ page.date }}", "content" : "{{ page.content | strip_html | strip_newlines }}" {% endif %} } {% unless forloop.last %},{% endunless %} {% endfor %}]```## Development- `npm install`- `npm test`#### Acceptance tests```bashcd example; jekyll serve# in another tabnpm run cypress -- run```## ContributorsThanks to all [contributors](https://github.com/christian-fei/Simple-Jekyll-Search/graphs/contributors) over the years! You are the best :)> [@daviddarnes](https://github.com/daviddarnes)[@XhmikosR](https://github.com/XhmikosR)[@PeterDaveHello](https://github.com/PeterDaveHello)[@mikeybeck](https://github.com/mikeybeck)[@egladman](https://github.com/egladman)[@midzer](https://github.com/midzer)[@eduardoboucas](https://github.com/eduardoboucas)[@kremalicious](https://github.com/kremalicious)[@tibotiber](https://github.com/tibotiber)and many others!## Stargazers over time[](https://starchart.cc/christian-fei/Simple-Jekyll-Search)"
} ,
{
"title" : "Home",
"category" : "",
"tags" : "",
"url" : "/page2/",
"date" : "",
"content" : "{% if page.url == "/" %} Featured {% for post in site.posts %} {% if post.featured == true %} {% include featuredbox.html %} {% endif %} {% endfor %} {% endif %} All Stories {% for post in paginator.posts %} {% include postbox.html %} {% endfor %} {% include pagination.html %}"
} ,
{
"title" : "Home",
"category" : "",
"tags" : "",
"url" : "/page3/",
"date" : "",
"content" : "{% if page.url == "/" %} Featured {% for post in site.posts %} {% if post.featured == true %} {% include featuredbox.html %} {% endif %} {% endfor %} {% endif %} All Stories {% for post in paginator.posts %} {% include postbox.html %} {% endfor %} {% include pagination.html %}"
} ,
{
} ,
{
}
]
Development
npm install
npm test
Acceptance tests
1
2
3
4
5
cd example; jekyll serve
# in another tab
npm run cypress -- run
Contributors
Thanks to all contributors over the years! You are the best :)
@daviddarnes @XhmikosR @PeterDaveHello @mikeybeck @egladman @midzer @eduardoboucas @kremalicious @tibotiber and many others!