mirror of
https://github.com/explosion/spaCy.git
synced 2025-01-14 11:36:24 +03:00
Merge branch 'develop' into spacy.io
This commit is contained in:
commit
0a7a2c73e2
|
@ -9,18 +9,19 @@ from ...compat import unicode_
|
||||||
class RussianLemmatizer(Lemmatizer):
|
class RussianLemmatizer(Lemmatizer):
|
||||||
_morph = None
|
_morph = None
|
||||||
|
|
||||||
def __init__(self, pymorphy2_lang='ru'):
|
def __init__(self):
|
||||||
super(RussianLemmatizer, self).__init__()
|
super(RussianLemmatizer, self).__init__()
|
||||||
try:
|
try:
|
||||||
from pymorphy2 import MorphAnalyzer
|
from pymorphy2 import MorphAnalyzer
|
||||||
except ImportError:
|
except ImportError:
|
||||||
raise ImportError(
|
raise ImportError(
|
||||||
"The Russian lemmatizer requires the pymorphy2 library: "
|
"The Russian lemmatizer requires the pymorphy2 library: "
|
||||||
'try to fix it with "pip install pymorphy2==0.8"'
|
'try to fix it with "pip install pymorphy2==0.8" '
|
||||||
|
'or "pip install git+https://github.com/kmike/pymorphy2.git pymorphy2-dicts-uk"'
|
||||||
|
"if you need Ukrainian too"
|
||||||
)
|
)
|
||||||
|
|
||||||
if RussianLemmatizer._morph is None:
|
if RussianLemmatizer._morph is None:
|
||||||
RussianLemmatizer._morph = MorphAnalyzer(lang=pymorphy2_lang)
|
RussianLemmatizer._morph = MorphAnalyzer()
|
||||||
|
|
||||||
def __call__(self, string, univ_pos, morphology=None):
|
def __call__(self, string, univ_pos, morphology=None):
|
||||||
univ_pos = self.normalize_univ_pos(univ_pos)
|
univ_pos = self.normalize_univ_pos(univ_pos)
|
||||||
|
|
|
@ -1,15 +1,207 @@
|
||||||
# coding: utf8
|
# coding: utf8
|
||||||
from __future__ import unicode_literals
|
from ...symbols import ADJ, DET, NOUN, NUM, PRON, PROPN, PUNCT, VERB, POS
|
||||||
|
from ...lemmatizer import Lemmatizer
|
||||||
from ..ru.lemmatizer import RussianLemmatizer
|
|
||||||
|
|
||||||
|
|
||||||
class UkrainianLemmatizer(RussianLemmatizer):
|
class UkrainianLemmatizer(Lemmatizer):
|
||||||
def __init__(self, pymorphy2_lang="ru"):
|
_morph = None
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super(UkrainianLemmatizer, self).__init__()
|
||||||
try:
|
try:
|
||||||
super(UkrainianLemmatizer, self).__init__(pymorphy2_lang="uk")
|
from pymorphy2 import MorphAnalyzer
|
||||||
except ImportError:
|
|
||||||
|
if UkrainianLemmatizer._morph is None:
|
||||||
|
UkrainianLemmatizer._morph = MorphAnalyzer(lang="uk")
|
||||||
|
except (ImportError, TypeError):
|
||||||
raise ImportError(
|
raise ImportError(
|
||||||
"The Ukrainian lemmatizer requires the pymorphy2 library and dictionaries: "
|
"The Ukrainian lemmatizer requires the pymorphy2 library and
|
||||||
'try to fix it with "pip install git+https://github.com/kmike/pymorphy2.git pymorphy2-dicts-uk"'
|
'dictionaries: try to fix it with "pip uninstall pymorphy2" and'
|
||||||
|
'"pip install git+https://github.com/kmike/pymorphy2.git pymorphy2-dicts-uk"'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def __call__(self, string, univ_pos, morphology=None):
|
||||||
|
univ_pos = self.normalize_univ_pos(univ_pos)
|
||||||
|
if univ_pos == "PUNCT":
|
||||||
|
return [PUNCT_RULES.get(string, string)]
|
||||||
|
|
||||||
|
if univ_pos not in ("ADJ", "DET", "NOUN", "NUM", "PRON", "PROPN", "VERB"):
|
||||||
|
# Skip unchangeable pos
|
||||||
|
return [string.lower()]
|
||||||
|
|
||||||
|
analyses = self._morph.parse(string)
|
||||||
|
filtered_analyses = []
|
||||||
|
for analysis in analyses:
|
||||||
|
if not analysis.is_known:
|
||||||
|
# Skip suggested parse variant for unknown word for pymorphy
|
||||||
|
continue
|
||||||
|
analysis_pos, _ = oc2ud(str(analysis.tag))
|
||||||
|
if analysis_pos == univ_pos or (
|
||||||
|
analysis_pos in ("NOUN", "PROPN") and univ_pos in ("NOUN", "PROPN")
|
||||||
|
):
|
||||||
|
filtered_analyses.append(analysis)
|
||||||
|
|
||||||
|
if not len(filtered_analyses):
|
||||||
|
return [string.lower()]
|
||||||
|
if morphology is None or (len(morphology) == 1 and POS in morphology):
|
||||||
|
return list(set([analysis.normal_form for analysis in filtered_analyses]))
|
||||||
|
|
||||||
|
if univ_pos in ("ADJ", "DET", "NOUN", "PROPN"):
|
||||||
|
features_to_compare = ["Case", "Number", "Gender"]
|
||||||
|
elif univ_pos == "NUM":
|
||||||
|
features_to_compare = ["Case", "Gender"]
|
||||||
|
elif univ_pos == "PRON":
|
||||||
|
features_to_compare = ["Case", "Number", "Gender", "Person"]
|
||||||
|
else: # VERB
|
||||||
|
features_to_compare = [
|
||||||
|
"Aspect",
|
||||||
|
"Gender",
|
||||||
|
"Mood",
|
||||||
|
"Number",
|
||||||
|
"Tense",
|
||||||
|
"VerbForm",
|
||||||
|
"Voice",
|
||||||
|
]
|
||||||
|
|
||||||
|
analyses, filtered_analyses = filtered_analyses, []
|
||||||
|
for analysis in analyses:
|
||||||
|
_, analysis_morph = oc2ud(str(analysis.tag))
|
||||||
|
for feature in features_to_compare:
|
||||||
|
if (
|
||||||
|
feature in morphology
|
||||||
|
and feature in analysis_morph
|
||||||
|
and morphology[feature] != analysis_morph[feature]
|
||||||
|
):
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
filtered_analyses.append(analysis)
|
||||||
|
|
||||||
|
if not len(filtered_analyses):
|
||||||
|
return [string.lower()]
|
||||||
|
return list(set([analysis.normal_form for analysis in filtered_analyses]))
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def normalize_univ_pos(univ_pos):
|
||||||
|
if isinstance(univ_pos, str):
|
||||||
|
return univ_pos.upper()
|
||||||
|
|
||||||
|
symbols_to_str = {
|
||||||
|
ADJ: "ADJ",
|
||||||
|
DET: "DET",
|
||||||
|
NOUN: "NOUN",
|
||||||
|
NUM: "NUM",
|
||||||
|
PRON: "PRON",
|
||||||
|
PROPN: "PROPN",
|
||||||
|
PUNCT: "PUNCT",
|
||||||
|
VERB: "VERB",
|
||||||
|
}
|
||||||
|
if univ_pos in symbols_to_str:
|
||||||
|
return symbols_to_str[univ_pos]
|
||||||
|
return None
|
||||||
|
|
||||||
|
def is_base_form(self, univ_pos, morphology=None):
|
||||||
|
# TODO
|
||||||
|
raise NotImplementedError
|
||||||
|
|
||||||
|
def det(self, string, morphology=None):
|
||||||
|
return self(string, "det", morphology)
|
||||||
|
|
||||||
|
def num(self, string, morphology=None):
|
||||||
|
return self(string, "num", morphology)
|
||||||
|
|
||||||
|
def pron(self, string, morphology=None):
|
||||||
|
return self(string, "pron", morphology)
|
||||||
|
|
||||||
|
def lookup(self, string):
|
||||||
|
analyses = self._morph.parse(string)
|
||||||
|
if len(analyses) == 1:
|
||||||
|
return analyses[0].normal_form
|
||||||
|
return string
|
||||||
|
|
||||||
|
|
||||||
|
def oc2ud(oc_tag):
|
||||||
|
gram_map = {
|
||||||
|
"_POS": {
|
||||||
|
"ADJF": "ADJ",
|
||||||
|
"ADJS": "ADJ",
|
||||||
|
"ADVB": "ADV",
|
||||||
|
"Apro": "DET",
|
||||||
|
"COMP": "ADJ", # Can also be an ADV - unchangeable
|
||||||
|
"CONJ": "CCONJ", # Can also be a SCONJ - both unchangeable ones
|
||||||
|
"GRND": "VERB",
|
||||||
|
"INFN": "VERB",
|
||||||
|
"INTJ": "INTJ",
|
||||||
|
"NOUN": "NOUN",
|
||||||
|
"NPRO": "PRON",
|
||||||
|
"NUMR": "NUM",
|
||||||
|
"NUMB": "NUM",
|
||||||
|
"PNCT": "PUNCT",
|
||||||
|
"PRCL": "PART",
|
||||||
|
"PREP": "ADP",
|
||||||
|
"PRTF": "VERB",
|
||||||
|
"PRTS": "VERB",
|
||||||
|
"VERB": "VERB",
|
||||||
|
},
|
||||||
|
"Animacy": {"anim": "Anim", "inan": "Inan"},
|
||||||
|
"Aspect": {"impf": "Imp", "perf": "Perf"},
|
||||||
|
"Case": {
|
||||||
|
"ablt": "Ins",
|
||||||
|
"accs": "Acc",
|
||||||
|
"datv": "Dat",
|
||||||
|
"gen1": "Gen",
|
||||||
|
"gen2": "Gen",
|
||||||
|
"gent": "Gen",
|
||||||
|
"loc2": "Loc",
|
||||||
|
"loct": "Loc",
|
||||||
|
"nomn": "Nom",
|
||||||
|
"voct": "Voc",
|
||||||
|
},
|
||||||
|
"Degree": {"COMP": "Cmp", "Supr": "Sup"},
|
||||||
|
"Gender": {"femn": "Fem", "masc": "Masc", "neut": "Neut"},
|
||||||
|
"Mood": {"impr": "Imp", "indc": "Ind"},
|
||||||
|
"Number": {"plur": "Plur", "sing": "Sing"},
|
||||||
|
"NumForm": {"NUMB": "Digit"},
|
||||||
|
"Person": {"1per": "1", "2per": "2", "3per": "3", "excl": "2", "incl": "1"},
|
||||||
|
"Tense": {"futr": "Fut", "past": "Past", "pres": "Pres"},
|
||||||
|
"Variant": {"ADJS": "Brev", "PRTS": "Brev"},
|
||||||
|
"VerbForm": {
|
||||||
|
"GRND": "Conv",
|
||||||
|
"INFN": "Inf",
|
||||||
|
"PRTF": "Part",
|
||||||
|
"PRTS": "Part",
|
||||||
|
"VERB": "Fin",
|
||||||
|
},
|
||||||
|
"Voice": {"actv": "Act", "pssv": "Pass"},
|
||||||
|
"Abbr": {"Abbr": "Yes"},
|
||||||
|
}
|
||||||
|
|
||||||
|
pos = "X"
|
||||||
|
morphology = dict()
|
||||||
|
unmatched = set()
|
||||||
|
|
||||||
|
grams = oc_tag.replace(" ", ",").split(",")
|
||||||
|
for gram in grams:
|
||||||
|
match = False
|
||||||
|
for categ, gmap in sorted(gram_map.items()):
|
||||||
|
if gram in gmap:
|
||||||
|
match = True
|
||||||
|
if categ == "_POS":
|
||||||
|
pos = gmap[gram]
|
||||||
|
else:
|
||||||
|
morphology[categ] = gmap[gram]
|
||||||
|
if not match:
|
||||||
|
unmatched.add(gram)
|
||||||
|
|
||||||
|
while len(unmatched) > 0:
|
||||||
|
gram = unmatched.pop()
|
||||||
|
if gram in ("Name", "Patr", "Surn", "Geox", "Orgn"):
|
||||||
|
pos = "PROPN"
|
||||||
|
elif gram == "Auxt":
|
||||||
|
pos = "AUX"
|
||||||
|
elif gram == "Pltm":
|
||||||
|
morphology["Number"] = "Ptan"
|
||||||
|
|
||||||
|
return pos, morphology
|
||||||
|
|
||||||
|
|
||||||
|
PUNCT_RULES = {"«": '"', "»": '"'}
|
||||||
|
|
|
@ -6,8 +6,10 @@ STOP_WORDS = set(
|
||||||
"""а
|
"""а
|
||||||
або
|
або
|
||||||
адже
|
адже
|
||||||
|
аж
|
||||||
але
|
але
|
||||||
алло
|
алло
|
||||||
|
б
|
||||||
багато
|
багато
|
||||||
без
|
без
|
||||||
безперервно
|
безперервно
|
||||||
|
@ -16,6 +18,7 @@ STOP_WORDS = set(
|
||||||
більше
|
більше
|
||||||
біля
|
біля
|
||||||
близько
|
близько
|
||||||
|
бо
|
||||||
був
|
був
|
||||||
буває
|
буває
|
||||||
буде
|
буде
|
||||||
|
@ -29,22 +32,27 @@ STOP_WORDS = set(
|
||||||
були
|
були
|
||||||
було
|
було
|
||||||
бути
|
бути
|
||||||
бывь
|
|
||||||
в
|
в
|
||||||
важлива
|
|
||||||
важливе
|
|
||||||
важливий
|
|
||||||
важливі
|
|
||||||
вам
|
вам
|
||||||
вами
|
вами
|
||||||
вас
|
вас
|
||||||
ваш
|
ваш
|
||||||
ваша
|
ваша
|
||||||
ваше
|
ваше
|
||||||
|
вашим
|
||||||
|
вашими
|
||||||
|
ваших
|
||||||
ваші
|
ваші
|
||||||
|
вашій
|
||||||
|
вашого
|
||||||
|
вашої
|
||||||
|
вашому
|
||||||
|
вашою
|
||||||
|
вашу
|
||||||
вгорі
|
вгорі
|
||||||
вгору
|
вгору
|
||||||
вдалині
|
вдалині
|
||||||
|
весь
|
||||||
вже
|
вже
|
||||||
ви
|
ви
|
||||||
від
|
від
|
||||||
|
@ -59,7 +67,15 @@ STOP_WORDS = set(
|
||||||
вони
|
вони
|
||||||
воно
|
воно
|
||||||
восьмий
|
восьмий
|
||||||
|
все
|
||||||
|
всею
|
||||||
|
всі
|
||||||
|
всім
|
||||||
|
всіх
|
||||||
всього
|
всього
|
||||||
|
всьому
|
||||||
|
всю
|
||||||
|
вся
|
||||||
втім
|
втім
|
||||||
г
|
г
|
||||||
геть
|
геть
|
||||||
|
@ -95,16 +111,15 @@ STOP_WORDS = set(
|
||||||
досить
|
досить
|
||||||
другий
|
другий
|
||||||
дуже
|
дуже
|
||||||
|
дякую
|
||||||
|
е
|
||||||
|
є
|
||||||
|
ж
|
||||||
же
|
же
|
||||||
життя
|
|
||||||
з
|
з
|
||||||
за
|
за
|
||||||
завжди
|
завжди
|
||||||
зазвичай
|
зазвичай
|
||||||
зайнята
|
|
||||||
зайнятий
|
|
||||||
зайняті
|
|
||||||
зайнято
|
|
||||||
занадто
|
занадто
|
||||||
зараз
|
зараз
|
||||||
зате
|
зате
|
||||||
|
@ -112,22 +127,28 @@ STOP_WORDS = set(
|
||||||
звідси
|
звідси
|
||||||
звідусіль
|
звідусіль
|
||||||
здається
|
здається
|
||||||
|
зі
|
||||||
значить
|
значить
|
||||||
знову
|
знову
|
||||||
зовсім
|
зовсім
|
||||||
ім'я
|
і
|
||||||
|
із
|
||||||
|
її
|
||||||
|
їй
|
||||||
|
їм
|
||||||
іноді
|
іноді
|
||||||
інша
|
інша
|
||||||
інше
|
інше
|
||||||
інший
|
інший
|
||||||
інших
|
інших
|
||||||
інші
|
інші
|
||||||
її
|
|
||||||
їй
|
|
||||||
їх
|
їх
|
||||||
|
й
|
||||||
його
|
його
|
||||||
йому
|
йому
|
||||||
|
каже
|
||||||
ким
|
ким
|
||||||
|
кілька
|
||||||
кого
|
кого
|
||||||
кожен
|
кожен
|
||||||
кожна
|
кожна
|
||||||
|
@ -136,13 +157,13 @@ STOP_WORDS = set(
|
||||||
коли
|
коли
|
||||||
кому
|
кому
|
||||||
краще
|
краще
|
||||||
крейдуючи
|
крім
|
||||||
кругом
|
|
||||||
куди
|
куди
|
||||||
ласка
|
ласка
|
||||||
|
ледве
|
||||||
лише
|
лише
|
||||||
люди
|
м
|
||||||
людина
|
має
|
||||||
майже
|
майже
|
||||||
мало
|
мало
|
||||||
мати
|
мати
|
||||||
|
@ -157,20 +178,27 @@ STOP_WORDS = set(
|
||||||
мій
|
мій
|
||||||
мільйонів
|
мільйонів
|
||||||
мною
|
мною
|
||||||
|
мого
|
||||||
могти
|
могти
|
||||||
моє
|
моє
|
||||||
мож
|
моєї
|
||||||
|
моєму
|
||||||
|
моєю
|
||||||
може
|
може
|
||||||
можна
|
можна
|
||||||
можно
|
можно
|
||||||
можуть
|
можуть
|
||||||
можхо
|
|
||||||
мої
|
мої
|
||||||
мор
|
моїй
|
||||||
|
моїм
|
||||||
|
моїми
|
||||||
|
моїх
|
||||||
|
мою
|
||||||
моя
|
моя
|
||||||
на
|
на
|
||||||
навіть
|
навіть
|
||||||
навіщо
|
навіщо
|
||||||
|
навколо
|
||||||
навкруги
|
навкруги
|
||||||
нагорі
|
нагорі
|
||||||
над
|
над
|
||||||
|
@ -183,10 +211,21 @@ STOP_WORDS = set(
|
||||||
наш
|
наш
|
||||||
наша
|
наша
|
||||||
наше
|
наше
|
||||||
|
нашим
|
||||||
|
нашими
|
||||||
|
наших
|
||||||
наші
|
наші
|
||||||
|
нашій
|
||||||
|
нашого
|
||||||
|
нашої
|
||||||
|
нашому
|
||||||
|
нашою
|
||||||
|
нашу
|
||||||
не
|
не
|
||||||
небагато
|
небагато
|
||||||
|
небудь
|
||||||
недалеко
|
недалеко
|
||||||
|
неї
|
||||||
немає
|
немає
|
||||||
нерідко
|
нерідко
|
||||||
нещодавно
|
нещодавно
|
||||||
|
@ -199,17 +238,22 @@ STOP_WORDS = set(
|
||||||
них
|
них
|
||||||
ні
|
ні
|
||||||
ніби
|
ніби
|
||||||
|
ніж
|
||||||
|
ній
|
||||||
ніколи
|
ніколи
|
||||||
нікуди
|
нікуди
|
||||||
|
нім
|
||||||
нічого
|
нічого
|
||||||
ну
|
ну
|
||||||
нх
|
|
||||||
нього
|
нього
|
||||||
|
ньому
|
||||||
о
|
о
|
||||||
|
обидва
|
||||||
обоє
|
обоє
|
||||||
один
|
один
|
||||||
одинадцятий
|
одинадцятий
|
||||||
одинадцять
|
одинадцять
|
||||||
|
однак
|
||||||
однієї
|
однієї
|
||||||
одній
|
одній
|
||||||
одного
|
одного
|
||||||
|
@ -218,11 +262,16 @@ STOP_WORDS = set(
|
||||||
он
|
он
|
||||||
особливо
|
особливо
|
||||||
ось
|
ось
|
||||||
|
п'ятий
|
||||||
|
п'ятнадцятий
|
||||||
|
п'ятнадцять
|
||||||
|
п'ять
|
||||||
перед
|
перед
|
||||||
перший
|
перший
|
||||||
під
|
під
|
||||||
пізніше
|
пізніше
|
||||||
пір
|
пір
|
||||||
|
після
|
||||||
по
|
по
|
||||||
повинно
|
повинно
|
||||||
подів
|
подів
|
||||||
|
@ -233,18 +282,14 @@ STOP_WORDS = set(
|
||||||
потім
|
потім
|
||||||
потрібно
|
потрібно
|
||||||
почала
|
почала
|
||||||
прекрасне
|
початку
|
||||||
прекрасно
|
|
||||||
при
|
при
|
||||||
про
|
про
|
||||||
просто
|
просто
|
||||||
проте
|
проте
|
||||||
проти
|
проти
|
||||||
п'ятий
|
|
||||||
п'ятнадцятий
|
|
||||||
п'ятнадцять
|
|
||||||
п'ять
|
|
||||||
раз
|
раз
|
||||||
|
разу
|
||||||
раніше
|
раніше
|
||||||
рано
|
рано
|
||||||
раптом
|
раптом
|
||||||
|
@ -252,6 +297,7 @@ STOP_WORDS = set(
|
||||||
роки
|
роки
|
||||||
років
|
років
|
||||||
року
|
року
|
||||||
|
році
|
||||||
сам
|
сам
|
||||||
сама
|
сама
|
||||||
саме
|
саме
|
||||||
|
@ -264,15 +310,15 @@ STOP_WORDS = set(
|
||||||
самого
|
самого
|
||||||
самому
|
самому
|
||||||
саму
|
саму
|
||||||
світу
|
|
||||||
свого
|
свого
|
||||||
своє
|
своє
|
||||||
|
своєї
|
||||||
свої
|
свої
|
||||||
своїй
|
своїй
|
||||||
своїх
|
своїх
|
||||||
свою
|
свою
|
||||||
сеаой
|
|
||||||
себе
|
себе
|
||||||
|
сих
|
||||||
сім
|
сім
|
||||||
сімнадцятий
|
сімнадцятий
|
||||||
сімнадцять
|
сімнадцять
|
||||||
|
@ -300,7 +346,17 @@ STOP_WORDS = set(
|
||||||
також
|
також
|
||||||
там
|
там
|
||||||
твій
|
твій
|
||||||
|
твого
|
||||||
твоє
|
твоє
|
||||||
|
твоєї
|
||||||
|
твоєму
|
||||||
|
твоєю
|
||||||
|
твої
|
||||||
|
твоїй
|
||||||
|
твоїм
|
||||||
|
твоїми
|
||||||
|
твоїх
|
||||||
|
твою
|
||||||
твоя
|
твоя
|
||||||
те
|
те
|
||||||
тебе
|
тебе
|
||||||
|
@ -312,15 +368,19 @@ STOP_WORDS = set(
|
||||||
тисяч
|
тисяч
|
||||||
тих
|
тих
|
||||||
ті
|
ті
|
||||||
|
тієї
|
||||||
тією
|
тією
|
||||||
|
тій
|
||||||
тільки
|
тільки
|
||||||
|
тім
|
||||||
|
то
|
||||||
тобі
|
тобі
|
||||||
тобою
|
тобою
|
||||||
того
|
того
|
||||||
тоді
|
тоді
|
||||||
той
|
той
|
||||||
том
|
|
||||||
тому
|
тому
|
||||||
|
тою
|
||||||
треба
|
треба
|
||||||
третій
|
третій
|
||||||
три
|
три
|
||||||
|
@ -338,7 +398,6 @@ STOP_WORDS = set(
|
||||||
усім
|
усім
|
||||||
усіма
|
усіма
|
||||||
усіх
|
усіх
|
||||||
усію
|
|
||||||
усього
|
усього
|
||||||
усьому
|
усьому
|
||||||
усю
|
усю
|
||||||
|
@ -356,6 +415,7 @@ STOP_WORDS = set(
|
||||||
цими
|
цими
|
||||||
цих
|
цих
|
||||||
ці
|
ці
|
||||||
|
цієї
|
||||||
цій
|
цій
|
||||||
цього
|
цього
|
||||||
цьому
|
цьому
|
||||||
|
@ -368,11 +428,24 @@ STOP_WORDS = set(
|
||||||
через
|
через
|
||||||
четвертий
|
четвертий
|
||||||
чи
|
чи
|
||||||
|
чиє
|
||||||
|
чиєї
|
||||||
|
чиєму
|
||||||
|
чиї
|
||||||
|
чиїй
|
||||||
|
чиїм
|
||||||
|
чиїми
|
||||||
|
чиїх
|
||||||
|
чий
|
||||||
|
чийого
|
||||||
|
чийому
|
||||||
чим
|
чим
|
||||||
численна
|
численна
|
||||||
численне
|
численне
|
||||||
численний
|
численний
|
||||||
численні
|
численні
|
||||||
|
чию
|
||||||
|
чия
|
||||||
чого
|
чого
|
||||||
чому
|
чому
|
||||||
чотири
|
чотири
|
||||||
|
@ -385,6 +458,8 @@ STOP_WORDS = set(
|
||||||
ще
|
ще
|
||||||
що
|
що
|
||||||
щоб
|
щоб
|
||||||
|
щодо
|
||||||
|
щось
|
||||||
я
|
я
|
||||||
як
|
як
|
||||||
яка
|
яка
|
||||||
|
@ -393,6 +468,6 @@ STOP_WORDS = set(
|
||||||
які
|
які
|
||||||
якій
|
якій
|
||||||
якого
|
якого
|
||||||
якщо
|
якої
|
||||||
""".split()
|
якщо""".split()
|
||||||
)
|
)
|
||||||
|
|
|
@ -573,7 +573,7 @@ class Language(object):
|
||||||
proc._rehearsal_model = deepcopy(proc.model)
|
proc._rehearsal_model = deepcopy(proc.model)
|
||||||
return self._optimizer
|
return self._optimizer
|
||||||
|
|
||||||
def evaluate(self, docs_golds, verbose=False):
|
def evaluate(self, docs_golds, verbose=False, batch_size=256):
|
||||||
scorer = Scorer()
|
scorer = Scorer()
|
||||||
docs, golds = zip(*docs_golds)
|
docs, golds = zip(*docs_golds)
|
||||||
docs = list(docs)
|
docs = list(docs)
|
||||||
|
@ -582,7 +582,7 @@ class Language(object):
|
||||||
if not hasattr(pipe, "pipe"):
|
if not hasattr(pipe, "pipe"):
|
||||||
docs = (pipe(doc) for doc in docs)
|
docs = (pipe(doc) for doc in docs)
|
||||||
else:
|
else:
|
||||||
docs = pipe.pipe(docs, batch_size=256)
|
docs = pipe.pipe(docs, batch_size=batch_size)
|
||||||
for doc, gold in zip(docs, golds):
|
for doc, gold in zip(docs, golds):
|
||||||
if verbose:
|
if verbose:
|
||||||
print(doc)
|
print(doc)
|
||||||
|
|
|
@ -179,6 +179,7 @@ def tt_tokenizer():
|
||||||
@pytest.fixture(scope="session")
|
@pytest.fixture(scope="session")
|
||||||
def uk_tokenizer():
|
def uk_tokenizer():
|
||||||
pytest.importorskip("pymorphy2")
|
pytest.importorskip("pymorphy2")
|
||||||
|
pytest.importorskip("pymorphy2.lang")
|
||||||
return get_lang_class("uk").Defaults.create_tokenizer()
|
return get_lang_class("uk").Defaults.create_tokenizer()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -92,6 +92,7 @@ def test_uk_tokenizer_splits_open_appostrophe(uk_tokenizer, text):
|
||||||
assert tokens[0].text == "'"
|
assert tokens[0].text == "'"
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.xfail(reason="See #3327")
|
||||||
@pytest.mark.parametrize("text", ["Тест''"])
|
@pytest.mark.parametrize("text", ["Тест''"])
|
||||||
def test_uk_tokenizer_splits_double_end_quote(uk_tokenizer, text):
|
def test_uk_tokenizer_splits_double_end_quote(uk_tokenizer, text):
|
||||||
tokens = uk_tokenizer(text)
|
tokens = uk_tokenizer(text)
|
||||||
|
|
21
spacy/tests/regression/test_issue3328.py
Normal file
21
spacy/tests/regression/test_issue3328.py
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
# coding: utf-8
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
from spacy.matcher import Matcher
|
||||||
|
from spacy.tokens import Doc
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.xfail
|
||||||
|
def test_issue3328(en_vocab):
|
||||||
|
doc = Doc(en_vocab, words=["Hello", ",", "how", "are", "you", "doing", "?"])
|
||||||
|
matcher = Matcher(en_vocab)
|
||||||
|
patterns = [
|
||||||
|
[{"LOWER": {"IN": ["hello", "how"]}}],
|
||||||
|
[{"LOWER": {"IN": ["you", "doing"]}}],
|
||||||
|
]
|
||||||
|
matcher.add("TEST", None, *patterns)
|
||||||
|
matches = matcher(doc)
|
||||||
|
assert len(matches) == 4
|
||||||
|
matched_texts = [doc[start:end].text for _, start, end in matches]
|
||||||
|
assert matched_texts == ["Hello", "how", "you", "doing"]
|
|
@ -22,6 +22,10 @@
|
||||||
"id": "83b0498b1e7fa3c91ce68c3f1",
|
"id": "83b0498b1e7fa3c91ce68c3f1",
|
||||||
"list": "89ad33e698"
|
"list": "89ad33e698"
|
||||||
},
|
},
|
||||||
|
"docSearch": {
|
||||||
|
"apiKey": "371e26ed49d29a27bd36273dfdaf89af",
|
||||||
|
"indexName": "spacy"
|
||||||
|
},
|
||||||
"spacyVersion": "2.1",
|
"spacyVersion": "2.1",
|
||||||
"binderUrl": "ines/spacy-io-binder",
|
"binderUrl": "ines/spacy-io-binder",
|
||||||
"binderBranch": "nightly",
|
"binderBranch": "nightly",
|
||||||
|
|
|
@ -18,6 +18,7 @@ import { ReactComponent as YesIcon } from '../images/icons/yes.svg'
|
||||||
import { ReactComponent as NoIcon } from '../images/icons/no.svg'
|
import { ReactComponent as NoIcon } from '../images/icons/no.svg'
|
||||||
import { ReactComponent as NeutralIcon } from '../images/icons/neutral.svg'
|
import { ReactComponent as NeutralIcon } from '../images/icons/neutral.svg'
|
||||||
import { ReactComponent as OfflineIcon } from '../images/icons/offline.svg'
|
import { ReactComponent as OfflineIcon } from '../images/icons/offline.svg'
|
||||||
|
import { ReactComponent as SearchIcon } from '../images/icons/search.svg'
|
||||||
|
|
||||||
import classes from '../styles/icon.module.sass'
|
import classes from '../styles/icon.module.sass'
|
||||||
|
|
||||||
|
@ -39,6 +40,7 @@ const icons = {
|
||||||
no: NoIcon,
|
no: NoIcon,
|
||||||
neutral: NeutralIcon,
|
neutral: NeutralIcon,
|
||||||
offline: OfflineIcon,
|
offline: OfflineIcon,
|
||||||
|
search: SearchIcon,
|
||||||
}
|
}
|
||||||
|
|
||||||
const Icon = ({ name, width, height, inline, variant, className }) => {
|
const Icon = ({ name, width, height, inline, variant, className }) => {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
import classNames from 'classnames'
|
import classNames from 'classnames'
|
||||||
|
import { navigate } from 'gatsby'
|
||||||
|
|
||||||
import Link from './link'
|
import Link from './link'
|
||||||
import Icon from './icon'
|
import Icon from './icon'
|
||||||
|
@ -8,14 +9,39 @@ import { github } from './util'
|
||||||
import { ReactComponent as Logo } from '../images/logo.svg'
|
import { ReactComponent as Logo } from '../images/logo.svg'
|
||||||
import classes from '../styles/navigation.module.sass'
|
import classes from '../styles/navigation.module.sass'
|
||||||
|
|
||||||
const Navigation = ({ title, items, section, children }) => (
|
const Dropdown = ({ items, section }) => {
|
||||||
|
const active = items.find(({ text }) => text.toLowerCase() === section)
|
||||||
|
const defaultValue = active ? active.url : 'title'
|
||||||
|
return (
|
||||||
|
<select
|
||||||
|
defaultValue={defaultValue}
|
||||||
|
className={classes.dropdown}
|
||||||
|
onChange={({ target }) => navigate(target.value)}
|
||||||
|
>
|
||||||
|
<option value="title" disabled>
|
||||||
|
Menu
|
||||||
|
</option>
|
||||||
|
{items.map(({ text, url }, i) => (
|
||||||
|
<option key={i} value={url}>
|
||||||
|
{text}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</select>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const Navigation = ({ title, items, section, search, children }) => {
|
||||||
|
return (
|
||||||
<nav className={classes.root}>
|
<nav className={classes.root}>
|
||||||
<Link to="/" aria-label={title} hidden>
|
<Link to="/" aria-label={title} hidden>
|
||||||
<h1 className={classes.title}>{title}</h1>
|
<h1 className={classes.title}>{title}</h1>
|
||||||
<Logo className={classes.logo} width={300} height={96} />
|
<Logo className={classes.logo} width={300} height={96} />
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
<ul className={classes.menu}>
|
<div className={classes.menu}>
|
||||||
|
<Dropdown items={items} section={section} />
|
||||||
|
|
||||||
|
<ul className={classes.list}>
|
||||||
{items.map(({ text, url }, i) => {
|
{items.map(({ text, url }, i) => {
|
||||||
const isActive = section && text.toLowerCase() === section
|
const isActive = section && text.toLowerCase() === section
|
||||||
const itemClassNames = classNames(classes.item, {
|
const itemClassNames = classNames(classes.item, {
|
||||||
|
@ -35,9 +61,12 @@ const Navigation = ({ title, items, section, children }) => (
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
{search && <div className={classes.search}>{search}</div>}
|
||||||
|
</div>
|
||||||
{children}
|
{children}
|
||||||
</nav>
|
</nav>
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
Navigation.defaultProps = {
|
Navigation.defaultProps = {
|
||||||
items: [],
|
items: [],
|
||||||
|
@ -52,6 +81,7 @@ Navigation.propTypes = {
|
||||||
})
|
})
|
||||||
),
|
),
|
||||||
section: PropTypes.string,
|
section: PropTypes.string,
|
||||||
|
search: PropTypes.node,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Navigation
|
export default Navigation
|
||||||
|
|
52
website/src/components/search.js
Normal file
52
website/src/components/search.js
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
import React, { useEffect, useState } from 'react'
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
import { window } from 'browser-monads'
|
||||||
|
|
||||||
|
import Icon from './icon'
|
||||||
|
import classes from '../styles/search.module.sass'
|
||||||
|
|
||||||
|
const Search = ({ id, placeholder, settings }) => {
|
||||||
|
const { apiKey, indexName } = settings
|
||||||
|
const [isInitialized, setIsInitialized] = useState(false)
|
||||||
|
useEffect(() => {
|
||||||
|
if (!isInitialized) {
|
||||||
|
setIsInitialized(true)
|
||||||
|
window.docsearch({
|
||||||
|
apiKey,
|
||||||
|
indexName,
|
||||||
|
inputSelector: `#${id}`,
|
||||||
|
debug: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, window.docsearch)
|
||||||
|
return (
|
||||||
|
<form className={classes.root}>
|
||||||
|
<label htmlFor={id} className={classes.icon}>
|
||||||
|
<Icon name="search" width={24} />
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
id={id}
|
||||||
|
className={classes.input}
|
||||||
|
type="search"
|
||||||
|
placeholder={placeholder}
|
||||||
|
aria-label={placeholder}
|
||||||
|
/>
|
||||||
|
</form>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
Search.defaultProps = {
|
||||||
|
id: 'docsearch',
|
||||||
|
placeholder: 'Search docs',
|
||||||
|
}
|
||||||
|
|
||||||
|
Search.propTypes = {
|
||||||
|
settings: PropTypes.shape({
|
||||||
|
apiKey: PropTypes.string.isRequired,
|
||||||
|
indexName: PropTypes.string.isRequired,
|
||||||
|
}).isRequired,
|
||||||
|
id: PropTypes.string.isRequired,
|
||||||
|
placeholder: PropTypes.string.isRequired,
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Search
|
|
@ -1,5 +1,6 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import PropTypes from 'prop-types'
|
import PropTypes from 'prop-types'
|
||||||
|
import classNames from 'classnames'
|
||||||
|
|
||||||
import Button from './button'
|
import Button from './button'
|
||||||
import Tag from './tag'
|
import Tag from './tag'
|
||||||
|
@ -34,7 +35,7 @@ const Title = ({ title, tag, version, teaser, source, image, children, ...props
|
||||||
</Tag>
|
</Tag>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{teaser && <div className={classes.teaser}>{teaser}</div>}
|
{teaser && <div className={classNames('heading-teaser', classes.teaser)}>{teaser}</div>}
|
||||||
|
|
||||||
{children}
|
{children}
|
||||||
</header>
|
</header>
|
||||||
|
|
43
website/src/html.js
Normal file
43
website/src/html.js
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
import React from 'react'
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
|
export default function HTML(props) {
|
||||||
|
return (
|
||||||
|
<html {...props.htmlAttributes}>
|
||||||
|
<head>
|
||||||
|
<meta charSet="utf-8" />
|
||||||
|
<meta httpEquiv="x-ua-compatible" content="ie=edge" />
|
||||||
|
<meta
|
||||||
|
name="viewport"
|
||||||
|
content="width=device-width, initial-scale=1, shrink-to-fit=no"
|
||||||
|
/>
|
||||||
|
{props.headComponents}
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
href="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.css"
|
||||||
|
/>
|
||||||
|
</head>
|
||||||
|
<body {...props.bodyAttributes}>
|
||||||
|
{props.preBodyComponents}
|
||||||
|
<noscript key="noscript" id="gatsby-noscript">
|
||||||
|
This app works best with JavaScript enabled.
|
||||||
|
</noscript>
|
||||||
|
<div key={`body`} id="___gatsby" dangerouslySetInnerHTML={{ __html: props.body }} />
|
||||||
|
{props.postBodyComponents}
|
||||||
|
</body>
|
||||||
|
<script
|
||||||
|
type="text/javascript"
|
||||||
|
src="https://cdn.jsdelivr.net/npm/docsearch.js@2/dist/cdn/docsearch.min.js"
|
||||||
|
/>
|
||||||
|
</html>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
HTML.propTypes = {
|
||||||
|
htmlAttributes: PropTypes.object,
|
||||||
|
headComponents: PropTypes.array,
|
||||||
|
bodyAttributes: PropTypes.object,
|
||||||
|
preBodyComponents: PropTypes.array,
|
||||||
|
body: PropTypes.string,
|
||||||
|
postBodyComponents: PropTypes.array,
|
||||||
|
}
|
3
website/src/images/icons/search.svg
Normal file
3
website/src/images/icons/search.svg
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
|
||||||
|
<path d="M9.516 14.016c2.484 0 4.5-2.016 4.5-4.5s-2.016-4.5-4.5-4.5-4.5 2.016-4.5 4.5 2.016 4.5 4.5 4.5zM15.516 14.016l4.969 4.969-1.5 1.5-4.969-4.969v-0.797l-0.281-0.281c-1.125 0.984-2.625 1.547-4.219 1.547-3.609 0-6.516-2.859-6.516-6.469s2.906-6.516 6.516-6.516 6.469 2.906 6.469 6.516c0 1.594-0.563 3.094-1.547 4.219l0.281 0.281h0.797z"></path>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 440 B |
|
@ -18,6 +18,7 @@
|
||||||
box-shadow: var(--box-shadow)
|
box-shadow: var(--box-shadow)
|
||||||
|
|
||||||
.logo
|
.logo
|
||||||
|
min-width: 95px
|
||||||
width: 95px
|
width: 95px
|
||||||
height: 30px
|
height: 30px
|
||||||
color: var(--color-theme) !important
|
color: var(--color-theme) !important
|
||||||
|
@ -26,23 +27,12 @@
|
||||||
.title
|
.title
|
||||||
display: none
|
display: none
|
||||||
|
|
||||||
.menu
|
.list
|
||||||
display: flex
|
display: flex
|
||||||
height: 100%
|
|
||||||
flex-flow: row nowrap
|
flex-flow: row nowrap
|
||||||
border-color: inherit
|
border-color: inherit
|
||||||
overflow-x: auto
|
|
||||||
overflow-y: hidden
|
|
||||||
-webkit-overflow-scrolling: touch
|
|
||||||
|
|
||||||
@include breakpoint(max, sm)
|
|
||||||
.menu
|
|
||||||
@include scroll-shadow-base(var(--color-shadow))
|
|
||||||
margin-left: 1rem
|
|
||||||
|
|
||||||
@include breakpoint(min, md)
|
|
||||||
.menu
|
|
||||||
justify-content: flex-end
|
justify-content: flex-end
|
||||||
|
margin-bottom: 0.25rem
|
||||||
|
|
||||||
.item
|
.item
|
||||||
display: inline-flex
|
display: inline-flex
|
||||||
|
@ -58,13 +48,40 @@
|
||||||
margin-left: 2em
|
margin-left: 2em
|
||||||
|
|
||||||
&:last-child
|
&:last-child
|
||||||
@include scroll-shadow-cover(right, var(--color-back))
|
|
||||||
padding-right: 2rem
|
padding-right: 2rem
|
||||||
|
|
||||||
&:first-child
|
&:first-child
|
||||||
@include scroll-shadow-cover(left, var(--color-back))
|
|
||||||
padding-left: 2rem
|
padding-left: 2rem
|
||||||
|
|
||||||
|
.menu
|
||||||
|
display: flex
|
||||||
|
flex-flow: row nowrap
|
||||||
|
margin-left: 0.5rem
|
||||||
|
|
||||||
|
.dropdown
|
||||||
|
font-family: var(--font-secondary)
|
||||||
|
font-size: 1.6rem
|
||||||
|
font-weight: bold
|
||||||
|
color: var(--color-theme)
|
||||||
|
text-transform: uppercase
|
||||||
|
background: transparent
|
||||||
|
border: 0
|
||||||
|
margin-right: 0.5rem
|
||||||
|
|
||||||
.is-active
|
.is-active
|
||||||
color: var(--color-dark)
|
color: var(--color-dark)
|
||||||
pointer-events: none
|
pointer-events: none
|
||||||
|
|
||||||
|
.search
|
||||||
|
display: inline-flex
|
||||||
|
align-items: center
|
||||||
|
height: 100%
|
||||||
|
padding-right: 2rem
|
||||||
|
|
||||||
|
@include breakpoint(max, xs)
|
||||||
|
.list
|
||||||
|
display: none
|
||||||
|
|
||||||
|
@include breakpoint(min, sm)
|
||||||
|
.dropdown
|
||||||
|
display: none
|
||||||
|
|
57
website/src/styles/search.module.sass
Normal file
57
website/src/styles/search.module.sass
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
@import base
|
||||||
|
|
||||||
|
.root
|
||||||
|
font: var(--font-size-sm)/var(--line-height-md) var(--font-primary)
|
||||||
|
border: 1px solid var(--color-subtle)
|
||||||
|
border-radius: 2em
|
||||||
|
max-width: 100%
|
||||||
|
display: flex
|
||||||
|
flex-flow: row nowrap
|
||||||
|
|
||||||
|
&:focus-within
|
||||||
|
border-color: var(--color-theme)
|
||||||
|
box-shadow: 0 0 0 1px var(--color-theme)
|
||||||
|
|
||||||
|
.input
|
||||||
|
width: 100%
|
||||||
|
max-width: 100%
|
||||||
|
font: inherit
|
||||||
|
padding: 0.5rem 1rem 0.5rem 0.5rem
|
||||||
|
|
||||||
|
.icon
|
||||||
|
display: inline-block
|
||||||
|
color: var(--color-subtle-dark)
|
||||||
|
padding-left: 0.5rem
|
||||||
|
position: relative
|
||||||
|
top: 0.25rem
|
||||||
|
cursor: pointer
|
||||||
|
|
||||||
|
/* Algolia DocSearch */
|
||||||
|
|
||||||
|
@include breakpoint(max, xs)
|
||||||
|
\:global(.algolia-autocomplete .ds-dropdown-menu)
|
||||||
|
max-width: 90vw
|
||||||
|
min-width: 90vw
|
||||||
|
|
||||||
|
\:global(.algolia-autocomplete .algolia-docsearch-suggestion--category-header)
|
||||||
|
display: block
|
||||||
|
font: bold var(--font-size-lg)/var(--line-height-md) var(--font-secondary)
|
||||||
|
text-transform: uppercase
|
||||||
|
color: var(--color-theme)
|
||||||
|
|
||||||
|
\:global(.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column)
|
||||||
|
color: var(--color-dark)
|
||||||
|
|
||||||
|
\:global(.algolia-autocomplete .algolia-docsearch-suggestion--title)
|
||||||
|
font-size: var(--font-size-sm)
|
||||||
|
|
||||||
|
\:global(.algolia-autocomplete .ds-dropdown-menu .ds-suggestion.ds-cursor .algolia-docsearch-suggestion--content)
|
||||||
|
background: var(--color-subtle-opaque) !important
|
||||||
|
|
||||||
|
\:global(.algolia-autocomplete .algolia-docsearch-suggestion--text)
|
||||||
|
font-size: var(--font-size-sm)
|
||||||
|
|
||||||
|
\:global(.algolia-autocomplete .algolia-docsearch-suggestion--highlight)
|
||||||
|
box-shadow: none !important
|
||||||
|
background: var(--color-theme-opaque) !important
|
||||||
|
color: var(--color-theme-dark) !important
|
|
@ -30,6 +30,7 @@ import Tag from '../components/tag'
|
||||||
import Grid from '../components/grid'
|
import Grid from '../components/grid'
|
||||||
import { YouTube, SoundCloud, Iframe, Image } from '../components/embed'
|
import { YouTube, SoundCloud, Iframe, Image } from '../components/embed'
|
||||||
import Alert from '../components/alert'
|
import Alert from '../components/alert'
|
||||||
|
import Search from '../components/search'
|
||||||
|
|
||||||
const mdxComponents = {
|
const mdxComponents = {
|
||||||
a: Link,
|
a: Link,
|
||||||
|
@ -119,7 +120,12 @@ class Layout extends React.Component {
|
||||||
bodyClass={bodyClass}
|
bodyClass={bodyClass}
|
||||||
/>
|
/>
|
||||||
<AlertSpace />
|
<AlertSpace />
|
||||||
<Navigation title={meta.title} items={meta.navigation} section={section}>
|
<Navigation
|
||||||
|
title={meta.title}
|
||||||
|
items={meta.navigation}
|
||||||
|
section={section}
|
||||||
|
search={<Search settings={meta.docSearch} />}
|
||||||
|
>
|
||||||
<Progress key={location.href} />
|
<Progress key={location.href} />
|
||||||
</Navigation>
|
</Navigation>
|
||||||
{isDocs ? (
|
{isDocs ? (
|
||||||
|
@ -184,6 +190,10 @@ export const pageQuery = graphql`
|
||||||
text
|
text
|
||||||
url
|
url
|
||||||
}
|
}
|
||||||
|
docSearch {
|
||||||
|
apiKey
|
||||||
|
indexName
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
file(fields: { slug: { eq: $slug } }) {
|
file(fields: { slug: { eq: $slug } }) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user