Skip to content
Snippets Groups Projects
Commit 00d85e47 authored by Anne GARCIA-FERNANDEZ's avatar Anne GARCIA-FERNANDEZ
Browse files

First draft of search: 3 xsl for producing template, Json Index and miniSearch...

First draft of search: 3 xsl for producing template, Json Index and miniSearch config + add MiniSearch files
parent f1b10627
No related branches found
No related tags found
1 merge request!99Merge Search functionnality to Master
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* XSLT TEI to Json : index for MiniSearch
* @author AnneGF@CNRS
* @date : 2024
* TODO : all books
* XML : Livre I.xml (à terme à changer donc...)
* Output : static/js/auto_app_minisearch.js
*/
-->
<!DOCTYPE xsl [
<!ENTITY times "&#215;">
<!ENTITY nbsp "&#160;">
]>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tei="http://www.tei-c.org/ns/1.0"
xmlns="http://www.w3.org/1999/xhtml" exclude-result-prefixes="xs tei" version="2.0">
<xsl:output method="html" indent="yes" encoding="UTF-8" omit-xml-declaration="yes"/>
<xsl:param name="data_json_file">
<xsl:text>static/json/auto_index.json</xsl:text>
</xsl:param>
<xsl:variable name="br">
<xsl:text>
</xsl:text>
</xsl:variable>
<xsl:template match="/">
<xsl:variable name="all_witness_id" select=" distinct-values(//@wit/tokenize(normalize-space(.), ' '))"/>
<xsl:variable name="witnesses_as_list">
<xsl:for-each select="$all_witness_id">
<xsl:text>'</xsl:text>
<xsl:value-of select="replace(., '#', '')"/>
<xsl:text>'</xsl:text>
<xsl:if test="position() &lt; last()">
<xsl:text>, </xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:text>// Setup data</xsl:text>
<xsl:value-of select="$br"/>
<xsl:text>let $searchable_fields = ['lem',</xsl:text>
<xsl:value-of select="$witnesses_as_list"/>
<xsl:text>];</xsl:text>
<xsl:value-of select="$br"/>
<xsl:text>let $showable_fields = ['book', 'chapter', 'n', 'lem',</xsl:text>
<xsl:value-of select="$witnesses_as_list"/>
<xsl:text>];</xsl:text>
<xsl:value-of select="$br"/>
<xsl:text>// Setup MiniSearch</xsl:text>
<xsl:value-of select="$br"/>
<xsl:text>let miniSearch = new MiniSearch({</xsl:text>
<xsl:value-of select="$br"/>
<xsl:text>fields: $searchable_fields, // fields to index for full-text search</xsl:text>
<xsl:value-of select="$br"/>
<xsl:text>storeFields: $showable_fields // fields to return with search results</xsl:text>
<xsl:value-of select="$br"/>
<xsl:text>})</xsl:text>
<xsl:value-of select="$br"/>
<xsl:text>let $data_json = '</xsl:text>
<xsl:value-of select="$data_json_file"/>
<xsl:text>';</xsl:text>
<xsl:value-of select="$br"/>
<xsl:value-of select="$br"/>
<xsl:text disable-output-escaping="yes">const renderSearchResults = (results) => {</xsl:text>
<xsl:value-of select="$br"/>
<xsl:text>$resultsList.innerHTML = results.map(({ book, chapter, n, lem,</xsl:text>
<xsl:variable name="simple_quote">
<xsl:text>'</xsl:text>
</xsl:variable>
<xsl:value-of select="replace($witnesses_as_list,$simple_quote,'')"/>
<xsl:text disable-output-escaping="yes"> }) => {</xsl:text>
<xsl:value-of select="$br"/>
let $result=`<h5 class="mt-3">
<xsl:text>Vers </xsl:text>
<a>
<xsl:attribute name="href">
<xsl:text>/book${book}/${chapter}#${n}</xsl:text>
</xsl:attribute>
<xsl:text>${n}</xsl:text>
</a>
</h5>
<dl>
<dt>Livre : </dt>
<dd>${book}</dd>
<dt>Chapitre : </dt>
<dd>${chapter}</dd>
<dt>Lemme :</dt>
<dd>${lem}</dd>`
<xsl:for-each select="$all_witness_id">
<xsl:text>if (! (`${</xsl:text>
<xsl:value-of select="replace(.,'#','')"/>
<xsl:text>}` === "undefined") ) {</xsl:text>
$result += `
<dt><xsl:value-of select="replace(.,'#','')"/> : </dt>
<dd>
<xsl:text>${</xsl:text>
<xsl:value-of select="replace(.,'#','')"/>
<xsl:text>}</xsl:text>
</dd>
`}
</xsl:for-each>
$result += `</dl>`
<xsl:text>return $result</xsl:text>
<xsl:value-of select="$br"/>
<xsl:text>}).join('\n')</xsl:text>
<xsl:value-of select="$br"/>
<xsl:text disable-output-escaping="yes">
if (results.length > 0) {
$app.classList.add('hasResults')
} else {
$app.classList.remove('hasResults')
}
}
const getSuggestions = (query) => {
return miniSearch.autoSuggest(query, { boost: { source_author: 3, fragment: 6} })
.filter(({ suggestion, score }, _, [first]) => score > first.score / 4)
.slice(0, 5)
}
</xsl:text>
</xsl:template>
</xsl:stylesheet>
\ No newline at end of file
...@@ -4,10 +4,13 @@ ...@@ -4,10 +4,13 @@
* XSLT TEI to Json : index for MiniSearch * XSLT TEI to Json : index for MiniSearch
* @author AnneGF@CNRS * @author AnneGF@CNRS
* @date : 2024 * @date : 2024
* TODO : all books + prologue
* XML : Livre I.xml (à terme à changer donc...)
* Output : static/json/auto_index.json
*/ */
--> -->
<!DOCTYPE tei2editorial [ <!DOCTYPE xsl [
<!ENTITY times "&#215;"> <!ENTITY times "&#215;">
<!ENTITY non_breakable_space "&#160;"> <!ENTITY non_breakable_space "&#160;">
]> ]>
...@@ -43,14 +46,33 @@ ...@@ -43,14 +46,33 @@
<xsl:for-each select=".//tei:l"> <xsl:for-each select=".//tei:l">
<xsl:variable name="l" select="." as="node()"/> <xsl:variable name="l" select="." as="node()"/>
<xsl:variable name="l_count" select="position()"/>
<xsl:variable name="chapter">
<xsl:number select="." count="tei:div" level="single"/>
<xsl:text>_chap_</xsl:text>
<xsl:value-of select="./ancestor::tei:div[@type='chap']/@n"/>
</xsl:variable>
<xsl:text> {</xsl:text> <xsl:text> {</xsl:text>
<xsl:value-of select="$br"/> <xsl:value-of select="$br"/>
<!-- Id -->
<xsl:text> "id": "</xsl:text>
<xsl:value-of select="$book"/>
<xsl:value-of select="$l_count"/>
<xsl:text>",</xsl:text>
<xsl:value-of select="$br"/>
<!-- Numero du livre --> <!-- Numero du livre -->
<xsl:text> "book": "</xsl:text> <xsl:text> "book": "</xsl:text>
<xsl:value-of select="$book"/> <xsl:value-of select="$book"/>
<xsl:text>",</xsl:text> <xsl:text>",</xsl:text>
<xsl:value-of select="$br"/> <xsl:value-of select="$br"/>
<!-- Numero du chapitre -->
<xsl:text> "chapter": "</xsl:text>
<xsl:value-of select="$chapter"/>
<xsl:text>",</xsl:text>
<xsl:value-of select="$br"/>
<!-- Numero de vers --> <!-- Numero de vers -->
<xsl:variable name="l_num" select="@n"/> <xsl:variable name="l_num" select="@n"/>
...@@ -72,7 +94,7 @@ ...@@ -72,7 +94,7 @@
<!-- Témoin --> <!-- Témoin -->
<xsl:text> "</xsl:text> <xsl:text> "</xsl:text>
<xsl:value-of select="$witness"/> <xsl:value-of select="replace($witness,'#','')"/>
<xsl:text>": "</xsl:text> <xsl:text>": "</xsl:text>
<xsl:value-of select="normalize-space($lesson)"/> <xsl:value-of select="normalize-space($lesson)"/>
<xsl:text>",</xsl:text> <xsl:text>",</xsl:text>
......
<?xml version="1.0" encoding="UTF-8"?>
<!--
/**
* XSLT TEI to Json : index for MiniSearch
* @author AnneGF@CNRS
* @date : 2024
* TODO : all books
* XML : Livre I.xml (à terme à changer donc...)
* Output : templates/search.html.j2
*/
-->
<!DOCTYPE xsl [
<!ENTITY times "&#215;">
<!ENTITY nbsp "&#160;">
]>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tei="http://www.tei-c.org/ns/1.0"
xmlns="http://www.w3.org/1999/xhtml" exclude-result-prefixes="xs tei" version="2.0">
<xsl:output method="html" indent="yes" encoding="UTF-8" omit-xml-declaration="yes"/>
<xsl:variable name="br">
<xsl:text>
</xsl:text>
</xsl:variable>
<xsl:template match="/">
<xsl:variable name="all_witness_id" select=" distinct-values(//@wit/tokenize(., ' '))"/>
<xsl:text>{% extends "base.html.j2" %}</xsl:text>
<xsl:value-of select="$br"/>
<xsl:text>{% block css %}</xsl:text>
<link href="/static/css/app_minisearch.css" rel="stylesheet"/>
<xsl:text>{% endblock %}</xsl:text>
<xsl:value-of select="$br"/>
<xsl:text>{% block containertype %}container{% endblock %}</xsl:text>
<xsl:value-of select="$br"/>
<xsl:text>{% block pageTitle %}Recherche{% endblock %}</xsl:text>
<xsl:value-of select="$br"/>
<xsl:text>{% block body %}</xsl:text>
<xsl:value-of select="$br"/>
<h1>Chercher dans un vers...</h1>
<div id="app">
<div class="App">
<div class="Loader">loading...</div>
<div class="SearchBox">
<div class="Search">
<input type="text"/>
<button class="clear">×</button>
</div>
<ul class="SuggestionList"></ul>
<details class="AdvancedOptions" open="">
<summary>Advanced options</summary>
<form class="options">
<div>
<b>Search in fields:</b>
<label><input type="checkbox" name="fields"
value="lem" checked=""/>&nbsp;Lemme</label>
<xsl:for-each select="$all_witness_id">
<xsl:variable name="wit" select="replace(.,'#','')"/>
<label><input type="checkbox" name="fields"
value="{$wit}" checked=""/>&nbsp;<xsl:value-of select="$wit"/></label></xsl:for-each>
</div>
<div>
<b>Search options:</b>
<label><input type="checkbox" name="prefix" value="true"
checked=""/> Prefix (considérer la recherche
comme un "début de mot" ; 'qui' renvoit 'qui',
'quidem', etc.)</label>
<label><input type="checkbox" name="fuzzy" value="true"
checked=""/> Fuzzy (autoriser les recherches
approximatives)</label>
</div>
<div>
<b>Combine terms with:</b>
<label><input type="radio" name="combineWith" value="OR"
checked=""/> OR (chercher au moins un des
termes)</label>
<label><input type="radio" name="combineWith"
value="AND"/> AND (chercher tous les
termes)</label>
</div>
</form>
</details>
</div>
<p class="Explanation"> Ceci est un premier jet de recherche, utilisant
la bibliothèque javascript <a
href="https://github.com/lucaong/minisearch">MiniSearch</a></p>
<ul class="resultsList"></ul>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/minisearch@7.1.0/dist/umd/index.min.js"/>
<script src="/static/js/auto_app_minisearch.js"></script>
<script src="/static/js/app_minisearch.js"></script>
<xsl:value-of select="$br"/>
<xsl:text>{% endblock %}</xsl:text>
</xsl:template>
</xsl:stylesheet>
dl {
font-size: smaller;
margin-left: 5px;
}
dt, dd {
display: inline;
margin: 0;
}
dt {
font-weight: bold;
color: #333;
}
dd:after {
content: '';
display: block;
}
details, summary {
outline: none;
}
.App .main {
padding: 1em;
display: flex;
flex-flow: column;
max-height: 100vh;
max-width: 900px;
margin: 0 auto;
}
.Header h1 {
font-size: 2em;
margin-top: 0;
}
.SearchBox {
position: relative;
}
.Search {
position: relative;
}
.Search button.clear {
position: absolute;
top: 0;
bottom: 0.2em;
right: 0.5em;
font-size: 1.5em;
line-height: 1;
z-index: 20;
border: none;
background: none;
outline: none;
margin: 0;
padding: 0;
}
.Search input {
width: 100%;
padding: 0.5em;
font-size: 16px;
border: 1px solid #ccc;
border-radius: 3px;
outline: none;
color: #555;
box-shadow: none;
}
.hasResults .Explanation {
display: none;
}
.AdvancedOptions {
font-size: 0.9em;
}
.AdvancedOptions summary {
text-decoration: underline;
}
.AdvancedOptions .options {
margin-top: 1em;
font-size: 0.85em;
}
.AdvancedOptions .options label {
display: inline;
margin-left: 0.7em;
}
.SuggestionList {
display: none;
list-style: none;
padding: 0;
border: 1px solid #ccc;
border-top: 0;
margin: 0 0 0.2em 0;
border-radius: 3px;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);
background: rgba(255, 255, 255, 0.93);
position: absolute;
z-index: 20;
left: 0;
right: 0;
}
.hasSuggestions .SuggestionList {
display: block;
}
.Suggestion {
padding: 0.5em 1em;
border-bottom: 1px solid #eee;
}
.Suggestion:last-child {
border: none;
}
.Suggestion.selected {
background: rgba(240, 240, 240, 0.95);
}
.Suggestion:hover:not(.selected) {
background: rgba(250, 250, 250, 0.95);
}
.Loader {
display: none;
}
.loading .Loader {
display: block;
}
.loading .main {
display: none;
}
.Loader,
.Loader:after {
border-radius: 50%;
width: 10em;
height: 10em;
}
.Loader {
margin: 5px auto;
font-size: 5px;
position: relative;
text-indent: -9999em;
border-top: 1.1em solid rgba(255, 255, 255, 0.2);
border-right: 1.1em solid rgba(255, 255, 255, 0.2);
border-bottom: 1.1em solid rgba(255, 255, 255, 0.2);
border-left: 1.1em solid #0099cc;
-webkit-transform: translateZ(0);
transform: translateZ(0);
-webkit-animation: load8 1.1s infinite linear;
animation: load8 1.1s infinite linear;
}
// Define functions and support variables
/*
const searchOptions = {
fuzzy: 0.2,
prefix: true,
fields: ['source_author', 'source_work'],
combineWith: 'OR',
filter: null
}
*/
// Select DOM elements
const $app = document.querySelector('.App')
const $search = document.querySelector('.Search')
const $searchInput = document.querySelector('.Search input')
const $clearButton = document.querySelector('.Search button.clear')
const $resultsList = document.querySelector('.resultsList')
const $explanation = document.querySelector('.Explanation')
const $suggestionList = document.querySelector('.SuggestionList')
const $options = document.querySelector('.AdvancedOptions form')
// Fetch and index data
$app.classList.add('loading')
function fetchJSONData() {
fetch($data_json)
.then((res) => {
if (!res.ok) {
throw new Error
(`HTTP error! Status: ${res.status}`);
}
return res.json();
})
.then((data) => {
console.log(data)
miniSearch.addAll(data)
$app.classList.remove('loading')
})
.catch((error) =>
console.error("Unable to fetch data:", error));
}
fetchJSONData()
//*** Search actions ***//
const getSearchResults = (query) => {
const searchOptions = getSearchOptions()
//console.log(query)
//console.log(searchOptions)
//console.log(miniSearch.search(query, searchOptions))
return miniSearch.search(query, searchOptions)
}
/* */
const renderSuggestions = (suggestions) => {
$suggestionList.innerHTML = suggestions.map(({ suggestion }) => {
return `<li class="Suggestion">${suggestion}</li>`
}).join('\n')
if (suggestions.length > 0) {
$app.classList.add('hasSuggestions')
} else {
$app.classList.remove('hasSuggestions')
}
}
//*** Bind event listeners ***//
// Typing into search bar updates search results and suggestions
$searchInput.addEventListener('input', (event) => {
const query = $searchInput.value
const results = (query.length > 1) ? getSearchResults(query) : []
renderSearchResults(results)
const suggestions = (query.length > 1) ? getSuggestions(query) : []
renderSuggestions(suggestions)
})
// Clicking on clear button clears search and suggestions
$clearButton.addEventListener('click', () => {
$searchInput.value = ''
$searchInput.focus()
renderSearchResults([])
renderSuggestions([])
})
// Clicking on a suggestion selects it
$suggestionList.addEventListener('click', (event) => {
const $suggestion = event.target
if ($suggestion.classList.contains('Suggestion')) {
const query = $suggestion.innerText.trim()
$searchInput.value = query
$searchInput.focus()
const results = getSearchResults(query)
renderSearchResults(results)
renderSuggestions([])
}
})
// Pressing up/down/enter key while on search bar navigates through suggestions
$search.addEventListener('keydown', (event) => {
const key = event.key
if (key === 'ArrowDown') {
selectSuggestion(+1)
} else if (key === 'ArrowUp') {
selectSuggestion(-1)
} else if (key === 'Enter' || key === 'Escape') {
$searchInput.blur()
renderSuggestions([])
} else {
return
}
const query = $searchInput.value
const results = getSearchResults(query)
renderSearchResults(results)
})
// Clicking outside of search bar clears suggestions
$app.addEventListener('click', (event) => {
renderSuggestions([])
})
// Changing any advanced option triggers a new search with the updated options
$options.addEventListener('change', (event) => {
const query = $searchInput.value
const results = getSearchResults(query)
renderSearchResults(results)
})
const selectSuggestion = (direction) => {
const $suggestions = document.querySelectorAll('.Suggestion')
const $selected = document.querySelector('.Suggestion.selected')
const index = Array.from($suggestions).indexOf($selected)
if (index > -1) {
$suggestions[index].classList.remove('selected')
}
const nextIndex = Math.max(Math.min(index + direction, $suggestions.length - 1), 0)
$suggestions[nextIndex].classList.add('selected')
$searchInput.value = $suggestions[nextIndex].innerText
}
const getSearchOptions = () => {
const formData = new FormData($options)
const searchOptions = {}
searchOptions.fuzzy = formData.has('fuzzy') ? 0.2 : false
searchOptions.prefix = formData.has('prefix')
searchOptions.fields = formData.getAll('fields')
searchOptions.combineWith = formData.get('combineWith')
return searchOptions
}
const capitalize = (string) => string.replace(/(\b\w)/gi, (char) => char.toUpperCase())
// Setup data
let $searchable_fields = ['lem','BnFfr4967', 'BnFfr5299', 'BnFfr23145', 'BnFfr49967', 'Cha514', 'BnFfr23146', 'BnFfr17274',
'Vat966', 'Aix419', 'BnFfr1724', 'Aix966'];
let $showable_fields = ['book', 'chapter', 'n', 'lem','BnFfr4967', 'BnFfr5299', 'BnFfr23145', 'BnFfr49967', 'Cha514', 'BnFfr23146', 'BnFfr17274',
'Vat966', 'Aix419', 'BnFfr1724', 'Aix966'];
// Setup MiniSearch
let miniSearch = new MiniSearch({
fields: $searchable_fields, // fields to index for full-text search
storeFields: $showable_fields // fields to return with search results
})
let $data_json = 'static/json/auto_index.json';
const renderSearchResults = (results) => {
$resultsList.innerHTML = results.map(({ book, chapter, n, lem,BnFfr4967, BnFfr5299, BnFfr23145, BnFfr49967, Cha514, BnFfr23146, BnFfr17274, Vat966,
Aix419, BnFfr1724, Aix966 }) => {
let $result=`<h5 xmlns="http://www.w3.org/1999/xhtml" class="mt-3">Vers <a href="/book${book}/${chapter}#${n}">${n}</a></h5><dl xmlns="http://www.w3.org/1999/xhtml">
<dt>Livre : </dt>
<dd>${book}</dd>
<dt>Chapitre : </dt>
<dd>${chapter}</dd>
<dt>Lemme :</dt>
<dd>${lem}</dd>`
if (! (`${BnFfr4967}` === "undefined") ) {
$result += `
<dt>BnFfr4967 : </dt>
<dd>${BnFfr4967}</dd>
`}
if (! (`${BnFfr5299}` === "undefined") ) {
$result += `
<dt>BnFfr5299 : </dt>
<dd>${BnFfr5299}</dd>
`}
if (! (`${BnFfr23145}` === "undefined") ) {
$result += `
<dt>BnFfr23145 : </dt>
<dd>${BnFfr23145}</dd>
`}
if (! (`${BnFfr49967}` === "undefined") ) {
$result += `
<dt>BnFfr49967 : </dt>
<dd>${BnFfr49967}</dd>
`}
if (! (`${Cha514}` === "undefined") ) {
$result += `
<dt>Cha514 : </dt>
<dd>${Cha514}</dd>
`}
if (! (`${BnFfr23146}` === "undefined") ) {
$result += `
<dt>BnFfr23146 : </dt>
<dd>${BnFfr23146}</dd>
`}
if (! (`${BnFfr17274}` === "undefined") ) {
$result += `
<dt>BnFfr17274 : </dt>
<dd>${BnFfr17274}</dd>
`}
if (! (`${Vat966}` === "undefined") ) {
$result += `
<dt>Vat966 : </dt>
<dd>${Vat966}</dd>
`}
if (! (`${Aix419}` === "undefined") ) {
$result += `
<dt>Aix419 : </dt>
<dd>${Aix419}</dd>
`}
if (! (`${BnFfr1724}` === "undefined") ) {
$result += `
<dt>BnFfr1724 : </dt>
<dd>${BnFfr1724}</dd>
`}
if (! (`${Aix966}` === "undefined") ) {
$result += `
<dt>Aix966 : </dt>
<dd>${Aix966}</dd>
`}
$result += `</dl>`
return $result
}).join('\n')
if (results.length > 0) {
$app.classList.add('hasResults')
} else {
$app.classList.remove('hasResults')
}
}
const getSuggestions = (query) => {
return miniSearch.autoSuggest(query, { boost: { source_author: 3, fragment: 6} })
.filter(({ suggestion, score }, _, [first]) => score > first.score / 4)
.slice(0, 5)
}
\ No newline at end of file
This diff is collapsed.
{% extends "base.html.j2" %}
{% block css %}<link xmlns="http://www.w3.org/1999/xhtml" href="/static/css/app_minisearch.css" rel="stylesheet">{% endblock %}
{% block containertype %}container{% endblock %}
{% block pageTitle %}Recherche{% endblock %}
{% block body %}
<h1 xmlns="http://www.w3.org/1999/xhtml">Chercher dans un vers...</h1><div xmlns="http://www.w3.org/1999/xhtml" id="app">
<div class="App">
<div class="Loader">loading...</div>
<div class="SearchBox">
<div class="Search"><input type="text"><button class="clear">×</button></div>
<ul class="SuggestionList"></ul>
<details class="AdvancedOptions" open="">
<summary>Advanced options</summary>
<form class="options">
<div><b>Search in fields:</b><label><input type="checkbox" name="fields" value="lem" checked="">&nbsp;Lemme</label><label><input type="checkbox" name="fields" value="BnFfr4967" checked="">&nbsp;BnFfr4967</label><label><input type="checkbox" name="fields" value="BnFfr5299" checked="">&nbsp;BnFfr5299</label><label><input type="checkbox" name="fields" value="BnFfr23145" checked="">&nbsp;BnFfr23145</label><label><input type="checkbox" name="fields" value="BnFfr49967" checked="">&nbsp;BnFfr49967</label><label><input type="checkbox" name="fields" value="" checked="">&nbsp;</label><label><input type="checkbox" name="fields" value="Cha514" checked="">&nbsp;Cha514</label><label><input type="checkbox" name="fields" value="BnFfr23146" checked="">&nbsp;BnFfr23146</label><label><input type="checkbox" name="fields" value="BnFfr17274" checked="">&nbsp;BnFfr17274</label><label><input type="checkbox" name="fields" value="Vat966" checked="">&nbsp;Vat966</label><label><input type="checkbox" name="fields" value="Aix419" checked="">&nbsp;Aix419</label><label><input type="checkbox" name="fields" value="BnFfr1724" checked="">&nbsp;BnFfr1724</label><label><input type="checkbox" name="fields" value="Aix966" checked="">&nbsp;Aix966</label></div>
<div><b>Search options:</b><label><input type="checkbox" name="prefix" value="true" checked=""> Prefix (considérer la recherche
comme un "début de mot" ; 'qui' renvoit 'qui',
'quidem', etc.)</label><label><input type="checkbox" name="fuzzy" value="true" checked=""> Fuzzy (autoriser les recherches
approximatives)</label></div>
<div><b>Combine terms with:</b><label><input type="radio" name="combineWith" value="OR" checked=""> OR (chercher au moins un des
termes)</label><label><input type="radio" name="combineWith" value="AND"> AND (chercher tous les
termes)</label></div>
</form>
</details>
</div>
<p class="Explanation"> Ceci est un premier jet de recherche, utilisant
la bibliothèque javascript <a href="https://github.com/lucaong/minisearch">MiniSearch</a></p>
<ul class="resultsList"></ul>
</div>
</div><script xmlns="http://www.w3.org/1999/xhtml" src="https://cdn.jsdelivr.net/npm/minisearch@7.1.0/dist/umd/index.min.js"></script><script xmlns="http://www.w3.org/1999/xhtml" src="/static/js/auto_app_minisearch.js"></script><script xmlns="http://www.w3.org/1999/xhtml" src="/static/js/app_minisearch.js"></script>
{% endblock %}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment