mirror of
				https://gitlab.ub.uni-bielefeld.de/sfb1288inf/nopaque.git
				synced 2025-11-04 04:12:45 +00:00 
			
		
		
		
	Merge branch 'query-builder' of gitlab.ub.uni-bielefeld.de:sfb1288inf/nopaque into query-builder
This commit is contained in:
		@@ -1,9 +1,6 @@
 | 
				
			|||||||
#corpus-analysis-concordance-query-builder-input-field-container {
 | 
					 | 
				
			||||||
  border-bottom: #9E9E9E 1px solid;
 | 
					 | 
				
			||||||
  height: 60px;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#corpus-analysis-concordance-query-builder-input-field {
 | 
					#corpus-analysis-concordance-query-builder-input-field {
 | 
				
			||||||
 | 
					  border-bottom: #9E9E9E 1px solid;
 | 
				
			||||||
 | 
					  min-height: 38px;
 | 
				
			||||||
  margin-top: 23px;
 | 
					  margin-top: 23px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,7 +23,7 @@ class ConcordanceQueryBuilder {
 | 
				
			|||||||
      if (modalId === 'corpus-analysis-concordance-exactly-n-token-modal' || modalId === 'corpus-analysis-concordance-between-nm-token-modal') {
 | 
					      if (modalId === 'corpus-analysis-concordance-exactly-n-token-modal' || modalId === 'corpus-analysis-concordance-between-nm-token-modal') {
 | 
				
			||||||
        button.addEventListener('click', () => this.generalFunctions.tokenNMSubmitHandler(modalId));
 | 
					        button.addEventListener('click', () => this.generalFunctions.tokenNMSubmitHandler(modalId));
 | 
				
			||||||
      } else if (modalId === 'corpus-analysis-concordance-exactly-n-character-modal' || modalId === 'corpus-analysis-concordance-between-nm-character-modal') {
 | 
					      } else if (modalId === 'corpus-analysis-concordance-exactly-n-character-modal' || modalId === 'corpus-analysis-concordance-between-nm-character-modal') {
 | 
				
			||||||
        button.addEventListener('click', () => this.generalFunctions.characterNMSubmitHandler(modalId));
 | 
					        button.addEventListener('click', () => this.tokenAttributeBuilderFunctions.characterNMSubmitHandler(modalId));
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,6 +9,13 @@ class GeneralFunctionsQueryBuilder {
 | 
				
			|||||||
    });
 | 
					    });
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  resetQueryInputField() {
 | 
				
			||||||
 | 
					    this.elements.queryInputField.innerHTML = '';
 | 
				
			||||||
 | 
					    this.addPlaceholder();
 | 
				
			||||||
 | 
					    this.updateChipList();
 | 
				
			||||||
 | 
					    this.queryPreviewBuilder();
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  updateChipList() {
 | 
					  updateChipList() {
 | 
				
			||||||
    this.elements.queryChipElements = this.elements.queryInputField.querySelectorAll('.query-component');
 | 
					    this.elements.queryChipElements = this.elements.queryInputField.querySelectorAll('.query-component');
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -210,7 +217,7 @@ class GeneralFunctionsQueryBuilder {
 | 
				
			|||||||
    let input_n = modal.querySelector('.n-m-input[data-value-type="n"]').value;
 | 
					    let input_n = modal.querySelector('.n-m-input[data-value-type="n"]').value;
 | 
				
			||||||
    let input_m = modal.querySelector('.n-m-input[data-value-type="m"]') || undefined;
 | 
					    let input_m = modal.querySelector('.n-m-input[data-value-type="m"]') || undefined;
 | 
				
			||||||
    input_m = input_m !== undefined ? input_m.value : '';
 | 
					    input_m = input_m !== undefined ? input_m.value : '';
 | 
				
			||||||
    let input = `{${input_n},${input_m}}`;
 | 
					    let input = `{${input_n}${input_m !== '' ? ',' : ''}${input_m}}`;
 | 
				
			||||||
    let pretty_input = `between ${input_n} and ${input_m} (${input})`;
 | 
					    let pretty_input = `between ${input_n} and ${input_m} (${input})`;
 | 
				
			||||||
    if (input_m === '') {
 | 
					    if (input_m === '') {
 | 
				
			||||||
     pretty_input = `exactly ${input_n} (${input})`;
 | 
					     pretty_input = `exactly ${input_n} (${input})`;
 | 
				
			||||||
@@ -220,7 +227,137 @@ class GeneralFunctionsQueryBuilder {
 | 
				
			|||||||
    instance.close();
 | 
					    instance.close();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    this.tokenIncidenceModifierHandler(input, pretty_input);
 | 
					    this.tokenIncidenceModifierHandler(input, pretty_input);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  switchToExpertModeParser() {
 | 
				
			||||||
 | 
					    let expertModeInputField = document.querySelector('#corpus-analysis-concordance-form-query');
 | 
				
			||||||
 | 
					    expertModeInputField.value = '';
 | 
				
			||||||
 | 
					    let queryBuilderInputFieldValue = Utils.unescape(document.querySelector('#corpus-analysis-concordance-query-preview').innerHTML.trim());
 | 
				
			||||||
 | 
					    if (queryBuilderInputFieldValue !== "") {
 | 
				
			||||||
 | 
					      expertModeInputField.value = queryBuilderInputFieldValue;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  switchToQueryBuilderParser() {
 | 
				
			||||||
 | 
					    this.resetQueryInputField();
 | 
				
			||||||
 | 
					    let expertModeInputFieldValue = document.querySelector('#corpus-analysis-concordance-form-query').value;
 | 
				
			||||||
 | 
					    let chipElements = this.parseTextToChip(expertModeInputFieldValue);
 | 
				
			||||||
 | 
					    for (let chipElement of chipElements) {
 | 
				
			||||||
 | 
					      this.queryChipFactory(chipElement['type'], chipElement['pretty'], chipElement['query']);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  parseTextToChip(query) {
 | 
				
			||||||
 | 
					    const parsingElementDict = {
 | 
				
			||||||
 | 
					      '<s>': {
 | 
				
			||||||
 | 
					        pretty: 'Sentence Start',
 | 
				
			||||||
 | 
					        type: 'start-sentence'
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      '<\/s>': {
 | 
				
			||||||
 | 
					        pretty: 'Sentence End',
 | 
				
			||||||
 | 
					        type: 'end-sentence'
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      '<ent>': {
 | 
				
			||||||
 | 
					        pretty: 'Entity Start',
 | 
				
			||||||
 | 
					        type: 'start-empty-entity'
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      '<ent_type="([A-Z]+)">': {
 | 
				
			||||||
 | 
					        pretty: '',
 | 
				
			||||||
 | 
					        type: 'start-entity'
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      '<\\\/ent(_type)?>': {
 | 
				
			||||||
 | 
					        pretty: 'Entity End',
 | 
				
			||||||
 | 
					        type: 'end-entity'
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      ':: ?match\\.text_[A-Za-z]+="[^"]+"': {
 | 
				
			||||||
 | 
					        pretty: '',
 | 
				
			||||||
 | 
					        type: 'text-annotation'
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      '\\[(word|lemma|pos|simple_pos)=(("[^"]+")|(\\u0027[^\\u0027]+\\u0027)) ?(%c)? ?((\\&|\\|) ?(word|lemma|pos|simple_pos)=(("[^"]+")|(\\u0027[^\\u0027]+\\u0027)) ?(%c)? ?)*\\]': {
 | 
				
			||||||
 | 
					        pretty: '',
 | 
				
			||||||
 | 
					        type: 'token'
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      '\\[\\]': {
 | 
				
			||||||
 | 
					        pretty: 'Empty Token',
 | 
				
			||||||
 | 
					        type: 'token'
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      '(?<!\\[) ?\\+ ?(?![^\\]]\\])': {
 | 
				
			||||||
 | 
					        pretty: ' one or more (+)',
 | 
				
			||||||
 | 
					        type: 'token-incidence-modifier'
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      '(?<!\\[) ?\\* ?(?![^\\]]\\])': {
 | 
				
			||||||
 | 
					        pretty: 'zero or more (*)',
 | 
				
			||||||
 | 
					        type: 'token-incidence-modifier'
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      '(?<!\\[) ?\\? ?(?![^\\]]\\])': {
 | 
				
			||||||
 | 
					        pretty: 'zero or one (?)',
 | 
				
			||||||
 | 
					        type: 'token-incidence-modifier'
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      '(?<!\\[) ?\\{[0-9]+} ?(?![^\\]]\\])': {
 | 
				
			||||||
 | 
					        pretty: '',
 | 
				
			||||||
 | 
					        type: 'token-incidence-modifier'
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      '(?<!\\[) ?\\{[0-9]+(,[0-9]+)?} ?(?![^\\]]\\])': {
 | 
				
			||||||
 | 
					        pretty: '',
 | 
				
			||||||
 | 
					        type: 'token-incidence-modifier'
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					    let chipElements = [];
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					    const regex = new RegExp(`<s>|<\/s>|<ent>|<ent_type="([A-Z]+)">|<\\\/ent(_type)?>|\\[(word|lemma|pos|simple_pos)=(("[^"]+")|(\\u0027[^\\u0027]+\\u0027)) ?(%c)? ?((\\&|\\|) ?(word|lemma|pos|simple_pos)=(("[^"]+")|(\\u0027[^\\u0027]+\\u0027)) ?(%c)? ?)*\\]|:: ?match\\.text_[A-Za-z]+="[^"]+"|(?<!\\[) ?(\\+|\\?|\\*|{[0-9]+(,[0-9]+)?}) ?(?![^\\]]\\])`, 'gi');
 | 
				
			||||||
 | 
					    let match;
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					    while ((match = regex.exec(query)) !== null) {
 | 
				
			||||||
 | 
					      // This is necessary to avoid infinite loops with zero-width matches
 | 
				
			||||||
 | 
					      if (match.index === regex.lastIndex) {
 | 
				
			||||||
 | 
					        regex.lastIndex++;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      let stringElement = match[0];
 | 
				
			||||||
 | 
					      for (let [pattern, chipElement] of Object.entries(parsingElementDict)) {
 | 
				
			||||||
 | 
					        const parsingRegex = new RegExp(pattern, 'gi');
 | 
				
			||||||
 | 
					        if (parsingRegex.exec(stringElement)) {
 | 
				
			||||||
 | 
					          let prettyText;
 | 
				
			||||||
 | 
					          switch (pattern) {
 | 
				
			||||||
 | 
					            case '<ent_type="([A-Z]+)">':
 | 
				
			||||||
 | 
					              prettyText = `Entity Type=${stringElement.replace(/<ent_type="|">/g, '')}`;
 | 
				
			||||||
 | 
					              break;
 | 
				
			||||||
 | 
					            case ':: ?match\\.text_[A-Za-z]+="[^"]+"':
 | 
				
			||||||
 | 
					              prettyText = stringElement.replace(/:: ?match\.text_|"|"/g, '');
 | 
				
			||||||
 | 
					              break;
 | 
				
			||||||
 | 
					            case '\\[(word|lemma|pos|simple_pos)=(("[^"]+")|(\\u0027[^\\u0027]+\\u0027)) ?(%c)? ?((\\&|\\|) ?(word|lemma|pos|simple_pos)=(("[^"]+")|(\\u0027[^\\u0027]+\\u0027)) ?(%c)? ?)*\\]':
 | 
				
			||||||
 | 
					              let doubleQuotes = /(word|lemma|pos|simple_pos)="[^"]+"/gi;
 | 
				
			||||||
 | 
					              let singleQuotes = /(word|lemma|pos|simple_pos)='[^']+'/gi;
 | 
				
			||||||
 | 
					              if (doubleQuotes.exec(stringElement)) {
 | 
				
			||||||
 | 
					                prettyText = stringElement.replace(/^\[|\]$|"/g, '');
 | 
				
			||||||
 | 
					              } else if (singleQuotes.exec(stringElement)) {
 | 
				
			||||||
 | 
					                prettyText = stringElement.replace(/^\[|\]$|'/g, '');
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					              prettyText = prettyText.replace(/\&/g, ' and ').replace(/\|/g, ' or ');
 | 
				
			||||||
 | 
					              break;
 | 
				
			||||||
 | 
					            case '(?<!\\[) ?\\{[0-9]+} ?(?![^\\]]\\])':
 | 
				
			||||||
 | 
					              prettyText = `exactly ${stringElement.replace(/{|}/g, '')} (${stringElement})`;
 | 
				
			||||||
 | 
					              break;
 | 
				
			||||||
 | 
					            case '(?<!\\[) ?\\{[0-9]+(,[0-9]+)?} ?(?![^\\]]\\])':
 | 
				
			||||||
 | 
					              prettyText = `between${stringElement.replace(/{|}/g, ' ').replace(',', ' and ')}(${stringElement})`;
 | 
				
			||||||
 | 
					              break;
 | 
				
			||||||
 | 
					            default:
 | 
				
			||||||
 | 
					              prettyText = chipElement.pretty;
 | 
				
			||||||
 | 
					              break;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          chipElements.push({
 | 
				
			||||||
 | 
					            type: chipElement.type,
 | 
				
			||||||
 | 
					            pretty: prettyText,
 | 
				
			||||||
 | 
					            query: stringElement
 | 
				
			||||||
 | 
					          });
 | 
				
			||||||
 | 
					          break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					    return chipElements;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -141,7 +141,7 @@ class TokenAttributeBuilderFunctionsQueryBuilder extends GeneralFunctionsQueryBu
 | 
				
			|||||||
          this.disableTokenSubmit();
 | 
					          this.disableTokenSubmit();
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
          tokenQueryPrettyText += `simple_pos=${this.elements.simplePosSelection.value}`;
 | 
					          tokenQueryPrettyText += `simple_pos=${this.elements.simplePosSelection.value}`;
 | 
				
			||||||
          tokenQueryCQLText += `simple_pos='${this.elements.simplePosSelection.value}'`;
 | 
					          tokenQueryCQLText += `simple_pos="${this.elements.simplePosSelection.value}"`;
 | 
				
			||||||
          this.elements.simplePosSelection.value = '';
 | 
					          this.elements.simplePosSelection.value = '';
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        break;
 | 
					        break;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -129,6 +129,7 @@
 | 
				
			|||||||
{% macro scripts() %}
 | 
					{% macro scripts() %}
 | 
				
			||||||
<script>
 | 
					<script>
 | 
				
			||||||
  const corpusAnalysisConcordance = new CorpusAnalysisConcordance(corpusAnalysisApp);
 | 
					  const corpusAnalysisConcordance = new CorpusAnalysisConcordance(corpusAnalysisApp);
 | 
				
			||||||
 | 
					  const concordanceQueryBuilder = new ConcordanceQueryBuilder();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  let queryBuilderDisplay = document.getElementById("corpus-analysis-concordance-query-builder-display");
 | 
					  let queryBuilderDisplay = document.getElementById("corpus-analysis-concordance-query-builder-display");
 | 
				
			||||||
  let expertModeDisplay = document.getElementById("corpus-analysis-concordance-expert-mode-display");
 | 
					  let expertModeDisplay = document.getElementById("corpus-analysis-concordance-expert-mode-display");
 | 
				
			||||||
@@ -138,11 +139,12 @@
 | 
				
			|||||||
    if (this.checked) {
 | 
					    if (this.checked) {
 | 
				
			||||||
      queryBuilderDisplay.classList.add("hide");
 | 
					      queryBuilderDisplay.classList.add("hide");
 | 
				
			||||||
      expertModeDisplay.classList.remove("hide");
 | 
					      expertModeDisplay.classList.remove("hide");
 | 
				
			||||||
 | 
					      concordanceQueryBuilder.generalFunctions.switchToExpertModeParser();
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      queryBuilderDisplay.classList.remove("hide");
 | 
					      queryBuilderDisplay.classList.remove("hide");
 | 
				
			||||||
      expertModeDisplay.classList.add("hide");
 | 
					      expertModeDisplay.classList.add("hide");
 | 
				
			||||||
 | 
					      concordanceQueryBuilder.generalFunctions.switchToQueryBuilderParser();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
{{ query_builder.scripts(id_prefix) }}
 | 
					 | 
				
			||||||
{% endmacro %}
 | 
					{% endmacro %}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,7 @@
 | 
				
			|||||||
  <form id="corpus-analysis-concordance-expert-mode-form">
 | 
					  <form id="corpus-analysis-concordance-expert-mode-form">
 | 
				
			||||||
    <div class="input-field col s12 m9">
 | 
					    <div class="input-field col s12 m9">
 | 
				
			||||||
      <i class="material-icons prefix">search</i>
 | 
					      <i class="material-icons prefix">search</i>
 | 
				
			||||||
      <input class="validate corpus-analysis-action" id="corpus-analysis-concordance-form-query" name="query" type="text" required pattern=".*\S+.*" placeholder="Type in your query or use the Query Builder on the right"></input>
 | 
					      <input class="validate corpus-analysis-action" id="corpus-analysis-concordance-form-query" name="query" type="text" required pattern=".*\S+.*" placeholder="Type in your query via CQL"></input>
 | 
				
			||||||
      <span class="error-color-text helper-text hide" id="corpus-analysis-concordance-error"></span>
 | 
					      <span class="error-color-text helper-text hide" id="corpus-analysis-concordance-error"></span>
 | 
				
			||||||
      <a class="modal-trigger" data-manual-modal-chapter="manual-modal-cqp-query-language" href="#manual-modal" style="margin-left: 40px;"><i class="material-icons" style="font-size: inherit;">help</i> Corpus Query Language tutorial</a>
 | 
					      <a class="modal-trigger" data-manual-modal-chapter="manual-modal-cqp-query-language" href="#manual-modal" style="margin-left: 40px;"><i class="material-icons" style="font-size: inherit;">help</i> Corpus Query Language tutorial</a>
 | 
				
			||||||
      <span> | </span>
 | 
					      <span> | </span>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -434,8 +434,8 @@
 | 
				
			|||||||
</div>
 | 
					</div>
 | 
				
			||||||
{% endmacro %}
 | 
					{% endmacro %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{% macro scripts(id_prefix) %}
 | 
					{# {% macro scripts(id_prefix) %}
 | 
				
			||||||
<script>
 | 
					<script>
 | 
				
			||||||
  const concordanceQueryBuilder = new ConcordanceQueryBuilder();
 | 
					  const concordanceQueryBuilder = new ConcordanceQueryBuilder();
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
{% endmacro %}
 | 
					{% endmacro %} #}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user