Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
No results found
Show changes
Showing
with 5735 additions and 186 deletions
<template id="">
<main tabindex="-1" ref="main" id="main">
<div class='about' :class="$vuetify.breakpoint.name">
<div id="return_to_results" v-if="$store.state.searchRoute && $route.name == 'about'">
<router-link id="return_link"
:to="$store.state.searchRoute">
<v-icon left
class="nav_arrow">chevron_left</v-icon>{{$t("notifications.back")}}
</router-link>
</div>
<div class="article" v-if="$store.state.currentLocale == 'eng'">
<h1> About </h1>
<p>This is the website for the two Norwegian standard dictionaries <em>Bokmålsordboka</em> and <em>Nynorskordboka</em>. The website is still under development, so some features may not yet be in place. The content of the dictionaries is undergoing revision, and the editorial staff continuously publishes new word-articles, or articles which have been revised and quality checked.</p>
<p>In connection with the website upgrade, we have cleaned up both the interface and our data. Therefore, there may be errors and omissions in the new solution that have not yet discovered, or have had time to get sorted. Should you discover an error or a wrong or defective article, we appreciate your feedback very much! Feel free to contact us via email:</p>
<p><ul class="bullet">
<li>{{$t('contact.content[2]')}}<a href="mailto:ordbok@uib.no">ordbok@uib.no</a></li>
<li>{{$t('contact.content[3]')}}<a href="mailto:ordbok-teknisk@uib.no">ordbok-teknisk@uib.no</a></li>
</ul></p>
<details>
<summary><h2>What if I cannot find a word in the dictionary?</h2></summary>
<p><em>Bokmålsordboka</em> and <em>Nynorskordboka</em> are medium-sized online dictionaries. The original dictionary in Bokmål contained around 65,000 articles and the Nynorsk dictionary freatured almost 90,000. After the <a href="https://www.uib.no/lle/revisjonsprosjektet">current dictionary revision</a>, it is estimated that both dictionaries will contain around 100,000 articles. The dictionaries document the central vocabulary in Norwegian – basically the most commonly occurring words in the written languages Bokmål and Nynorsk in the last 50 years that have been included. Specialised terms and terminology are only included if also used outside the field in which they have arisen.</p>
<p>The most common way to make new words in Norwegian is to compound existing words in new ways – and there are countless combination possibilities. Therefore, many compounds will not have their own articles in Bokmålsordboka and Nynorskordboka. Thus, if you do not find the Norwegian term for ‘bicycle seat’ (<em>sykkelsete</em>) as an entry in the dictionaries, it does not mean that the word does not exist or is not allowed to use. Compound words are generally only included based on the following considerations:</p>
<p><ul class="bullet">
<li>when the compound is not immediately understandable from the knowledge of each individual compound element</li>
<li>so that the dictionary user confer on what other compounds with the same first element mean, based on selection of compound words included</li>
<li>to show which binding letter the composition should have (<em>skogbruk</em> (forestry), but skog<u>s</u>arbeid (forestry work); <em>sakfører</em> (lawyer), but <em>sak<u>s</u>sbehandler</em> (caseworker); <em>ost<u>e</u>klokke</em> (cheese bell), but <em>dørklokke</em> (door bell))</li>
</ul></p>
<p>Similarly, only a limited selection of derivatives (for example, verbal nouns in <em>-ing</em>) are included in the standard dictionaries. In Norwegian it is possible to form ing-forms from most verbs. Thus, you will be able to find the words <em>organisere</em> (to organise) and <em>sitere</em> (to quote, to cite) in <em>Bokmålsordboka</em> and <em>Nynorskordboka</em>, and form the derivations <em>organisering</em> (organisation) and <em>sitering</em> (quotation, citation) yourself. Note, however, that there are potential <em>ing-</em>forms that are rarely used, such as <em>komming</em> (coming) and <em>væring</em> (being).</p>
<p>The <em>Bokmålsordboka</em> and <em>Nynorskordboka</em> are not to be regarded as lists of words permitted to use in Norwegian. There are many words – old as well as new – that are not in the dictionaries. But you can use anyway. New words do not need official approval before they can be used. It is the language users who jointly decide which words are commonly used in Norwegian. Normally, new words do not enter the dictionaries until they have been in use for some time and are well-established in the language. The dictionary editors decide which words are to be included based on surveys of large text corpora, and the Norwegian Language Council decides how the words are to be spelled and inflected.</p>
<p><a href="https://www.sprakradet.no/Vi-og-vart/Publikasjoner/Spraaknytt/spraknytt-2014/Spraknytt-12014/Ord-som-finst-og-ikkje-finst/">Read more about the word selection</a> in e.g. <em>Bokmålsordboka</em> and <em>Nynorskordboka</em>.</p>
<p>If you do not find the word you are looking for, you can check the larger documentation dictionaries <a href="https://alfa.norsk-ordbok.no">Norsk Ordbok (for Nynorsk and dialect words)</a> and <a href="https://naob.no/">NAOB (for Bokmål)</a>.</p>
</details>
<details>
<summary><h2>Quality-Assured Content</h2></summary>
<p><em>Bokmålsordboka</em> and <em>Nynorskordboka</em> are two independent, monolingual dictionaries for Bokmål and Nynorsk, respectively. The dictionaries are jointly owned by the Language Council and the University of Bergen.</p>
<p><a href ="https://www.sprakradet.no/">The Norwegian Language Council</a> decides how words are spelled and inflected in Bokmål and Nynorsk. <em>Bokmålsordboka</em> and <em>Nynorskordboka</em> are continuously being updated in line with spelling decisions in the Language Council and is the right place for information on what is current and correct spelling in Bokmål and Nynorsk.</p>
<p>Since 2016, the editorial work with the standard dictionaries <em>Bokmålsordboka</em> and <em>Nynorskordboka</em> has been carried out at the University of Bergen, with several departments involved. <a href ="https://www.uib.no/en/ub/spesial/161345/about-norwegian-language-collections">The Norwegian Language Collections</a> manage the dictionaries and the source material on which they are based. The dictionary editors are employed at the <a href="https://www.uib.no/lle">Department of Linguistic, Literary and Aesthetic Studies (LLE)</a>, and the computer technical work takes place at the <a href="https://www.uib.no/it">IT department</a> and the Norwegian Language Collections at the University Library. The content of the dictionaries is quality assured by the Language Council.</p>
</details>
<details>
<summary><h2>Citing the dictionaries</h2></summary>
<p>The contents of <em>Bokmålsordboka</em> and <em>Nynorskordboka</em> are protected by copyright, cf. the Norwegian copyright act: Lov om opphavsrett til åndsverk. Should you wish to quote an article in Bokmålsordboka or Nynorskordboka, we recommend stating when the article was retrieved (read) when quoting, such as e.g.:</p>
<p>"Hvordan". In: <em>Bokmålsordboka</em>. The Norwegian Language Council and the University of Bergen. &lt;http: //ordbøkene.no&gt; (retrieved 25.1.2022).</p>
<p>Both owners of the dictionary, the Norwegian Language Council and the University of Bergen, must be mentioned in the reference</p>
</details>
<details>
<summary><h2>Adding a shortcut on your smartphone</h2></summary>
<p>The website, ordbøkene.no, has a responsive design. This means that the dictionary content adapts to screens of all sizes. If you wish to have a shortcut to Bokmålsordboka and Nynorskordboka on your smartphone, search for ordbøkene.no in the browser and place it as an icon on the screen. The icon looks like an app, and you can click right into the website without opening your browser.</p>
<h3>For iPhone / iOS</h3>
<p>
<ul class="bullet">
<li>Open your browser and type ordbokene.no or ordbøkene.no.</li>
<li>From the front page, select the share icon <v-icon>ios_share</v-icon> at the bottom of the page.</li>
<li>From the double row of sub-options, select the icon "Add to Home Screen" <v-icon>add_box</v-icon>. You may need to drag the row from the right to get to the icon.</li>
</ul>
</p><p>
The dictionaries icon <img class="ordbokene-icon" src="favicon.ico" aria-hidden="true"/> is now on your home screen, and you can access the dictionary page directly by clicking on it.
</p>
<h3>For Android</h3>
<p>
<ul class="bullet">
<li>Open the browser and type ordbokene.no or ordbøkene.no.</li>
<li>From the front page, select the icon with the three vertical dots in the upper right corner.</li>
<li>A list of options appears. Select "Add to home page", a little down the list.</li>
<li>A new window appears asking you to add ordbøkene.no to your home screen. Click "Add".</li>
</ul>
</p>
<p>
The dictionaries icon is now on your home screen, and you can access the dictionary page directly by clicking on it.
NB! On some models from Samsung, the option "Add page in" is found in a menu at the bottom of the page. From there, select the home screen.
</p>
</details>
<details>
<summary><h2>Open Data</h2></summary>
<p>The contents of <em>Bokmålsordboka</em> and <em>Nynorskordboka</em> are openly available for download, and can be used for any purpose, including commercial, in accordance with the conditions given. <a href="https://www.uib.no/ub/fagressurser/spesialsamlingene/142334/lisens-bokm%C3%A5lsordboka-og-nynorskordboka">Read more about the open license here</a>.</p>
<p>Inflection information in Bokmålsordboka and Nynorskordboka is sourced from Norsk ordbank (Norwegian Word Database). Ordbanken is a lexical database for Bokmål and Nynorsk providing information on word class and standard inflection for far more words than those found in the standard dictionaries. Norsk ordbank is available for download at Språkbanken at the National Library under a CC-BY license.</p>
</details>
<details>
<summary><h2>History</h2></summary>
<p>The standard dictionaries <em>Bokmålsordboka</em> and <em>Nynorskordboka</em> were first published in 1986 as a collaborative project between the University of Oslo and the Norwegian Language Council and have since been issued in several editions. In printed form, <em>Bokmålsordboka</em> and <em>Nynorskordboka</em> are large single-volume dictionaries. Spelling and inflection are always in line with current standards. Furthermore, the dictionaries state meanings, examples of usage and give short etymologies. </p>
<p><a href="https://www.uib.no/sites/w3.uib.no/files/attachments/om_ordbokene.pdf">Here you will find the preface to the printed editions (in Norwegian)</a> and more information about previous dictionary editors and the earlier work carried out at the University of Oslo. </p>
<p>The University of Bergen and the Language Council will no longer be issuing printed editions of the standard dictionaries. </p>
</details>
<details>
<summary><h2>Dictionary revision</h2></summary>
<p>The Bokmålsordboka and Nynorskordboka are currently undergoing an extensive content update. During the period 2018–2023, an editorial group is revising both dictionaries from a to å. The most important tasks are to bring in new words and update meanings, and make sure that the content is in line with current language use. Making the selection of words more similar in the two dictionaries is also a priority. More information can be found on the Dictionary Revision Project’s website (in Norwegian). </p>
<p>Current editorial staff of <em>Bokmålsordboka</em> and <em>Nynorskordboka</em>:<ul>
<li>Anne Engø, editor 2018–2023</li>
<li>Marita Kristiansen, editor 2020–2021</li>
<li>Gunn Inger Lyse, editor 2018–2023</li>
<li>Mikkel Ekeland Paulsen, PhD candidate 2019–2023</li>
<li>Margunn Rauset, project manager 2018–2023</li>
<li>Bente Selback, editor 2018–2023</li>
<li>Kari-Anne Selvik, editor 2018–2023</li>
<li>Klara Sjo, editor 2020–2023</li>
<li>Marie Lund Stokka, editor 2020</li>
<li>Terje Svardal, editor at the Norwegian Language Collections</li>
</ul></p>
<p>Quality controllers in the Language Council:<ul>
<li>Sturla Berg-Olsen, senior adviser</li>
<li>Knut E. Karlsen, senior adviser</li>
<li>Dagfinn Rødningen, senior adviser</li>
<li>Ålov Runde, senior adviser</li>
</ul></p>
<p>IT Developers at the University of Bergen<ul>
<li>Henrik Askjer, head engineer, Norwegian Language Collections</li>
<li>Eirik T. Gullaksen, head engineer, IT department</li>
<li>Paul Meurer, senior engineer, Norwegian Language Collections</li>
<li>Nils Øverås, head engineer, IT department</li>
<li>Ole Voldsæter, head engineer, IT department 2019–2021</li>
</ul></p>
<p><a href="https://www.netlife.com/">Netlife</a> has conducted user surveys and prepared design sketches for ordbøkene.no.</p>
</details>
<details>
<summary><h2>Useful Links to Language Resources</h2></summary>
<p>Should you have questions about clear, good and correct Norwegian language use, please contact the <a href="mailto:sporsmal@sprakradet.no">Language Council's response service.</a></p>
<h3>Online language resources</h3>
The Norwegian Language Collections at the University of Bergen Library have a number of language resources, including:
<p><ul class="bullet">
<li><a href="https://ord.uib.no/">ord.uib.no:</a> word lists and API-description for Ordbøkene.no (Norwegian. <a href="https://ordbokene.no/api/swagger-ui.html">Interactive documentation in english</a>).</li>
<li><a href="http://inger.uib.no/perl/search/search.cgi?appid=72&tabid=1106">Norsk ordbank, bokmål</a>: Search full declension form lists for Norwegian Bokmål </li>
<li><a href="http://inger.uib.no/perl/search/search.cgi?appid=73&tabid=1116">Norsk ordbank, nynorsk</a>: Search full declension form lists for Norwegian Nynorsk </li>
<li><a href="http://inger.uib.no/perl/search/search.cgi?appid=7&tabid=571">Metaordboka</a>: A documentation database of all registered words sorted by standard Nynorsk headwords </li>
<li><a href="http://inger.uib.no/perl/search/search.cgi?appid=118&tabid=1777">Ordbokhotellet</a>: An electronic index of word forms from a number of dictionaries and local dialect collections sorted under their standardised headword </li>
</ul></p>
<p>
<a href="http://www.sprakradet.no/">The Language Council</a> has several language resources under the menu “Language Help”, go to <a href="http://www.sprakradet.no/sprakhjelp/Skriveregler/">spelling rules</a>, <a href="http://www.sprakradet.no/sprakhjelp/Praktisk-grammatikk/">practical grammar</a> or <a href="http://www.sprakradet.no/sprakhjelp/Skriverad/">writing advice</a>.
</p>
<p>Norsk ordbank (Norwegian Word Database) is also available for download at <a href="https://www.nb.no/sprakbanken/ressurskatalog/?_search=ordbank">Språkbanken at the National Library</a> under a CC-BY license. The dictionary contains word lists for Bokmål and Nynorsk with information on word class and standard inflection.
</p>
<h3>Other quality-assured and freely available dictionaries</h3>
<p><ul class="bullet">
<li><a href="https://alfa.norsk-ordbok.no">Norsk Ordbok</a>: The dictionary of the Norwegian vernacular and written Nynorsk </li>
<li><a href="https://naob.no/">NAOB</a>: The Norwegian Academy's Dictionary: Bokmål and Riksmål from the early 1800s until today </li>
<li><a href="http://lexin.udir.no/">LEXIN</a>: dictionaries for minority language students in primary, secondary and adult education </li>
<li><a href="https://islex.arnastofnun.is/no/">Islex</a>: A dictionary in Icelandic-Norwegian (Bokmål and Nynorsk), Icelandic-Swedish, Icelandic-Danish, Icelandic-Faroese and Icelandic-Finnish </li>
<li><a href="http://ordnet.dk/">ordnet.dk</a>: A joint website for several Danish dictionaries and word corpora </li>
<li><a href="https://svenska.se/">svenska.se</a>: A joint website for several Swedish dictionaries </li>
</ul></p>
</details>
<details>
<summary><h2>Privacy</h2></summary>
<p>Ordbøkene.no does not use cookies, but saves user preferences using local storage in the browser, without sending this information to our server at UiB. Searches are logged on the server, but we do not use this information for other purposes than search statistics.
We use a Nginx-webserver that continuously overwrites the logs, so that we never store IP-addresses permanently. We also log the usage of certain features on the website using plausible.io, a service that does not store IP-addresses or other information that can connect the usage statistics to individual users.</p>
</details>
</div>
<div class="article" v-if="$store.state.currentLocale == 'nno'">
<h1>Om ordbøkene</h1>
<p>
Dette er nettsida til standardordbøkene <em>Bokmålsordboka</em> og <em>Nynorskordboka</em>. Sida er
framleis under utvikling, så det er visse
funksjonar som ikkje er heilt på plass enno. Arbeidet med å revidere
innhaldet i ordbøkene er på gang, og redaksjonen legg fortløpande ut
ordartiklar som er reviderte og kvalitetssjekka.
</p>
<p>
I samband med oppgraderinga har vi rydda både i grensesnittet og dataa
våre. Derfor kan det vere feil og manglar i den nye løysinga som vi ikkje
har oppdaga enno, eller ikkje har hatt tid til å få på plass. Dersom du
oppdagar noko som er feil eller mangelfullt, vil vi gjerne ha
tilbakemelding om det! Kontakt oss gjerne på e-post:</p>
<p><ul class="bullet">
<li>{{$t('contact.content[2]')}}<a href="mailto:ordbok@uib.no">ordbok@uib.no</a></li>
<li>{{$t('contact.content[3]')}}<a href="mailto:ordbok-teknisk@uib.no">ordbok-teknisk@uib.no</a></li>
</ul></p>
<details>
<summary>
<h2>Kva betyr det om du ikkje finn eit ord i ordboka?</h2>
</summary>
<p>
<em>Bokmålsordboka</em>
og <em>Nynorskordboka</em> er mellomstore nettordbøker.<em>Bokmålsordboka</em> har hatt rundt 65&nbsp;000 oppslagsord
og<em>Nynorskordboka</em> rundt 90&nbsp;000, men etter <a href="https://www.uib.no/lle/revisjonsprosjektet">den
revisjonen som
er på gang</a>, reknar vi med at begge skal innehalde rundt 100 000
oppslagsord. Ordbøkene skal gjere greie for det sentrale ordtilfanget, og
det er i utgangspunktet dei vanlegaste orda i skriftspråka bokmål og
nynorsk dei siste 50 åra som er tekne med. Faguttrykk er berre tekne med i
den grad dei òg er i bruk utanfor fagfeltet dei oppstod i.
</p>
<p>
Den vanlegaste måten vi lagar nye norske ord på, er å setje saman gamle ord
på nye måtar, og det er tallause måtar å kombinere dei på. Derfor er det
mange samansetningar som ikkje har eigne artiklar i <em>Bokmålsordboka</em>
og <em>Nynorskordboka</em>. Sjølv om du ikkje finn<em> sykkelsete</em> som
oppslagsord her, tyder ikkje det at ordet ikkje finst eller ikkje er lov å
skrive. Samansette ord er særleg tekne med ut frå tre omsyn:
</p>
<ul class="bullet">
<li>når dei ikkje utan vidare er forståelege ut frå kjennskap til dei enkelte ledda</li>
<li>for at ordbokbrukaren på grunnlag av dei samansetningane som er tekne med, kan slutte seg til kva andre
samansetningar med same forledd tyder</li>
<li>for å vise kva bindebokstav samansetninga skal ha, om nokon (<em>skogbruk</em>, men <em>skog<u>s</u>arbeid</em>;
<em>sakførar</em>, men <em>sak<u>s</u>behandlar</em>;<em> ost<u>e</u>klokke</em>, men<em> dørklokke</em>)</li>
</ul>
<p>
Tilsvarande er berre eit avgrensa utval av avleiingar (for eksempel
verbalsubstantiv på -<em>ing</em>) tekne med i standardordbøkene. På norsk
kan vi danne<em> ing</em>-former av dei aller fleste verb, så finn du
oppslagsorda <em>organisere</em> og <em>sitere</em> i <em>Bokmålsordboka</em> og <em>Nynorskordboka</em>, kan du
sjølv lage
avleiingane <em>organisering</em> og <em>sitering</em>. Merk likevel at det
finst potensielle <em>ing</em>-former som sjeldan blir brukte, til dømes <em>koming</em> og <em>vering</em>.
</p>
<p>
<em>Bokmålsordboka</em>
og <em>Nynorskordboka</em> er ikkje å rekne som lister over kva ord som er
tillatne å bruke på norsk. Det finst mange ord, både gamle og nye, som
ikkje er med i ordbøkene, men som du gjerne kan bruke likevel. Det er
heller ikkje slik at nye ord må godkjennast før dei kan takast i bruk, det
er språkbrukarane som i fellesskap avgjer kva ord som er gangbare i norsk.
Normalt kjem ikkje nye ord inn i ordbøkene før dei har vore i bruk ei stund
og er etablerte i språket. Ordbokredaksjonen avgjer kva ord som skal vere
med basert på undersøkingar av store tekstsamlingar, og Språkrådet avgjer
korleis orda skal stavast og bøyast.
</p>
<p>
<a
href="https://www.sprakradet.no/Vi-og-vart/Publikasjoner/Spraaknytt/spraknytt-2014/Spraknytt-12014/Ord-som-finst-og-ikkje-finst/">
Her kan du lese meir om ordutvalet
</a>
mellom anna i <em>Bokmålsordboka </em>og <em>Nynorskordboka</em>.
</p>
<p>
Dersom du ikkje finn ordet du leitar etter, kan du sjekke dei større og
dokumenterande ordbøkene <a href="https://alfa.norsk-ordbok.no"><em>Norsk Ordbok</em></a> (for dialektord
og nynorsk) og <a href="https://naob.no/">NAOB</a> (for bokmål).
</p>
</details>
<details>
<summary>
<h2>Kvalitetssikra innhald</h2>
</summary>
<p>
<em>Bokmålsordboka</em>
og <em>Nynorskordboka</em> er to sjølvstendige, einspråklege ordbøker.
Språkrådet og Universitetet i Bergen (UiB) eig ordbøkene i fellesskap.
</p>
<p>
<a href="https://www.sprakradet.no/">Språkrådet</a>
avgjer korleis ord skal skrivast og bøyast på bokmål og nynorsk. <em>Bokmålsordboka</em> og <em>Nynorskordboka
</em>blir løpande oppdaterte
i tråd med rettskrivingsvedtak i Språkrådet, så det er her du finn fasiten
på kva som er gjeldande og fullstendig rettskriving i bokmål og nynorsk.
</p>
<p>
Sidan 2016 har det redaksjonelle arbeidet med standardordbøkene blitt
utført ved Universitetet i Bergen, der fleire avdelingar er involverte.
<a href="https://www.uib.no/ub/spesialsamlingene/160666/om-spr%C3%A5ksamlingane">
Språksamlingane
</a>
forvaltar ordbøkene og kjeldegrunnlaget dei byggjer på, ordbokredaktørane
er tilsette ved
<a href="https://www.uib.no/lle">
Institutt for lingvistiske, litterære og estetiske studium
</a>
, og det datatekniske arbeidet går føre seg ved <a href="https://www.uib.no/it">IT-avdelinga</a>. Innhaldet i
ordbøkene er
kvalitetssikra av Språkrådet.
</p>
</details>
<details>
<summary>
<h2>Sitere ordbøkene</h2>
</summary>
<p>
Innhaldet i <em>Bokmålsordboka</em> og <em>Nynorskordboka</em> er verna av
opphavsrett, jf.
<a href="https://lovdata.no/dokument/NL/lov/2018-06-15-40">
lov om opphavsrett til åndsverk
</a>
mv.
</p>
<p>
Ønskjer du å sitere ein artikkel i <em>Bokmålsordboka</em> eller <em>Nynorskordboka</em>, rår vi deg til å gje
opp når artikkelen vart henta
(lesen), t.d. slik:
</p>
<p>
«Korleis». I: <em>Nynorskordboka</em>. Språkrådet og Universitetet i
Bergen. &lt;<a href="http://ordbokene.no/">http://ordbøkene.no</a>
&gt; (henta 25.1.2022).
</p>
<p>
Begge eigarane av ordboka, Språkrådet og Universitetet i Bergen, bør
nemnast i referansen.
</p>
</details>
<details>
<summary><h2>Ordbøkene på smarttelefon</h2></summary><div>
<p>Nettsida ordbøkene.no har responsivt design, som gjer at innhaldet tilpassar seg både store og små skjermar. Ynskjer du å ha lenkja til Bokmålsordboka og Nynorskordboka på mobilskjermen din, søkjer du opp ordbøkene.no i nettlesaren og legg henne ut som ikon på skjermen. Ikonet ser ut som ein app, og du kan trykkje deg rett inn på nettsida, utan å gå vegen om nettlesaren.</p>
<h3>For iPhone/iOs</h3>
<p><ul class="bullet"><li>Opne nettlesaren og skriv inn enten ordbokene.no eller ordbøkene.no.</li>
<li>Når du er inne på forsida, vel du ikonet nedst på sida for å dele: <v-icon>ios_share</v-icon>.</li>
<li>Det kjem opp delealternativ i to rader. I den nedste rada vel du «Legg til på Heim-skjerm» med ikonet <v-icon>add_box</v-icon> Det kan hende du må drage rada frå høgre for å kome til ikonet.</li>
</ul></p><p>Ikonet <img class="ordbokene-icon" src="favicon.ico" aria-hidden="true"/> ligg no på heim-skjermen din, og du kjem direkte inn på ordboksida ved å klikke på det.</p>
<h3>For Android</h3>
<p><ul class="bullet"><li>Opne nettlesaren og skriv inn enten ordbokene.no eller ordbøkene.no.</li>
<li>Når du er inne på forsida, vel du ikonet med dei tre loddrette prikkane i øvre høgre hjørnet: <v-icon>more_vert</v-icon>.</li>
<li>Det kjem då fram ei liste med valalternativ, og du vel «Legg til på startsida», eit stykke nede på lista.</li>
<li>Det dukkar opp eit vindauge som føreslår at du legg til Ordbøkene på startsida. Klikk på valet «Legg til».</li></ul></p>
<p>Ikonet <img class="ordbokene-icon" src="favicon.ico"/> ligg no på startsida di, og du kjem direkte inn på ordboksida ved å klikke på det.
NB! I somme modellar frå Samsung ligg valet «Legg til side i» i ein meny nedst på sida. Derfrå vel du startsida.</p>
</div></details>
<details>
<summary>
<h2>Opne data</h2>
</summary>
<p>
<em>Innhaldet i Bokmålsordboka</em>
og <em>Nynorskordboka</em> ligg ope tilgjengeleg for nedlasting. Det kan
brukast til kva formål som helst, inkludert kommersielle, i samsvar med
gjevne vilkår.
<a
href="https://www.uib.no/ub/fagressurser/spesialsamlingene/142334/lisens-bokm%C3%A5lsordboka-og-nynorskordboka">
Les meir om den opne lisensen her.
</a>
</p>
<p>
Informasjonen i bøyingstabellane i <em>Bokmålsordboka</em> og <em>Nynorskordboka</em> er henta frå Norsk
ordbank. Ordbanken er ein
leksikalsk database for bokmål og nynorsk med informasjon om ordklasse og
normert bøying for langt fleire ord enn dei som er oppslagsord i
standardordbøkene. Norsk ordbank ligg
<a href="https://www.nb.no/sprakbanken/ressurskatalog/?_search=ordbank">
tilgjengeleg for nedlasting hos Språkbanken
</a>
ved Nasjonalbiblioteket under lisensen CC-BY.
</p>
</details>
<details>
<summary>
<h2>Historikk</h2>
</summary>
<p>
<em>Bokmålsordboka</em>
og <em>Nynorskordboka</em> vart først gjevne ut i 1986, produsert gjennom
eit samarbeidsprosjekt mellom Universitetet i Oslo og Norsk språkråd, og
seinare har dei kome i fleire utgåver. I trykt form er <em>Bokmålsordboka</em> og <em>Nynorskordboka</em> store
eittbinds
ordbøker. Dei viser skrivemåtar og bøying som alltid er i tråd med dei
gjeldande normene. Vidare gjev ordbøkene opp tydingar, bruksdøme og korte
etymologiar.
</p>
<p>
<a href="https://www.uib.no/sites/w3.uib.no/files/attachments/om_ordbokene.pdf">
Her finn du fororda til dei trykte utgåvene
</a>
og meir informasjon om tidlegare ordbokredaktørar og arbeidet med ordbøkene
ved Universitetet i Oslo.
</p>
<p>
Universitetet i Bergen og Språkrådet kjem ikkje til å publisere fleire
trykte utgåver av standardordbøkene.
</p>
</details>
<details>
<summary>
<h2>Revisjonsprosjektet</h2>
</summary>
<div>
<p>
Det går for tida føre seg eit omfattande arbeid med å oppdatere innhaldet i <em>Bokmålsordboka</em> og
<em>Nynorskordboka</em>. I perioden 2018–2023
går ei gruppe redaktørar gjennom begge ordbøkene frå a til å. Dei
viktigaste oppgåvene er å få inn nye ord og tydingar, passe på at innhaldet
er i tråd med språkbruken i dag, og gjere utvalet av ord likare i dei to
ordbøkene. Meir informasjon finner du på
<a href="https://www.uib.no/lle/revisjonsprosjektet">
nettsida til Revisjonsprosjektet
</a>
.
</p>
<p>
Noverande redaksjon for <em>Bokmålsordboka </em>og <em>Nynorskordboka</em>:
<ul>
<li>
Anne Engø, redaktør 2018–2023
</li>
<li>
Marita Kristiansen, redaktør 2020–2021
</li>
<li>
Gunn Inger Lyse, redaktør 2018–2023
</li>
<li>
Mikkel Ekeland Paulsen, stipendiat 2019–2023
</li>
<li>
Margunn Rauset, prosjektleiar 2018–2023
</li>
<li>
Bente Selback, redaktør 2018–2023
</li>
<li>
Kari-Anne Selvik, redaktør 2018–2023
</li>
<li>
Klara Sjo, redaktør 2020–2022
</li>
<li>
Marie Lund Stokka, redaktør 2020
</li>
<li>
Terje Svardal, redaktør ved Språksamlingane
</li>
</ul>
</p>
<p>
Kvalitetskontrollørar i Språkrådet:
<ul>
<li>
Sturla Berg-Olsen, seniorrådgjevar
</li>
<li>
Knut E. Karlsen, seniorrådgjevar
</li>
<li>
Ålov Runde, seniorrådgjevar
</li>
<li>
Dagfinn Rødningen, seniorrådgjevar
</li>
</ul>
</p>
<p>
Denne sida har blitt utforma av utviklarar på IT-avdelinga ved Universitetet i Bergen og Språksamlingane:
<ul>
<li>Henrik Askjer, overingeniør, Språksamlingane</li>
<li>Eirik T. Gullaksen, overingeniør, IT-avdelinga</li>
<li>Paul Meurer, senioringeniør, Språksamlingane</lI>
<li>Nils Øverås, overingeniør, IT-avdelinga</li>
<li>Ole Voldsæter, overingeniør, IT-avdelinga 2019–2021</li></ul>
</p>
<p><a href="https://www.netlife.com/">Netlife</a> har gjennomført brukerundersøkingar og utarbeidd designskisser til ordbøkene.no.</p>
</div>
</details>
<details>
<summary>
<h2>Grammatiske kodar i ordbøkene</h2>
</summary>
<p>Kodane nedanfor viser dei regelrette bøyingane for substantiv, adjektiv og verb. Ord med ufullstendige eller uregelrette bøyingar i desse ordklassane har bøyingskodar utan tal. Dei er merkte f. (femininum, hokjønn), m. (maskulinum, hankjønn), n. (nøytrum, inkjekjønn), subst. (substantiv), adj. (adjektiv) eller v. (verb).</p>
<h3>Substantiv (Nynorskordboka)</h3>
<p>
<table>
<tr>
<th>Kode</th>
<th>Ubunden form eintal</th>
<th>Bunden form eintal</th>
<th>Ubunden form fleirtal</th>
<th>Bunden form fleirtal</th>
</tr>
<tr>
<td>f1</td>
<td> bygd</td>
<td> bygda</td>
<td> bygder</td>
<td> bygdene</td>
</tr>
<tr>
<td>f2</td>
<td> vise</td>
<td> visa</td>
<td> viser</td>
<td> visene</td>
</tr>
<tr>
<td>f3</td>
<td> dronning</td>
<td> dronninga</td>
<td> dronningar</td>
<td> dronningane</td>
</tr>
<tr>
<td rowspan="3">m1</td>
<td> båt</td>
<td> båten</td>
<td> båtar</td>
<td> båtane</td>
</tr>
<tr>
<td>hage</td>
<td>hagen</td>
<td>hagar</td>
<td>hagane</td>
</tr>
<tr>
<td> lærar</td>
<td> læraren</td>
<td> lærarar</td>
<td> lærarane</td>
</tr>
<tr>
<td rowspan="2">
n1</td>
<td> hus</td>
<td> huset</td>
<td> hus</td>
<td> husa</td>
</tr>
<tr>
<td> rike</td>
<td> riket</td>
<td> rike</td>
<td> rika</td>
</tr>
</table>
</p>
<h3>Adjektiv (Nynorskordboka)</h3>
<p>
<table>
<tr>
<th>Kode</th>
<th>Hankjønn og hokjønn</th>
<th>Inkjekjønn</th>
<th>Bunden form</th>
<th>Fleirtal</th>
</tr>
<tr>
<td>
a1</td>
<td> sterk</td>
<td> sterkt</td>
<td> sterke</td>
<td> sterke</td>
</tr>
<tr>
<td>
a2</td>
<td> norsk</td>
<td> norsk</td>
<td> norske</td>
<td> norske</td>
</tr>
<tr>
<td>
a3</td>
<td> grepa</td>
<td> grepa</td>
<td> grepa</td>
<td> grepa</td>
</tr>
<tr>
<td>
a4</td>
<td> open</td>
<td> ope el. opent</td>
<td> opne</td>
<td> opne</td>
</tr>
<tr>
<td>
a5</td>
<td> vaksen</td>
<td> vakse</td>
<td> vaksne</td>
<td> vaksne</td>
</tr>
</table>
</p>
<h3>Verb (Nynorskordboka)</h3>
<p>
<table>
<tr>
<th>Kode</th>
<th>Infinitiv</th>
<th>Presens (Notid)</th>
<th>Preteritum (Fortid)</th>
<th>Perfektum partisipp (Supinum)</th>
</tr>
<tr>
<td rowspan="2">v1</td>
<td> kasta el. kaste</td>
<td> kastar</td>
<td> kasta</td>
<td> kasta</td>
</tr>
<tr>
<td> ropa el. rope</td>
<td> ropar</td>
<td> ropa</td>
<td> ropa</td>
</tr>
<tr>
<td rowspan="2">v2</td>
<td> kvila el. kvile</td>
<td> kviler</td>
<td> kvilte</td>
<td> kvilt</td>
</tr>
<tr>
<td>ropa el. rope</td>
<td> roper</td>
<td> ropte</td>
<td> ropt</td>
</tr>
<tr>
<td>v3</td>
<td> ropa el. rope</td>
<td> ropar</td>
<td> ropte</td>
<td> ropt</td>
</tr>
</table>
</p>
<h3>Substantiv (Bokmålsordboka)</h3>
<p>
<table>
<tbody><tr>
<th>Kode</th>
<th>Ubestemt form entall</th>
<th>Bestemt form entall</th>
<th>Ubestemt form flertall</th>
<th>Bestemt form flertall</th>
</tr>
<tr>
<td rowspan="2">f1</td>
<td>bru</td>
<td>brua</td>
<td>bruer</td>
<td>bruene</td>
</tr>
<tr>
<td>pumpe</td>
<td>pumpa</td>
<td>pumper</td>
<td>pumpene</td>
</tr>
<tr>
<td rowspan="3">m1</td>
<td>stol</td>
<td>stolen</td>
<td>stoler</td>
<td>stolene</td>
</tr>
<tr>
<td>bakke</td>
<td>bakken</td>
<td>bakker</td>
<td>bakkene</td>
</tr>
<tr>
<td>pumpe</td>
<td>pumpen</td>
<td>pumper</td>
<td>pumpene</td>
</tr>
<tr>
<td rowspan="2">m2</td>
<td>lærer</td>
<td>læreren</td>
<td>lærere</td>
<td>lærerne</td>
</tr>
<tr>
<td>dommer</td>
<td>dommeren</td>
<td>dommere</td>
<td>dommerne</td>
</tr>
<tr>
<td rowspan="2">m3</td>
<td>bever</td>
<td>beveren</td>
<td>bevere, bevrer el. bevre</td>
<td>beverne el. bevrene</td>
</tr>
<tr>
<td>sommer</td>
<td>sommeren</td>
<td>sommere, somrer el. somre</td>
<td>sommerne el. somrene</td>
</tr>
<tr>
<td>n1</td>
<td>slott</td>
<td>slottet</td>
<td>slott</td>
<td>slotta el. slottene</td>
</tr>
<tr>
<td rowspan="2">n2</td>
<td>salt</td>
<td>saltet</td>
<td>salter</td>
<td>salta el. saltene</td>
</tr>
<tr>
<td>eple</td>
<td>eplet</td>
<td>epler</td>
<td>epla el. eplene</td>
</tr>
<tr>
<td rowspan="2">n3</td>
<td>kontor</td>
<td>kontoret</td>
<td>kontor el. kontorer</td>
<td>kontora el. kontorene</td>
</tr>
<tr>
<td>høve</td>
<td>høvet</td>
<td>høve el. høver</td>
<td>høva el. høvene</td>
</tr>
</tbody></table>
</p>
<h3>Adjektiv (Bokmålsordboka)</h3>
<p>
<table>
<tbody><tr>
<th>Kode</th>
<th>Hankjønn og hunkjønn</th>
<th>Intetkjønn</th>
<th>Bestemt form</th>
<th>Flertall</th>
</tr>
<tr>
<td>a1</td>
<td>god</td>
<td>godt</td>
<td>gode</td>
<td>gode</td>
</tr>
<tr>
<td>a2</td>
<td>norsk</td>
<td>norsk</td>
<td>norske</td>
<td>norske</td>
</tr>
<tr>
<td rowspan="2">a3</td>
<td>ekte</td>
<td>ekte</td>
<td>ekte</td>
<td>ekte</td>
</tr>
<tr>
<td>oppskjørta</td>
<td>oppskjørta</td>
<td>oppskjørta</td>
<td>oppskjørta</td>
</tr>
<tr>
<td>
a4</td>
<td>oppskjørtet</td>
<td>oppskjørtet</td>
<td>oppskjørtede el. oppskjørtete</td>
<td>oppskjørtede el. oppskjørtete</td>
</tr>
<tr>
<td rowspan="2">
a5</td>
<td>makaber</td>
<td>makabert</td>
<td>makabre</td>
<td>makabre</td>
</tr>
<tr>
<td>lunken</td>
<td>lunkent</td>
<td>lunkne</td>
<td>lunkne</td>
</tr>
</tbody></table>
</p>
<h3>Verb (Bokmålsordboka)</h3>
<p>
<table>
<tbody><tr>
<th>Kode</th>
<th>Infinitiv</th>
<th>Presens (Nåtid)</th>
<th>Preteritum (Fortid)</th>
<th>Perfektum partisipp (Supinum)</th>
</tr>
<tr>
<td rowspan="2">v1</td>
<td>kaste</td>
<td>kaster</td>
<td>kasta el. kastet</td>
<td>kasta el. kastet</td>
</tr>
<tr>
<td>bie</td>
<td>bier</td>
<td>bia el. biet</td>
<td>bia el. biet</td>
</tr>
<tr>
<td rowspan="2">v2</td>
<td>lyse</td>
<td>lyser</td>
<td>lyste</td>
<td>lyst</td>
</tr>
<tr>
<td>lesse</td>
<td>lesser</td>
<td>lesste</td>
<td>lesst</td>
</tr>
<tr>
<td>v3</td>
<td>leve</td>
<td>lever</td>
<td>levde</td>
<td>levd</td>
</tr>
<tr>
<td rowspan="2">v4</td>
<td></td>
<td>når</td>
<td>nådde</td>
<td>nådd</td>
</tr>
<tr>
<td>bie</td>
<td>bier</td>
<td>bidde</td>
<td>bidd</td>
</tr>
</tbody></table>
</p>
</details>
<details>
<summary>
<h2>Nyttige språklenkjer</h2>
</summary>
<p>
Har du spørsmål om klar, god og korrekt språkbruk, kan du ta kontakt med <a
href="mailto:sporsmal@sprakradet.no">svartenesta</a> til Språkrådet.
Språkrådet har mange språkressursar samla under menyen Språkhjelp: Gå til
<a href="https://www.sprakradet.no/sprakhjelp/Skriveregler/">
skriveregler
</a>
,
<a href="https://www.sprakradet.no/sprakhjelp/Praktisk-grammatikk/">
praktisk grammatikk
</a>
eller <a href="https://www.sprakradet.no/sprakhjelp/Skriverad/">skriveråd</a>.
</p>
<p>
Språksamlingane ved Universitetsbiblioteket i Bergen har ei rekkje
språkressursar, mellom andre:
</p>
<p>
<ul class="bullet">
<li><a href="https://ord.uib.no/">ord.uib.no:</a> ordlister og API-beskriving for Ordbøkene (<a href="https://ordbokene.no/api/swagger-ui.html">interaktiv dokumentasjon</a>).</li>
<li>
<a href="http://inger.uib.no/perl/search/search.cgi?appid=72&amp;tabid=1106">
Norsk ordbank, bokmål
</a>
: søk i fullformslister for bokmål
</li>
<li>
<a href="http://inger.uib.no/perl/search/search.cgi?appid=73&amp;tabid=1116">
Norsk ordbank, nynorsk
</a>
: søk i fullformslister for nynorsk
</li>
<li>
<a href="http://inger.uib.no/perl/search/search.cgi?appid=7&amp;tabid=571">
Metaordboka
</a>
: felles database over alle dokumenterte ord sortert på normert nynorsk
oppslagsord
</li>
<li>
<a href="http://inger.uib.no/perl/search/search.cgi?appid=118&amp;tabid=1777">
Ordbokhotellet
</a>
: elektronisk indeks over ordformer frå ei rekkje lokale ordsamlingar
sortert under normert oppslagsform
</li>
<li>
<a href="http://inger.uib.no/perl/search/search.cgi">
Alle digitale språkressursar under Språksamlingane
</a>
</li>
</ul>
</p>
<h3>
Andre kvalitetssikra og fritt tilgjengelege ordbøker:
</h3>
<p><ul class="bullet">
<li>
<a href="https://alfa.norsk-ordbok.no">Norsk Ordbok</a>
: Ordboka over det norske folkemålet og det nynorske skriftmålet
</li>
<li>
<a href="http://www.naob.no/">NAOB</a>
: Det Norske Akademis Ordbok: bokmål og riksmål frå tidleg 1800-tall fram
til i dag
</li>
<li>
<a href="https://lexin.oslomet.no/#/">LEXIN</a>
: ordbøker for minoritetsspråklege elever i grunnskulen, vidaregåande og
vaksenopplæring
</li>
<li>
<a href="https://islex.arnastofnun.is/no/">Islex</a>
: ordbok frå islandsk til norsk (bokmål og nynorsk), svensk, dansk, færøysk
og finsk
</li>
<li>
<a href="http://www.ordnet.dk/">ordnet.dk</a>
: fleire danske ordbøker og korpus
</li>
<li>
<a href="http://www.svenska.se/">svenska.se</a>
: fleire svenske ordbøker
</li>
</ul></p>
</details>
<details>
<summary><h2>Bruk av ordbøkene.no i skulen</h2></summary>
<p>Blant dei norskspråklege ordbøkene og ordlistene er det berre dei som er godkjende av Språkrådet, som kan nyttast i undervisning og på prøver og eksamen. <em>Bokmålsordboka</em> og <em>Nynorskordboka</em> er blant desse, og dei andre finn du i <a href ="https://www.sprakradet.no/sprakhjelp/Skriverad/Ordlister/Ordlister-til-skulebruk/">oversikta til Språkrådet over godkjende ressursar</a>.</p>
<p>Når skulane stengjer ein del nettsider på prøver og eksamen, må eit utval andre sider vere opne for at ordbøkene.no skal fungere. Her er domena som ordboksida brukar:
<ul class="bullet">
<li><a href="https://ordbokene.no/">https://ordbokene.no/</a></li>
<li><a href="https://oda.uib.no/">https://oda.uib.no/</a></li>
<li><a href="https://odd.uib.no/">https://odd.uib.no/</a></li>
<li><a href="https://plausible.io/">https://plausible.io/</a></li>
</ul></p>
<p>Nynorsksenteret har skrive to saker om bruk av ordbøkene.no i skulen:
<ul class="bullet"><li><a href="https://nynorsksenteret.no/vidaregaande/grammatikk/gode-tips-til-bruk-av-nettordboka">Gode tips til bruk av nettordboka</a></li>
<li><a href="https://nynorsksenteret.no/blogg/ta-i-bruk-dei-nye-ordbokene">Ta i bruk dei nye ordbøkene</a></li></ul></p><p>
Nynorsksenteret har dessutan eit opplegg for ungdomsskulen om <a href="https://nynorsksenteret.no/ungdomsskule/skriving/kreativ-skriving/hiphop-ordboka-som-kreativt-verktoy">hiphop og bruk av ordbøkene som kreative verktøy</a></p>
</details>
<details>
<summary><h2>Personvern</h2></summary>
<p>Ordbøkene brukar ikkje informasjonskapslar (cookiar), men lagrar brukarinnstillingane lokalt i nettlesaren (local storage), utan at informasjonen blir sendt vidare til serveren vår på UiB. Søkjeord blir logga på serveren, men vi brukar dette berre til å lage søkjestatistikk. Vi brukar ein Nginx-webserver der loggane blir overskrivne etter ei stund, slik at IP-adressene ikkje blir lagra permanent nokon stad. Vi loggar òg bruken av enkelte funksjonar på nettsida med plausible.io, som ikkje lagrar IP-adresser eller annan informasjon som kan knyte bruksstatistikken til enkeltbrukarar.</p>
</details>
</div>
<div class="article" v-if="$store.state.currentLocale == 'nob'">
<h1>Om ordbøkene</h1>
<p>Dette er nettsiden til standardordbøkene <em>Bokmålsordboka</em> og <em>Nynorskordboka.</em> Siden er fortsatt under utvikling, så enkelte funksjoner er ikke på plass ennå. Arbeidet med å revidere innholdet i ordbøkene pågår, og redaksjonen legger fortløpende ut ordartikler som er revidert og kvalitetssjekket. </p>
<p>I forbindelse med oppgraderingen har vi gjort en opprydding både i grensesnittet og i dataene våre. Derfor kan det være feil og mangler i den nye løsningen vi ikke har oppdaget ennå, eller ikke har hatt tid til å få på plass. Dersom du oppdager noe som er feil eller mangelfullt, vil vi gjerne ha tilbakemelding om det! Kontakt oss gjerne på e-post:</p>
<p><ul class="bullet">
<li>{{$t('contact.content[2]')}}<a href="mailto:ordbok@uib.no">ordbok@uib.no</a></li>
<li>{{$t('contact.content[3]')}}<a href="mailto:ordbok-teknisk@uib.no">ordbok-teknisk@uib.no</a></li>
</ul></p>
<details>
<summary><h2>Hva betyr det om du ikke finner et ord i ordboka?</h2></summary><div>
<p><em>Bokmålsordboka</em> og <em>Nynorskordboka</em> er mellomstore nettordbøker. <em>Bokmålsordboka</em> har hatt rundt 65&nbsp;000 oppslagsord og <em>Nynorskordboka</em> rundt 90&nbsp;000, men etter <a href="http://www.uib.no/lle/revisjonsprosjektet">den revisjonen som pågår</a>
regner vi med at begge skal inneholde rundt 100 000 oppslagsord. Ordbøkene skal gjøre rede for det sentrale ordforrådet, og det er i utgangspunktet de vanligste ordene i skriftspråkene bokmål og nynorsk de siste 50 årene som er tatt med. Faguttrykk er bare tatt med i den grad de også brukes utenfor fagfeltet de har oppstått i.</p>
<p>Den vanligste måten vi lager nye norske ord på, er å sette sammen gamle ord på nye måter, og det er talløse kombinasjonsmuligheter. Derfor er det mange sammensetninger som ikke har egne artikler i <em>Bokmålsordboka</em> og <em>Nynorskordboka</em>. Selv om du ikke finner <em>sykkelsete</em> som oppslagsord her, betyr det ikke at ordet ikke finnes eller ikke er tillatt. Sammensatte ord er særlig tatt med ut fra tre hensyn:</p>
<ul class="bullet">
<li>når de ikke umiddelbart er forståelige ut fra kjennskap til hvert enkelt ledd</li>
<li>for at ordbokbrukeren på grunnlag av de sammensetningene som er tatt med, kan slutte seg til hva andre sammensetninger med samme forledd betyr</li>
<li>for å vise hvilken bindebokstav sammensetningen skal ha (<em>skogbruk</em>, men <em>skog<u>s</u>arbeid</em>; <em>sakefall</em>, men <em>sak<u>es</u>løs</em>; <em>sakfører</em>, men <em>sak<u>s</u>behandler</em>; <em>ost<u>e</u>klokke</em>, men <em>dørklokke</em>)</li>
</ul>
<p>Tilsvarende er bare et avgrenset utvalg av avledninger (for eksempel verbalsubstantiv på <em>-ing</em>) tatt med i standardordbøkene. På norsk kan vi danne ing-former av de aller fleste verb, så finner du oppslagsordene <em>organisere</em> og <em>sitere</em> i <em>Bokmålsordboka</em> og <em>Nynorskordboka</em>, kan du selv lage avledningene organisering og sitering. Merk likevel at det finnes potensielle ing-former som sjelden blir brukt, for eksempel komming og væring.</p>
<p><em>Bokmålsordboka</em> og <em>Nynorskordboka</em> er ikke å betrakte som lister over hvilke ord som er tillatt å bruke på norsk. Det finnes mange ord, både gamle og nye, som ikke er med i ordbøkene, men som du gjerne kan bruke likevel. Det er heller ikke slik at nye ord må godkjennes før de kan tas i bruk, det er språkbrukerne som i fellesskap avgjør hvilke ord som er gangbare i norsk. Normalt kommer ikke nye ord inn i ordbøkene før de har vært i bruk en stund og er etablert i språket. Ordbokredaksjonen avgjør hvilke ord som skal være med basert på undersøkelser av store tekstsamlinger, og Språkrådet bestemmer hvordan ordene skal staves og bøyes.</p>
<p><a href="https://www.sprakradet.no/Vi-og-vart/Publikasjoner/Spraaknytt/spraknytt-2014/Spraknytt-12014/Ord-som-finst-og-ikkje-finst/">Her kan du lese mer om ordutvalget</a> bl.a. i <em>Bokmålsordboka</em> og <em>Nynorskordboka</em>.</p>
<p>Dersom du ikke finner ordet du leter etter, kan du sjekke de større og dokumenterende ordbøkene <a href="https://alfa.norsk-ordbok.no">Norsk Ordbok</a> (for dialektord og nynorsk) og <a href="https://naob.no/">NAOB</a> (for bokmål).</p>
</div></details>
<details>
<summary><h2>Kvalitetssikret innhold</h2></summary><div>
<p><em>Bokmålsordboka</em> og <em>Nynorskordboka</em> er to selvstendige, enspråklige ordbøker for henholdsvis bokmål og nynorsk. Ordbøkene eies av Språkrådet og Universitetet i Bergen i fellesskap.</p>
<p><a href="https://www.sprakradet.no/">Språkrådet</a> avgjør hvordan ord skal skrives og bøyes på bokmål og nynorsk. <em>Bokmålsordboka</em> og <em>Nynorskordboka</em> blir løpende oppdatert i tråd med rettskrivingsvedtak i Språkrådet, så det er her du finner fasiten på hva som er gjeldende og fullstendig rettskriving i bokmål og nynorsk. </p>
<p>Siden 2016 har det redaksjonelle arbeidet med standardordbøkene blitt utført ved Universitetet i Bergen, der flere avdelinger er involvert. <a href="https://www.uib.no/ub/spesialsamlingene/160666/om-spr%C3%A5ksamlingane">Språksamlingane</a> forvalter ordbøkene og kildegrunnlaget de bygger på, ordbokredaktørene er ansatt ved <a href="https://www.uib.no/lle">Institutt for lingvistiske, litterære og estetiske studium</a>, og det datatekniske arbeidet foregår ved IT-avdelingen. Innholdet i ordbøkene er kvalitetssikret av Språkrådet.</p>
</div></details>
<details>
<summary><h2>Sitere ordbøkene</h2></summary><div>
<p>Innholdet i Bokmålsordboka og Nynorskordboka er beskyttet av opphavsrett, jf. lov om opphavsrett til åndsverk mv.
Ønsker du å sitere en artikkel i <em>Bokmålsordboka</em> eller <em>Nynorskordboka</em>, anbefaler vi å oppgi når artikkelen ble hentet (lest), f.eks. slik:</p>
<blockquote><p>«Hvordan». I: <em>Bokmålsordboka</em>. Språkrådet og Universitetet i Bergen. <br>‹http://ordbøkene.no› (hentet 25.1.2022).</p></blockquote>
<p>Begge eierne av ordboka, Språkrådet og Universitetet i Bergen, bør nevnes i referansen.</p>
</div></details>
<details>
<summary><h2>Ordbøkene på smarttelefon</h2></summary><div>
<p> Nettsiden ordbøkene.no har responsivt design, som gjør at innholdet tilpasser seg skjermer av alle størrelser. Ønsker du å ha lenken til <em>Bokmålsordboka</em> og <em>Nynorskordboka</em> på mobilskjermen din, søker du opp ordbøkene.no i nettleseren og legger den til som ikon på skjermen. Ikonet ser ut som en app, og du kan trykke deg rett inn på nettsiden, uten å gå veien om nettleseren.</p>
<h3>For iPhone/iOs:</h3>
<p><ul><li>Åpne nettleseren og skriv inn enten ordbokene.no eller ordbøkene.no.</li>
<li>Når du er inne på forsiden, velger du ikonet nederst på siden for å dele: <v-icon>ios_share</v-icon>.</li>
<li>Det kommer opp delealternativer i to rader. I den nederste raden velger du «Legg til på Hjem-skjerm» med ikonet <v-icon>add_box</v-icon> . Det kan hende du må dra raden fra høyre for å komme til ikonet.</li></ul></p>
<p>Ikonet <img class="ordbokene-icon" src="favicon.ico" aria-hidden="true"/> ligger nå på hjem-skjermen din, og du kommer direkte inn på ordboksiden ved å klikke på det.</p>
<h3>For Android:</h3>
<p><ul class="bullet"><li>Åpne nettleseren og skriv inn enten ordbokene.no eller ordbøkene.no.</li>
<li>Når du er inne på forsiden, velger du ikonet med de tre loddrette prikkene i øvre høyre hjørnet: <v-icon>more_vert</v-icon>.</li>
<li>Det kommer da opp en liste med valgalternativer, og du velger «Legg til på startsiden», et stykke nede på listen.</li>
<li>Det dukker opp et vindu som foreslår at du legger til ordbøkene.no på startsiden. Klikk på valget «Legg til».</li></ul></p>
<p>Ikonet <img class="ordbokene-icon" src="favicon.ico" aria-hidden="true"/> ligger nå på startsiden din, og du kommer direkte inn på ordboksiden ved å klikke på det.
NB! I noen modeller fra Samsung ligger valget «Legg til side i» i en meny nederst på siden. Derfra velger du startsiden.</p>
</div></details>
<details>
<summary><h2>Åpne data</h2></summary><div>
<p>Innholdet i <em>Bokmålsordboka</em> og <em>Nynorskordboka</em> ligger åpent tilgjengelig for nedlasting. De kan brukes til alle formål, inkludert kommersielle, i samsvar med gitte vilkår. <a href="https://www.uib.no/ub/fagressurser/spesialsamlingene/142334/lisens-bokm%C3%A5lsordboka-og-nynorskordboka">Les mer om den åpne lisensen her</a>.</p>
<p>Informasjonen i bøyingstabellene i <em>Bokmålsordboka</em> og <em>Nynorskordboka</em> er hentet fra Norsk ordbank. Ordbanken er en leksikalsk database for bokmål og nynorsk med informasjon om ordklasse og normert bøying for langt flere ord enn de som er oppslagsord i standardordbøkene. Norsk ordbank ligger <a href="https://www.nb.no/sprakbanken/ressurskatalog/?_search=ordbank">tilgjengelig for nedlasting hos Språkbanken</a> ved Nasjonalbiblioteket under lisensen CC-BY. </p>
</div></details>
<details>
<summary><h2>Historikk</h2></summary><div>
<p><em>Bokmålsordboka</em> og <em>Nynorskordboka</em> ble utgitt første gang i 1986, produsert gjennom et samarbeidsprosjekt mellom Universitetet i Oslo og Norsk Språkråd, og er siden kommet i flere utgaver. I trykt form er <em>Bokmålsordboka</em> og <em>Nynorskordboka</em> store ettbinds ordbøker. De viser skrivemåter og bøying som alltid er i tråd med de gjeldende normene. Videre oppgir ordbøkene betydninger, brukseksempler og korte etymologier.</p>
<p><a href="https://www.uib.no/sites/w3.uib.no/files/attachments/om_ordbokene.pdf">Her finner du forordene til de trykte utgavene</a> og mer informasjon om tidligere ordbokredaktører og arbeidet med ordbøkene ved Universitetet i Oslo.</p>
<p>Universitetet i Bergen og Språkrådet kommer ikke til publisere flere trykte utgaver av standardordbøkene.</p>
</div></details>
<details>
<summary><h2>Revisjonsprosjektet</h2></summary><div>
<p>Det pågår for tiden et omfattende arbeid med å oppdatere innholdet i <em>Bokmålsordboka</em> og <em>Nynorskordboka</em>. I perioden 2018–2023 går en gruppe redaktører gjennom begge ordbøkene fra a til å. De viktigste oppgavene er å få inn nye ord og betydninger, passe på at innholdet er i tråd med dagens språkbruk, og gjøre utvalget av ord likere i de to ordbøkene. Mer informasjon finner du på <a href="https://www.uib.no/lle/revisjonsprosjektet">nettsiden til Revisjonsprosjektet</a>.</p>
<p>Nåværende redaksjon for <em>Bokmålsordboka</em> og <em>Nynorskordboka</em>:
<ul>
<li>Anne Engø, redaktør 2018–2023</li>
<li>Marita Kristiansen, redaktør 2020–2021</li>
<li>Gunn Inger Lyse, redaktør 2018–2023</li>
<li>Mikkel Ekeland Paulsen, stipendiat 2019–2023</li>
<li>Margunn Rauset, prosjektleder 2018–2023</li>
<li>Bente Selback, redaktør 2018–2023</li>
<li>Kari-Anne Selvik, redaktør 2018–2023</li>
<li>Klara Sjo, redaktør 2020–2022</li>
<li>Marie Lund Stokka, redaktør 2020</li>
<li>Terje Svardal, redaktør ved Språksamlingene</li>
</ul>
</p>
Kvalitetskontrollører i Språkrådet:
<p><ul>
<li>Sturla Berg-Olsen, seniorrådgiver</li>
<li>Knut E. Karlsen, seniorrådgiver</li>
<li>Dagfinn Rødningen, seniorrådgiver</li>
<li>Ålov Runde, seniorrådgiver</li>
</ul>
</p>
Denne siden har blitt utformet av utviklere på IT-avdelingen ved Universitetet i Bergen og Språksamlingane:
<ul>
<li>Henrik Askjer, overingeniør, Språksamlingane</li>
<li>Eirik T. Gullaksen, overingeniør, IT-avdelingen</li>
<li>Paul Meurer, senioringeniør, Språksamlingane</li>
<li>Nils Øverås, overingeniør, IT-avdelingen</li>
<li>Ole Voldsæter, overingeniør, IT-avdelingen 2019–2021</li>
</ul> <p>
</p>
<p><a href="https://www.netlife.com/">Netlife</a> har gjennomført brukerundersøkelser og utarbeidet designskisser til ordbøkene.no.</p>
</div></details>
<details>
<summary><h2>Grammatiske koder i ordbøkene</h2>
</summary>
<p>Kodene nedenfor viser de regelrette bøyningene for substantiv, adjektiv og verb. Ord med med ufullstendige eller uregelrette bøyninger i disse ordklassene har koder uten tall. De er merket med f. (femininum, hunkjønn), m. (maskulinum, hankjønn), n. (nøytrum, intetkjønn), subst. (substantiv), adj. (adjektiv) eller v. (verb).</p>
<h3>Substantiv (Bokmålsordboka)</h3>
<p>
<table>
<tbody><tr>
<th>Kode</th>
<th>Ubestemt form entall</th>
<th>Bestemt form entall</th>
<th>Ubestemt form flertall</th>
<th>Bestemt form flertall</th>
</tr>
<tr>
<td rowspan="2">f1</td>
<td>bru</td>
<td>brua</td>
<td>bruer</td>
<td>bruene</td>
</tr>
<tr>
<td>pumpe</td>
<td>pumpa</td>
<td>pumper</td>
<td>pumpene</td>
</tr>
<tr>
<td rowspan="3">m1</td>
<td>stol</td>
<td>stolen</td>
<td>stoler</td>
<td>stolene</td>
</tr>
<tr>
<td>bakke</td>
<td>bakken</td>
<td>bakker</td>
<td>bakkene</td>
</tr>
<tr>
<td>pumpe</td>
<td>pumpen</td>
<td>pumper</td>
<td>pumpene</td>
</tr>
<tr>
<td rowspan="2">m2</td>
<td>lærer</td>
<td>læreren</td>
<td>lærere</td>
<td>lærerne</td>
</tr>
<tr>
<td>dommer</td>
<td>dommeren</td>
<td>dommere</td>
<td>dommerne</td>
</tr>
<tr>
<td rowspan="2">m3</td>
<td>bever</td>
<td>beveren</td>
<td>bevere, bevrer el. bevre</td>
<td>beverne el. bevrene</td>
</tr>
<tr>
<td>sommer</td>
<td>sommeren</td>
<td>sommere, somrer el. somre</td>
<td>sommerne el. somrene</td>
</tr>
<tr>
<td>n1</td>
<td>slott</td>
<td>slottet</td>
<td>slott</td>
<td>slotta el. slottene</td>
</tr>
<tr>
<td rowspan="2">n2</td>
<td>salt</td>
<td>saltet</td>
<td>salter</td>
<td>salta el. saltene</td>
</tr>
<tr>
<td>eple</td>
<td>eplet</td>
<td>epler</td>
<td>epla el. eplene</td>
</tr>
<tr>
<td rowspan="2">n3</td>
<td>kontor</td>
<td>kontoret</td>
<td>kontor el. kontorer</td>
<td>kontora el. kontorene</td>
</tr>
<tr>
<td>høve</td>
<td>høvet</td>
<td>høve el. høver</td>
<td>høva el. høvene</td>
</tr>
</tbody></table>
</p>
<h3>Adjektiv (Bokmålsordboka)</h3>
<p>
<table>
<tbody><tr>
<th>Kode</th>
<th>Hankjønn og hunkjønn</th>
<th>Intetkjønn</th>
<th>Bestemt form</th>
<th>Flertall</th>
</tr>
<tr>
<td>a1</td>
<td>god</td>
<td>godt</td>
<td>gode</td>
<td>gode</td>
</tr>
<tr>
<td>a2</td>
<td>norsk</td>
<td>norsk</td>
<td>norske</td>
<td>norske</td>
</tr>
<tr>
<td rowspan="2">a3</td>
<td>ekte</td>
<td>ekte</td>
<td>ekte</td>
<td>ekte</td>
</tr>
<tr>
<td>oppskjørta</td>
<td>oppskjørta</td>
<td>oppskjørta</td>
<td>oppskjørta</td>
</tr>
<tr>
<td>
a4</td>
<td>oppskjørtet</td>
<td>oppskjørtet</td>
<td>oppskjørtede el. oppskjørtete</td>
<td>oppskjørtede el. oppskjørtete</td>
</tr>
<tr>
<td rowspan="2">
a5</td>
<td>makaber</td>
<td>makabert</td>
<td>makabre</td>
<td>makabre</td>
</tr>
<tr>
<td>lunken</td>
<td>lunkent</td>
<td>lunkne</td>
<td>lunkne</td>
</tr>
</tbody></table>
</p>
<h3>Verb (Bokmålsordboka)</h3>
<p>
<table>
<tbody><tr>
<th>Kode</th>
<th>Infinitiv</th>
<th>Presens (Nåtid)</th>
<th>Preteritum (Fortid)</th>
<th>Perfektum partisipp (Supinum)</th>
</tr>
<tr>
<td rowspan="2">v1</td>
<td>kaste</td>
<td>kaster</td>
<td>kasta el. kastet</td>
<td>kasta el. kastet</td>
</tr>
<tr>
<td>bie</td>
<td>bier</td>
<td>bia el. biet</td>
<td>bia el. biet</td>
</tr>
<tr>
<td rowspan="2">v2</td>
<td>lyse</td>
<td>lyser</td>
<td>lyste</td>
<td>lyst</td>
</tr>
<tr>
<td>lesse</td>
<td>lesser</td>
<td>lesste</td>
<td>lesst</td>
</tr>
<tr>
<td>v3</td>
<td>leve</td>
<td>lever</td>
<td>levde</td>
<td>levd</td>
</tr>
<tr>
<td rowspan="2">v4</td>
<td></td>
<td>når</td>
<td>nådde</td>
<td>nådd</td>
</tr>
<tr>
<td>bie</td>
<td>bier</td>
<td>bidde</td>
<td>bidd</td>
</tr>
</tbody></table>
</p>
<h3>Substantiv (Nynorskordboka)</h3>
<p>
<table>
<tr>
<th>Kode</th>
<th>Ubunden form eintal</th>
<th>Bunden form eintal</th>
<th>Ubunden form fleirtal</th>
<th>Bunden form fleirtal</th>
</tr>
<tr>
<td>f1</td>
<td> bygd</td>
<td> bygda</td>
<td> bygder</td>
<td> bygdene</td>
</tr>
<tr>
<td>f2</td>
<td> vise</td>
<td> visa</td>
<td> viser</td>
<td> visene</td>
</tr>
<tr>
<td>f3</td>
<td> dronning</td>
<td> dronninga</td>
<td> dronningar</td>
<td> dronningane</td>
</tr>
<tr>
<td rowspan="3">m1</td>
<td> båt</td>
<td> båten</td>
<td> båtar</td>
<td> båtane</td>
</tr>
<tr>
<td>hage</td>
<td>hagen</td>
<td>hagar</td>
<td>hagane</td>
</tr>
<tr>
<td> lærar</td>
<td> læraren</td>
<td> lærarar</td>
<td> lærarane</td>
</tr>
<tr>
<td rowspan="2">
n1</td>
<td> hus</td>
<td> huset</td>
<td> hus</td>
<td> husa</td>
</tr>
<tr>
<td> rike</td>
<td> riket</td>
<td> rike</td>
<td> rika</td>
</tr>
</table>
</p>
<h3>Adjektiv (Nynorskordboka)</h3>
<p>
<table>
<tr>
<th>Kode</th>
<th>Hankjønn og hokjønn</th>
<th>Inkjekjønn</th>
<th>Bunden form</th>
<th>Fleirtal</th>
</tr>
<tr>
<td>
a1</td>
<td> sterk</td>
<td> sterkt</td>
<td> sterke</td>
<td> sterke</td>
</tr>
<tr>
<td>
a2</td>
<td> norsk</td>
<td> norsk</td>
<td> norske</td>
<td> norske</td>
</tr>
<tr>
<td>
a3</td>
<td> grepa</td>
<td> grepa</td>
<td> grepa</td>
<td> grepa</td>
</tr>
<tr>
<td>
a4</td>
<td> open</td>
<td> ope el. opent</td>
<td> opne</td>
<td> opne</td>
</tr>
<tr>
<td>
a5</td>
<td> vaksen</td>
<td> vakse</td>
<td> vaksne</td>
<td> vaksne</td>
</tr>
</table>
</p>
<h3>Verb (Nynorskordboka)</h3>
<p>
<table>
<tr>
<th>Kode</th>
<th>Infinitiv</th>
<th>Presens (Notid)</th>
<th>Preteritum (Fortid)</th>
<th>Perfektum partisipp (Supinum)</th>
</tr>
<tr>
<td rowspan="2">v1</td>
<td> kasta el. kaste</td>
<td> kastar</td>
<td> kasta</td>
<td> kasta</td>
</tr>
<tr>
<td> ropa el. rope</td>
<td> ropar</td>
<td> ropa</td>
<td> ropa</td>
</tr>
<tr>
<td rowspan="2">v2</td>
<td> kvila el. kvile</td>
<td> kviler</td>
<td> kvilte</td>
<td> kvilt</td>
</tr>
<tr>
<td>ropa el. rope</td>
<td> roper</td>
<td> ropte</td>
<td> ropt</td>
</tr>
<tr>
<td>v3</td>
<td> ropa el. rope</td>
<td> ropar</td>
<td> ropte</td>
<td> ropt</td>
</tr>
</table>
</p>
</details>
<details>
<summary><h2>Nyttige språklenker</h2></summary><div>
<p>Har du spørsmål om klar, god og korrekt språkbruk, kan du ta kontakt med <a href="mailto:sporsmal@sprakradet.no">Språkrådets svartjeneste</a>.</p>
<h3>Språkressurser på nettet</h3>
<p>Språksamlingene ved Universitetsbiblioteket i Bergen har en rekke språkressurser, blant annet:</p>
<ul class="bullet">
<li><a href="https://ord.uib.no/">ord.uib.no:</a> ordlister og API-beskrivelse for Ordbøkene (<a href="https://ordbokene.no/api/swagger-ui.html">interaktiv dokumentasjon</a>).</li>
<li><a href="http://inger.uib.no/perl/search/search.cgi?appid=72&tabid=1106">Norsk ordbank, bokmål:</a> søk i fullformslister for bokmål</li>
<li><a href="http://inger.uib.no/perl/search/search.cgi?appid=73&tabid=1116">Norsk ordbank, nynorsk:</a> søk i fullformslister for nynorsk</li>
<li><a href="http://inger.uib.no/perl/search/search.cgi?appid=7&tabid=571">Metaordboka:</a> felles database over alle dokumenterte ord sortert på normert nynorsk oppslagsord</li>
<li><a href="http://inger.uib.no/perl/search/search.cgi?appid=118&tabid=1777">Ordbokhotellet:</a> elektronisk indeks over ordformer fra en rekke lokale ordsamlinger sortert under normert oppslagsform</li>
<li><a href="http://inger.uib.no/perl/search/search.cgi">Alle digitale språkressurser under språksamlingene</a></li>
</ul>
<p><a href="http://www.sprakradet.no/">Språkrådet</a> har mange språkressurser samlet under menyen Språkhjelp, gå til <a href="http://www.sprakradet.no/sprakhjelp/Skriveregler/">skriveregler</a>, <a href="http://www.sprakradet.no/sprakhjelp/Praktisk-grammatikk/">praktisk grammatikk</a> eller <a href="http://www.sprakradet.no/sprakhjelp/Skriverad/">skriveråd</a>.</p>
<p>Norsk ordbank ligger også tilgjengelig for nedlasting hos <a href="https://www.nb.no/sprakbanken/ressurskatalog/?_search=ordbank">Språkbanken ved Nasjonalbiblioteket</a> under lisensen CC-BY. Ordbanken inneholder bl.a. fullformslister for bokmål og nynorsk med informasjon om ordklasse og normert bøying.</p>
<h3>Andre kvalitetssikrede og fritt tilgjengelige ordbøker</h3>
<p><ul class="bullet">
<li><a href="https://alfa.norsk-ordbok.no">Norsk Ordbok:</a> Ordboka over det norske folkemålet og det nynorske skriftmålet</li>
<li><a href="https://naob.no/">NAOB:</a> Det Norske Akademis Ordbok: bokmål og riksmål fra tidlig 1800-tall fram til i dag</li>
<li><a href="http://lexin.udir.no/">LEXIN:</a> ordbøker for minoritetsspråklige elever i grunnskolen, videregående og voksenopplæring</li>
<li><a href="https://islex.arnastofnun.is/no/">Islex:</a> ordbok fra islandsk til norsk (bokmål og nynorsk), svensk, dansk, færøysk og finsk</li>
<li><a href="http://ordnet.dk/">ordnet.dk:</a> flere danske ordbøker og korpus</li>
<li><a href="https://svenska.se/">svenska.se:</a> flere svenske ordbøker</li>
</ul></p>
</div></details>
<details>
<summary><h2>Bruk av ordbøkene.no i skolen</h2></summary>
<p>Blant norskspråklige ordbøker og ordlister er det bare de som er godkjent av Språkrådet, som kan brukes i undervisning og på prøver og eksamen. <em>Bokmålsordboka</em> og <em>Nynorskordboka</em> er blant disse, og de andre finner du på <a href ="https://www.sprakradet.no/sprakhjelp/Skriverad/Ordlister/Ordlister-til-skulebruk/"> Språkrådets oversikt over godkjente ressurser</a>.</p>
<p>Når skolene stenger en del nettsider på prøver og eksamen, må et utvalg andre sider være åpne for at ordbøkene.no skal fungere. Her er domenene som ordboksida bruker:
<ul class="bullet">
<li><a href="https://ordbokene.no/">https://ordbokene.no/</a></li>
<li><a href="https://oda.uib.no/">https://oda.uib.no/</a></li>
<li><a href="https://odd.uib.no/">https://odd.uib.no/</a></li>
<li><a href="https://plausible.io/">https://plausible.io/</a></li>
</ul></p>
<p>Nynorsksenteret har skrevet to saker om bruk av ordbøkene.no i skolen:
<ul class="bullet"><li><a href="https://nynorsksenteret.no/vidaregaande/grammatikk/gode-tips-til-bruk-av-nettordboka">Gode tips til bruk av nettordboka</a></li>
<li><a href="https://nynorsksenteret.no/blogg/ta-i-bruk-dei-nye-ordbokene">Ta i bruk dei nye ordbøkene</a></li></ul></p><p>
Nynorsksenteret har dessuten et opplegg for ungdomsskolen om <a href="https://nynorsksenteret.no/ungdomsskule/skriving/kreativ-skriving/hiphop-ordboka-som-kreativt-verktoy">hiphop og bruk av ordbøkene som kreative verktøy</a></p>
</details>
<details>
<summary><h2>Personvern</h2></summary>
<p>Ordbøkene bruker ikke informasjonskapsler (cookier), men lagrer brukerinnstillinger lokalt i nettleseren (local storage), uten å sende denne informasjonen til vår server på UiB. Søkeord logges på serveren, men dette bruker vi kun til å lage søkestatistikk. Vi benytter en Nginx-webserver der loggene overskrives etter en stund, slik at IP-adressene ikke lagres permanent noe sted. Vi logger også bruken av enkelte funksjoner på nettsiden med plausible.io, som ikke lagrer IP-adresser eller annen informasjon som kan knytte bruksstatistikken til bestemte brukere.</p>
</details>
</div>
<div class="article" v-if="$store.state.currentLocale == 'ukr'">
<h1> Про нас </h1>
<p>Це новий вебсайт для стандартних словників двох письмових варіантів норвезької мови – <em>букмола</em> та <em>нюношка</em>. Сайт все ще розробляється, тому деякі функції ще не доступні. Робота над переглядом вмісту словників триває, редакція постійно публікує доопрацьовані та перевірені на якість словникові статті. </p>
<p>У зв’язку з оновленням ми почистили як інтерфейс, так і наші дані. Тому в новій версії можуть бути помилки та недоліки, які ми ще не виявили або не встигли виправити. Якщо ви знайдете помилку або виявите, що чогось бракує, ми хотіли б отримати відгук про це! Не соромтеся зв’язатися з нами електронною поштою:</p>
<p>
<ul class="bullet">
<li>{{$t('contact.content[2]')}}
<a href="mailto:ordbok@uib.no">ordbok@uib.no</a>
</li>
<li>{{$t('contact.content[3]')}}
<a href="mailto:ordbok-teknisk@uib.no">ordbok-teknisk@uib.no</a>
</li>
</ul>
</p>
<details>
<summary>
<h2>Не можете знайти слово в словнику?</h2>
</summary>
<p>
<em>Словник букмола</em> та <em>Словник нюношка</em> — онлайн-словники середнього розміру.
<em>Словник букмола</em> налічує близько 65&nbsp;000 словникових статей, а <em>Словник нюношка</em> близько 90&nbsp;000,
але <a href="http://www.uib.no/lle/revisjonsprosjektet">наповнення триває</a> і ми очікуємо,
що обидва словники міститимуть близько 100 000 слів. Словники нададуть інформацію про основний
словниковий запас і це, здебільшого, найпоширеніші слова в письмових мовах <em>букмола</em> і <em>нюношка</em> за останні 50 років.
Технічні терміни з певних галузей включені лише в тому випадку,
якщо вони використовуються поза професійною сферою, у якій вони виникли.
</p>
<p>
Найпоширеніший спосіб створення нових норвезьких слів — це поєднання старих слів по-новому,
і є незліченна кількість комбінацій. Тому є багато поєднань, які не мають власних статей
у словниках. Навіть якщо ви не знайдете тут ключове
слово <em>sykkelsete</em> (велосипедне сидіння), це не означає, що цього слова не існує або воно не дозволене.
Складені слова включені, зокрема, з трьох причин:</p>
<p>
<ul class="bullet">
<li>коли вони не відразу зрозумілі на основі знання кожного окремого елемента </li>
<li>щоб користувач словника на основі складених словосполучень міг зрозуміти, що означають інші словосполучення з тим самим складником</li>
<li>щоб показати, яку сполучну літеру має мати складова частина (<em>skogbruk</em> (лісове господарство), але <em>skog<u>s</u>arbeid</em> (лісова робота); <em>sakefall</em> (грошове стягнення, яке накладається як покарання - застаріле слово), але <em>sak<u>es</u>løs</em> (невинуватий); <em>sakfører</em> (адвокат), але <em>sak<u>s</u>behandler</em> (відповідальний); <em>ost<u>e</u>klokke</em> (сирна кришка), але <em>dørklokke</em> (дверний дзвінок)</li>
</ul>
</p>
<p>
Аналогічно, стандартні словники містять обмежену кількість похідних слів (наприклад, дієприкметників на <em>-ing</em>).
У норвезькій мові можна утворювати форми дієслів на <em>-ing</em> майже зі всіх дієслів.
Тому якщо ви знайдете слова <em>organisere</em> та <em>sitere</em> у словниках <em>букмола</em> та <em>нюношка</em>,
ви можете самостійно створити похідні слова: <em>organisering</em> (організація) та <em>sitering</em> (цитування).
Проте зауважте, що існують потенційні форми <em>-ing</em>, які рідко використовуються, наприклад <em>komming</em> і <em>væring</em>.
</p>
<p>
Ці словники не є списком дозволених слів для вживання в норвезькій мові.
Існує багато слів, які не включені до словників, але їх можна використовувати.
Нові слова не потребують затвердження, адже лише користувачі мови спільно вирішують,
які слова є загальновживаними в норвезькій мові. Зазвичай нові слова не включаються до словників,
поки вони не стануть вживаними і не закріпляться в мові. Редакція словників вирішує, які слова повинні
бути включені на основі досліджень великих текстових колекцій, а Мовна рада визначає, як варто писати
та відмінювати ці слова.
</p>
<p>
<a href="https://www.sprakradet.no/Vi-og-vart/Publikasjoner/Spraaknytt/spraknytt-2014/Spraknytt-12014/Ord-som-finst-og-ikkje-finst/">Тут ви можете прочитати більше про вибір слів</a>, зокрема, для словників <em>букмола</em> та <em>нюношка</em>.
</p>
<p>
Якщо ви не можете знайти потрібне слово, ви можете перевірити більші та документовані словники <a href="https://alfa.norsk-ordbok.no">Norsk Ordbok</a> (для діалектних слів і нюношка) і <a href="https://naob.no/">NAOB</a> (для букмола).
</p>
</details>
<details>
<summary>
<h2>Забезпечення якості вмісту</h2>
</summary>
<p>
<em>Словник букмола</em> та <em>Словник нюношка</em> — це два незалежні, одномовні словники для
<em>букмола</em> та <em>нюношка</em> відповідно. Словники є спільною власністю Мовної ради та Бергенського університету.
</p>
<p>
<a href="https://www.sprakradet.no/">Мовна рада</a> вирішує, як варто писати й відмінювати слова <em>букмолом</em> та <em>нюношком</em>.
<em>Букмол</em> та <em>нюношк</em> постійно оновлюються відповідно до рішень щодо правопису в Мовній раді,
тож тут ви знайдете правильні відповіді щодо поточної та повної орфографії <em>букмола</em> та <em>нюношка</em>.
</p>
<p>
З 2016 року редакційна робота над стандартними словниками проводиться в Бергенському університеті,
де задіяно кілька відділів.
<a href="https://www.uib.no/ub/spesialsamlingene/160666/om-spr%C3%A5ksamlingane">Відділ Норвезькі мовні коллекції</a>
керує словниками та вихідним матеріалом, на якому вони базуються. Редактори словників працюють у
<a href="https://www.uib.no/lle">Інституті лінгвістичних, літературознавчих та естетичних досліджень</a>,
а технічна робота з даними відбувається в ІТ-відділі. Якість вмісту словників гарантує Мовна рада.</p>
</details>
<details>
<summary>
<h2>Цитування словників</h2>
</summary>
<p>
Вміст словників <em>букмола</em> і <em>нюношка</em> захищено авторським правом, див. Закон про авторське право на інтелектуальну
власність тощо. Якщо ви бажаєте процитувати статтю зі словника <em>букмола</em> або <em>нюношка</em>,
ми рекомендуємо вказати дату, коли статтю було взято (прочитано), наприклад, так:
</p>
<blockquote>
<p>“Hvordan”. У: <em>Словнику букмола</em>. Мовна рада та Бергенський університет. <br>‹http://ordbøkene.no› (взято 25.01.2022).</p>
</blockquote>
<p>У довідці потрібно згадати обох власників словника — Мовну раду та Бергенський університет.</p>
</details>
<details>
<summary>
<h2>Словники на смартфоні</h2>
</summary>
<p>
Вебсайт ordbøkene.no має адаптивний дизайн, що дозволяє вмісту адаптуватися до екранів будь-якого розміру.
Якщо ви хочете мати посилання на словники <em>букмола</em> та <em>нюношка</em> на своєму мобільному екрані,
ви можете знайти ordbøkene.no в браузері та додати його як іконку на екран. Іконка виглядає як додаток,
і ви можете одразу перейти на вебсайт, не заходячи через браузер.</p>
<h3>Для iPhone/iOs:</h3>
<p>
<ul class="bullet">
<li>Відкрийте браузер і введіть ordbokene.no або ordbøkene.no.</li>
<li>Коли ви знаходитесь на головній сторінці, виберіть іконку внизу сторінки щоб поділитися: <v-icon>ios_share</v-icon>.</li>
<li>З’являться варіанти у двох рядках. У нижньому рядку виберіть “Додати на головний екран” з іконкою <v-icon>add_box</v-icon>. Можливо, вам доведеться перетягнути рядок з правого боку, щоб дістатися до іконки.</li>
</ul>
</p>
<p>Іконка словників <img class="ordbokene-icon" src="favicon.ico" aria-hidden="true"/> тепер знаходиться на домашньому екрані вашого пристрою, і ви зможете зайти на сторінку словника, натиснувши на неї.</p>
<h3>Для Android:</h3>
<p>
<ul class="bullet">
<li>Відкрийте браузер і введіть ordbokene.no або ordbøkene.no.</li>
<li>Коли ви знаходитесь на головній сторінці, виберіть іконку з трьома вертикальними крапками у верхньому правому куті: <v-icon>more_vert</v-icon>.</li>
<li>З’явиться список варіантів вибору, і ви обираєте “Додати на стартову сторінку”, дещо нижче в списку.</li>
<li>З’явиться вікно, яке пропонує додати ordbøkene.no на стартову сторінку. Натисніть опцію “Додати”.</li>
</ul>
</p>
<p>
Іконка словників <img class="ordbokene-icon" src="favicon.ico" aria-hidden="true"/> тепер знаходиться на вашій основній сторінці, і ви можете перейти безпосередньо на сторінку словника, натиснувши на неї.
Увага! У деяких моделях Samsung вибір "Додати до сторінки" знаходиться в меню внизу сторінки. Звідти виберіть стартову сторінку.
</p>
</details>
<details>
<summary>
<h2>Відкриті дані</h2>
</summary>
<p>Вміст словників <em>букмола</em> та <em>нюношка</em> доступний для завантаження й може використовуватися для будь-яких цілей, включаючи комерційні, відповідно до наведених умов. <a href="https://www.uib.no/ub/fagressurser/spesialsamlingene/142334/lisens-bokm%C3%A5lsordboka-og-nynorskordboka">Дізнайтеся більше про відкриту ліцензію тут</a>.</p>
<p>Інформація в таблицях зміни форми слів у словниках <em>букмола</em> та <em>нюношка</em> отримана з Норвезької бази даних слів (Norsk ordbank). Вона є лексичною базою даних для <em>букмола</em> та <em>нюношка</em>, яка містить інформацію про клас та форми зміни для значно більшої кількості слів, ніж ті, які є у стандартних словниках. База даних норвезьких слів доступна для завантаження в Мовному банку (Språkbanken) Національної бібліотеки
за ліцензією CC-BY.</p>
</details>
<details>
<summary>
<h2>Історія</h2>
</summary>
<p>Словники <em>букмола</em> та <em>нюношка</em> вперше були видані у 1986 році в рамках спільного проєкту Університету Осло та Норвезької мовної ради і з тих пір вийшли у декількох виданнях. У друкованому вигляді словники <em>букмола</em> та <em>нюношка</em> є великими однотомними словниками. Вони показують правопис та зміну форми слів, які завжди відповідають чинним нормам. Крім того, словники надають значення, приклади використання та короткі етимології.</p>
<p>
<a href="https://www.uib.no/sites/w3.uib.no/files/attachments/om_ordbokene.pdf">Тут ви знайдете передмови до друкованих видань</a>,
додаткову інформацію про попередніх редакторів словників та раніше проведену роботу в Університеті Осло.
</p>
<p>Бергенський університет та Норвезька мовна рада більше не випускатимуть друковані видання стандартних словників.</p>
</details>
<details>
<summary>
<h2>Проєкт перегляду словників</h2>
</summary>
<p>Наразі триває значна робота з оновленням вмісту словників <em>букмола</em> та <em>нюношка</em>. З 2018 по 2023 рік група редакторів працює над обома словниками від початку до кінця алфавіту. Найважливіші завдання - додати нові слова й оновити значення, переконатись, що вміст відповідає сучасній мові та зробити вибір слів подібним в обох словниках. Додаткову інформацію можна знайти на <a href="https://www.uib.no/lle/revisjonsprosjektet"">сайті Проєкту перегляду словників</a>.</p>
<p>Поточний склад редакції словників <em>букмола</em> та <em>нюношка</em>:
<ul>
<li>Anne Engø, редактор 2018–2023</li>
<li>Marita Kristiansen, редактор 2020–2021</li>
<li>Gunn Inger Lyse, редактор 2018–2023</li>
<li>Mikkel Ekeland Paulsen, науковий співробітник 2019–2023</li>
<li>Margunn Rauset, керівник проєкту 2018–2023</li>
<li>Bente Selback, редактор 2018–2023</li>
<li>Kari-Anne Selvik, редактор 2018–2023</li>
<li>Klara Sjo, редактор 2020–2022</li>
<li>Marie Lund Stokka, редактор 2020</li>
</ul>
</p>
<p>Контролери якості від Норвезької мовної ради:
<ul>
<li>Sturla Berg-Olsen, старший радник</li>
<li>Knut E. Karlsen, старший радник</li>
<li>Dagfinn Rødningen, старший радник</li>
<li>Ålov Runde, старший радник</li>
</ul>
</p>
<p>Цю сторінку створили розробники ІТ-департаменту Бергенського університету:
<ul>
<li>Henrik Askjer, головний інженер</li>
<li>Eirik T. Gullaksen, головний інженер, ІТ-відділ</li>
<li>Paul Meurer, головний інженер, IT-відділ</li>
<li>Nils Øverås, головний інженер, IT-відділ</li>
<li>Ole Voldsæter, головний інженер, IT-відділ 2019–2021</li>
</ul>
</p>
<p>
<a href="https://www.netlife.com/">Netlife</a> провели дослідження користувачів та розробили макети дизайну для ordbøkene.no.
</p>
</details>
<details>
<summary>
<h2>Корисні посилання на мовні ресурси</h2>
</summary>
<p>Якщо у вас виникли питання щодо чіткого, правильного та коректного використання норвезької мови, будь ласка, зверніться до <a href="mailto:sporsmal@sprakradet.no">служби відповідей Мовної ради</a>.
</p>
<h3>Мовні ресурси онлайн</h3> У Норвезькій мовній колекції в Бібліотеці Університету Бергена є низка мовних ресурсів, зокрема:
<ul class="bullet">
<li>
<a href="https://ord.uib.no/">ord.uib.no:</a> словники і опис API для ordbøkene.no (норвезькою). <a href="https://ordbokene.no/api/swagger-ui.html">Інтерактивна документація англійською мовою</a>)
</li>
<li>
<a href="http://inger.uib.no/perl/search/search.cgi?appid=72&tabid=1106">Норвезька база даних слів, букмол</a>: Пошук повних списків форм відмінювання для норвезької мови (букмол)
</li>
<li>
<a href="http://inger.uib.no/perl/search/search.cgi?appid=73&tabid=1116">Норвезька база даних слів, нюношк</a>: Пошук повних списків форм відмінювання для норвезької мови (нюношк)
</li>
<li>
<a href="http://inger.uib.no/perl/search/search.cgi?appid=7&tabid=571">Метасловник</a>: База даних документації всіх зареєстрованих слів, відсортованих стандартними заголовними словами нюношка
</li>
<li>
<a href="http://inger.uib.no/perl/search/search.cgi?appid=118&tabid=1777">Ordbokhotellet</a>: електронний індекс форм слів із ряду словників і сукупності місцевих діалектів, відсортовані за стандартизованими заголовками
</li>
</ul>
</p>
<p>
<a href="http://www.sprakradet.no/">Мовна рада</a> має кілька мовних ресурсів у меню “Мовна допомога” (Språkhjelp), перейдіть на <a href="http://www.sprakradet.no/sprakhjelp/Skriveregler/">правила правопису</a>, <a href="http://www.sprakradet.no/sprakhjelp/Praktisk-grammatikk/">практична граматика</a> або <a href="http://www.sprakradet.no/sprakhjelp/Skriverad/">письмові поради</a>.
</p>
<p>Norsk ordbank (база даних норвезьких слів) також доступний для завантаження на сайті <a href="https://www.nb.no/sprakbanken/ressurskatalog/?_search=ordbank">Мовного банку у Національній бібліотеці</a> за ліцензією CC-BY. База містить списки слів для букмолу та нюношку з інформацією про клас слів і стандартні форми зміни слів. </p>
<h3>Інші безкоштовні словники</h3>
<ul class="bullet">
<li>
<a href="https://alfa.norsk-ordbok.noperl/ordbok/no2014.cgi">Норвезький словник</a>: Словник норвезьких діалектів та письмового нюношка
</li>
<li>
<a href="https://naob.no/">NAOB</a>: словник Норвезької академії: букмол і ріксмол з початку 1800-х років до сьогодні
</li>
<li>
<li><a href="http://lexin.udir.no/">LEXIN</a>: словники для студентів, які вивчають мови національних меншин у початковій, неповній середній та повній середній освіті, а також освіті для дорослих
</li>
<li>
<a href="https://islex.arnastofnun.is/no/">ISLEX</a>: словник ісландсько-норвезької (букмол і нюношк), ісландсько-шведської, ісландсько-данської, ісландсько-фарерської та ісландсько-фінської мови
</li>
<li>
<a href="http://ordnet.dk/">ordnet.dk</a>: спільна вебсторінка для кількох словників данської мови
</li>
<li>
<a href="https://svenska.se/">svenska.se</a>: спільна вебсторінка для кількох словників шведської мови
</li>
</ul>
</p>
</details>
<details>
<summary>
<h2>Конфіденційність</h2>
</summary>
<p>Ordbøkene.no не використовує файли cookie, але зберігає налаштування користувача за допомогою локального сховища в браузері, не надсилаючи цю інформацію на наш сервер в UiB. Пошуки реєструються на сервері, але ми не використовуємо цю інформацію для інших цілей, крім статистики пошуку. Ми використовуємо вебсервер Nginx, який постійно перезаписує журнали, тому ми ніколи не зберігаємо IP-адреси. Ми також реєструємо використання певних функцій на веб-сайті за допомогою plausible.io, служби, яка не зберігає IP-адреси чи іншу інформацію, яка може зв’язати статистику використання з окремими користувачами.</p>
</details>
</div>
</div>
</main>
</template>
<script>
export default {
name: 'About',
metaInfo() {
return {title: "Om ordbøkene",
meta: [{name: 'description', vmid: 'description', content: "Dette er nettsida til standardordbøkene Bokmålsordboka og Nynorskordboka."}],
link: [{rel: "canonical", href: 'https://ordbokene.no/om'} ]
}
}
}
</script>
<style scoped>
main {
background-color: var(--v-tertiary-base);
}
.about_lang {
margin-left: 20px;
}
.about {
padding-left: calc((100vw - 1200px) / 2);
padding-right: calc((100vw - 1200px) / 2);
}
h1, h2, h3, p{
padding: 3px;
}
ul.bullet > li {
list-style: disc;
margin-left: 20px;
}
details summary > * {
display: inline;
}
summary {
width: auto;
cursor: pointer;
margin-bottom: 10px;
padding-bottom: 10px;
text-align: left;
}
blockquote {
margin-left:50px;
}
.ordbokene-icon {
width: 16px;
height: 16px;
}
</style>
<template>
<article v-show="article.lemmas.length">
<Header :lemmas="article.lemmas" />
<section v-if="article.body.pronunciation.length">
<h3>Uttale</h3>
<ul>
<DefElement v-for="(element, index) in article.body.pronunciation" :key="index" :body='element' @article-click="article_link_click" />
</ul>
</section>
<section v-if="article.body.etymology">
<h3>Etymologi</h3>
<div v-if="article" :lang="{nob:'nb', nno: 'nn', eng: 'en', 'ukr': 'uk'}[dictionary]" class="article-container">
<span :lang="lang_tag_locale" v-if="$vuetify.breakpoint.smAndDown || !$route.name || $route.name == 'lookup'" class="dict-label" role="heading" aria-level="2">{{dict_label}}</span>
<div class="article" v-bind:class="{'expanded': !collapsed && collapsable, 'collapsable': collapsable, 'hide-label': hide_label, 'v-sheet v-card rounded-xl': !$parent.article}" v-if="article">
<div :class="$vuetify.breakpoint.name" v-if="!invalid">
<Header :title_id="title_id" :lemmas="article.lemmas" :dictionary="dictionary" :article_id="article.article_id" @toggle-collapse = "toggle_collapse"/>
<div class="article_content" :class="$vuetify.breakpoint.name" v-show="!collapsed" ref="article_content">
<section v-if="article.body.pronunciation && article.body.pronunciation.length" class="pronunciation">
<h4 :lang="lang_tag_locale">{{$t('article.headings.pronunciation', content_locale)}}</h4>
<ul>
<DefElement v-for="(element, index) in article.body.pronunciation" :dictionary="dictionary" :key="index" :body='element' @article-click="article_link_click" @error="article_error"/>
</ul>
</section>
<section v-if="article.body.etymology && article.body.etymology.length" class="etymology">
<h4 :lang="lang_tag_locale">{{$t('article.headings.etymology', content_locale)}}</h4>
<ul>
<DefElement v-for="(element, index) in article.body.etymology" :dictionary="dictionary" :key="index" :body='element' @article-click="article_link_click" @error="article_error"/>
</ul>
</section>
<section class="definitions" v-if="has_content">
<h4 :lang="lang_tag_locale">{{$t('article.headings.definitions', content_locale)}}</h4>
<ol>
<Definition v-for="definition in article.body.definitions" :dictionary="dictionary" :level="1" :key="definition.id" :body='definition' @article-click="article_link_click" @error="article_error"/>
</ol>
</section>
<section v-if="sub_articles.length" class="expressions">
<h4 :lang="lang_tag_locale">{{$t('article.headings.expressions', content_locale)}}</h4>
<ul>
<DefElement v-for="(element, index) in article.body.etymology" :key="index" :body='element' @article-click="article_link_click" />
<SubArticle :body="subart" v-for="(subart, index) in sub_articles" :dictionary="dictionary" :key="index" @article-click="article_link_click" @error="article_error"/>
</ul>
</section>
<section>
<h3>Definisjoner</h3>
<ol>
<Definition v-for="definition in definitions" :key="definition.id" :body='definition' @article-click="article_link_click" />
</ol>
</section>
</article>
</section>
</div>
<ArticleFooter v-if="!collapsed" :article="article"/>
</div>
<div v-else><v-icon left>warning</v-icon> {{$t('error.article', {no: article.article_id, dict: $t('dicts_inline.'+this.dictionary)})}}</div>
</div>
</div>
</template>
<script>
//import axios from "axios";
import DefElement from './DefElement.vue'
import Definition from './Definition.vue'
import SubArticle from './SubArticle.vue'
import Header from './Header.vue'
import ArticleFooter from './ArticleFooter.vue'
import entities from '../utils/entities.js'
import Mark from 'mark.js';
function find_sub_articles(definition) {
let sub_art_list = []
try {
let sub_definitions = definition.elements.filter(el => el.type_ == 'definition')
let sub_articles = definition.elements.filter(el => el.type_ == 'sub_article' && el.lemmas)
sub_definitions.forEach((subdef, i) => {
sub_art_list = sub_art_list.concat(find_sub_articles(subdef))
})
sub_art_list = sub_art_list.concat(sub_articles)
return sub_art_list
}
catch(error) {
console.log("find_sub_articles", this.article.article_id, this.dictionary, '"'+error.message+'"')
return []
}
}
export default {
name: 'Article',
props: {
article: Object
article: Object,
articleLookup: Boolean,
title_id: String,
queryPattern: String,
scope: String,
},
data: function() {
return {
is_collapsed: true,
invalid: false
}
},
metaInfo() {
if (this.articleLookup) {
return {title: this.article.lemmas[0].lemma + ' | ' + {"bm,nn": "Bokmålsordboka og Nynorskordboka", "bm": "Bokmålsordboka", "nn": "Nynorskordboka"}[this.dictionary],
meta: [{name: 'description', vmid: 'description', content: this.meta_description}],
link: [{rel: "canonical", href: `https://ordbokene.no/${this.article.dictionary}/${this.article.article_id}`} ]
}
}
},
computed: {
hide_label: function() {
//collapsable || (collapsed && $store.state.collapseArticles != 'never')
if (this.$parent.count_bm || this.$parent.count_nn) {
let two_results = (this.$parent.count_bm + this.$parent.count_nn) < 3
if (two_results) {
return false
}
else if (this.$vuetify.breakpoint.mdAndUp && (this.collapsed || this.$store.state.collapseArticles == 'never')) {
return true
}
else {
return false
}
}
},
dictionary: function() {
return this.article.dictionary
},
content_locale: function() {
if (this.$i18n.locale == 'eng') {
return 'eng'
} else if (this.$i18n.locale == 'ukr') {
return 'ukr'
} else {
return {bm: 'nob', nn: 'nno'}[this.dictionary]
}
},
fulltext_highlight: function() {
return this.$store.state.fulltextHighlight
},
collapsable: function() {
if (this.$parent.$options.name != 'SearchResults') {
this.is_collapsed = false
return false
}
let collapsable = this.$store.state.collapseArticles
if (collapsable == 'never') {
this.is_collapsed = false
return false
}
if (collapsable == 'always') {
this.is_collapsed = true
return true
}
if (collapsable == 'auto') {
this.is_collapsed = this.$parent.$options.name == 'SearchResults' && (this.$parent.results_bm.length + this.$parent.results_nn.length > 2)
return this.$parent.$options.name == 'SearchResults' && (this.$parent.results_bm.length + this.$parent.results_nn.length > 2)
}
},
collapsed: {
get() {
if (this.$parent.$options.name != 'SearchResults') {
return false
}
if (!this.collapsable) {
this.is_collapsed = false
}
return this.is_collapsed
},
set(value) {
this.is_collapsed = value
}
},
snippet: function() {
if (this.collapsable && this.article.body.definitions) {
return this.meta_description
}
return null
},
meta_description: function() {
return this.parse_definitions(this.article.body.definitions)
},
link_to_self: function() {
try {
return {
ref: '/' + this.dictionary + '/' + this.article.article_id,
article: this.article
}
} catch(error) {
console.log("link_to_self",this.article.article_id, this.dictionary, '"'+error.message+'"')
this.invalid = true
//console.error(error)
return {ref: "", article: this.article}
}
},
lang_tag_locale: function() {
return {nob: "nb", nno: "nn", eng: "en", ukr: "uk"}[this.content_locale]
},
dict_label: function() {
let label = ''
const dictionary = this?.article?.dictionary
if (dictionary) {
if (this.$route.name) {
label = this.$t(`dicts.${dictionary}`, this.content_locale)
} else {
label = this.$t('from', this.content_locale) + " " + this.$t(`dicts_from.${dictionary}`, this.content_locale)
}
}
return label
},
sub_articles: function() {
return this.article.body.definitions.reduce((acc, val) => acc.concat(find_sub_articles(val)), []).sort((s1, s2) => s1.lemmas[0].localeCompare(s2.lemmas[0]))
},
has_content: function() {
for (const definition of this.article.body.definitions) {
for (const element of definition.elements) {
if (['explanation', 'example', 'compound_list', 'definition'].includes(element.type_)) {
return true
}
}
}
return false
}
},
components: {
DefElement,
Definition,
Header
SubArticle,
Header,
ArticleFooter
},
computed: {
definitions: function() {
let defs = this.article.body.definitions
if (defs.length == 1) {
let types = defs[0].elements.reduce((acc, toAdd)=>acc.add(toAdd.type_), new Set())
if (types.size == 1 && types.has('definition')) {
return defs[0].elements
}
mounted: function() {
if (this.scope && this.scope.includes("f")) {
let instance = new Mark(this.$refs.article_content)
if (/[_%|]/.test(this.queryPattern)) {
instance.markRegExp(new RegExp(this.queryPattern), {acrossElements: true, separateWordSearch:false});
}
return defs
else {
instance.mark(this.queryPattern, {acrossElements: true, separateWordSearch:false, accuracy: 'exact', wildcards: 'enabled'});
}
}
if (this.$route.hash == "#"+ this.title_id) {
let focused = document.getElementById(this.title_id)
if (focused) focused.focus()
}
else if (this.$route.hash) {
let focused =document.getElementById(this.$route.hash.replace("#",""))
if (focused) focused.scrollIntoView({block: "center"})
}
},
methods: {
article_error: function(payload) {
console.log("DefElement",payload.location, this.article.article_id, this.dictionary, '"'+payload.message+'"')
},
parse_subitems: function(explanation, text) {
let new_string = ""
let old_parts = text.split(/(\$)/)
let linkIndex = 0
let self = this
old_parts.forEach((item) => {
if (item == '$') {
let subitem = explanation.items[linkIndex]
if (/^\d$/.test(subitem.text)) {
if (subitem.type_ == "superscript") {
new_string += "⁰¹²³⁴⁵⁶⁷⁸⁹"[parseInt(subitem.text)]
}
else if (subitem.type_ == "subscript") {
new_string += "₀₁₂₃₄₅₆₇₈₉"[parseInt(subitem.text)]
}
}
else if (subitem.id) {
new_string += entities[self.dictionary][explanation.items[linkIndex].id].expansion
}
else if (subitem.text) {
if (subitem.text.includes('$')) {
new_string += self.parse_subitems(subitem, subitem.text)
}
else new_string += subitem.text
}
else {
if (explanation.items[linkIndex].lemmas) {
new_string += explanation.items[linkIndex].word_form || explanation.items[linkIndex].lemmas[0].lemma
}
}
linkIndex += 1
}
else {
new_string += item
}
})
return new_string
},
parse_definitions: function(node) {
let definitionTexts = []
let self = this
try {
node.forEach((definition) => {
if (definition.elements) {
if (definition.elements[0].content) {
let new_string = self.parse_subitems(definition.elements[0], definition.elements[0].content)
if (new_string.substring(new_string.length, new_string.length - 1) == ":") {
new_string = new_string.slice(0, -1)
}
definitionTexts.push(new_string)
}
else if (definition.elements[0].elements) {
definitionTexts.push(self.parse_definitions(definition.elements))
}
}
})
} catch(error) {
console.log("parse_definitions",this.article.article_id, this.dictionary, '"'+error.message+'"')
this.invalid = true
definitionTexts = []
}
let snippet = definitionTexts.join("\u00A0•\u00A0")
return snippet
},
toggle_collapse: function() {
if (this.collapsed) {
this.$plausible.trackEvent('expand article', {props: {article: `${this.dictionary} ${this.article.article_id}`}})
}
this.collapsed = !this.collapsed
},
article_link_click: function(item) {
this.$emit('article-click', item)
},
details_click: function(item) {
item.title_id = this.title_id
this.$emit('details-click', item)
}
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style>
article {
margin-top: 30px;
.article {
position: relative;
padding: 24px;
padding-bottom: 12px;
margin-bottom: 20px;
margin-right: 10px;
margin-left: 10px;
background-color: #ffffff;
}
section.xs .article, section.sm .article {
margin-bottom: 10px !important;
}
h3 {
margin: 40px 0 0;
section.md .article, section.lg .article, section.xl .article {
padding-top: 10px;
}
a {
//color: #42b983;
.welcome .article_footer {
display: block;
}
ol > li {
padding-bottom: 2em;
#single_article_container .article {
border: none;
margin-top: 10px;
}
ul {
padding-top: 8px;
section {
padding-top: 10px;
padding-bottom: 10px
}
ul li {
list-style:none;
section.etymology > h4, section.pronunciation > h4 {
display: inline;
}
section.etymology ul, section.pronunciation ul, section.etymology li, section.pronunciation li {
display: inline;
}
section.etymology li:not(:first-child):not(:last-child):before, section.pronunciation li:not(:first-child):not(:last-child):before {
content: ", ";
}
section.etymology li:not(:first-child):last-child:before, section.pronunciation li:not(:first-child):last-child:before {
content: "; ";
font-size: smaller;
}
li {
padding-bottom: 4px;
}
li.level1.definition {
list-style: upper-alpha;
}
li.level2.definition {
list-style: decimal;
}
li.level3.definition {
/* Norsk ordbok skal ha "lower.alpha" her */
list-style: disc;
}
li ul .definition ul {
padding-left: 6px;
li.sub_article > ul {
padding-left: 0px;
}
::marker {
font-weight: bold;
color: var(--v-primary-base);
}
ol > li:only-child.level1, li:only-child.level2 {
/* level3 a.k.a. underdefinisjoner skal vises med bullet selv om de står alene */
list-style: none;
}
li:only-child.level1 > ol {
padding-left: 0px;
}
ul, ol {
padding-left: 12px !important;
}
ul li {
list-style:none;
}
ul li.definition {
list-style: disc;
}
.choose {
color: var(--v-primary-base) !important;
text-decoration: none;
}
.info-card {
padding: 12px;
}
.expanded {
padding-bottom: 34px;
}
.header {
border-radius: 0px !important;
}
.dict-label {
color: var(--v-primary-base) ;
font-weight: bold;
position: absolute;
padding-left: 34px;
margin-top: -2px;
z-index: 2;
font-variant-caps: all-small-caps;
font-size: 1.17em;
}
</style>
<template>
<div :lang="lang_tag_locale" class="article_footer">
<v-snackbar centered
max-width="300px"
min-width="300px"
max-height="36px"
min-height="36px"
rounded="pill"
v-model='copy_popup'
timeout="1000">
<span class="text-center">{{$t(what_copied, content_locale)}}</span>
</v-snackbar>
<v-btn v-if="showLinkCopy"
small text class="toolbar-button" rounded @click="copy_link">
<v-icon small left>link</v-icon><span class = "button-text">{{$t("article.copy_link", content_locale)}}</span>
</v-btn>
<v-btn v-if="webShareApiSupported" text small class="toolbar-button" rounded @click="shareViaWebShare">
<v-icon small left>share</v-icon><span class = "button-text">{{$t("article.share", content_locale)}}</span>
</v-btn>
<v-dialog max-width="600px" v-model="citation_dialog">
<template v-slot:activator="{ on, attrs }">
<v-btn @click="track_citation" text small class="toolbar-button" rounded v-on="on" v-bind="attrs">
<v-icon left small>format_quote</v-icon> <span class = "button-text">{{$t("article.cite", content_locale)}}</span>
</v-btn>
</template>
<v-card>
<v-toolbar elevation="0">
<v-toolbar-title><span role="heading" aria-level="1">{{$t('article.cite_title')}}</span></v-toolbar-title>
<v-spacer></v-spacer><v-toolbar-items><v-btn @click="close_citation_dialog" text>{{$t('close')}}<v-icon right>close</v-icon></v-btn></v-toolbar-items></v-toolbar>
<v-card-text class="text--primary">
{{$t("article.cite_description[0]", content_locale)}}<em>{{$t('dicts.'+$parent.dictionary)}}</em>{{$t("article.cite_description[1]", content_locale)}}
<br/>
<div id = "citation" v-html="this.create_citation()"/>
</v-card-text>
<v-card-actions>
<v-btn depressed small rounded @click="copy_citation"><br>
<v-icon left small icon>content_copy</v-icon> <span class = "button-text">{{$t("article.copy", content_locale)}}</span>
</v-btn>
<v-btn depressed small rounded @click="download_ris"><br>
<v-icon left small icon>get_app</v-icon> <span class = "button-text">{{$t("article.download")}}</span>
</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</div>
</template>
<script>
export default {
name: 'ArticleFooter',
props: {
article: Object
},
computed: {
webShareApiSupported() {
return navigator.share
},
showLinkCopy() {
return (!navigator.share || this.$vuetify.breakpoint.mdAndUp) && navigator.clipboard
},
hasPointer() {
return window.matchMedia('(hover: hover) and (pointer: fine)').matches
},
content_locale: function() {
return this.$parent.content_locale
},
lang_tag_locale: function() {
return this.$parent.lang_tag_locale
}
},
data: function() {
return {
copy_popup: false,
citation_dialog: false,
what_copied: null
}
},
methods: {
track_citation() {
this.$plausible.trackEvent('citation click', {props: {article: `${this.$parent.dictionary} ${this.$parent.article.article_id}`}})
},
shareViaWebShare() {
this.$plausible.trackEvent('webshare', {props: {article: `${this.$parent.dictionary} ${this.$parent.article.article_id}`}})
navigator.share({
title: "Ordbøkene.no: " + this.article.lemmas[0].lemma,
text: "",
url: "/" + this.article.dictionary + '/' + this.article.article_id
})
},
create_link() {
return 'https://ordbokene.no/' + this.article.dictionary + '/' + this.article.article_id
},
get_citation_info() {
let date = new Date();
let dd = (date.getDate() < 10? '0' : '') + date.getDate()
let mm = (date.getMonth() < 9? '0' : '') + (date.getMonth()+1)
let yyyy = date.getFullYear()
let link = this.create_link()
let lemma = this.article.lemmas[0].lemma
let dict = this.$t(`dicts.${this.article.dictionary}`, this.content_locale)
return [lemma, dd, mm, yyyy, link, dict]
},
create_citation() {
const [lemma, dd, mm, yyyy, link, dict] = this.get_citation_info()
let citation = this.$t("article.citation", {lemma, link, dd, mm, yyyy, dict})
return citation
},
copy_link() {
let link = this.create_link()
console.log(`${this.$parent.dictionary} ${this.$parent.article.article_id}`)
this.$plausible.trackEvent('copy link', {props: {article: `${this.$parent.dictionary} ${this.$parent.article.article_id}`}})
let self = this
navigator.clipboard.writeText(link).then(() => {
self.what_copied = this.$t("article.link_copied")
self.copy_popup = true
}).catch(err => {
console.log("ERROR COPYING:",err)
})
},
copy_citation() {
let citation = document.getElementById("citation").textContent;
navigator.clipboard.writeText(citation)
this.citation_dialog = false
this.what_copied = this.$t("article.citation_copied")
this.copy_popup = true
},
close_citation_dialog() {
this.citation_dialog = false
},
download_ris() {
const [lemma, dd, mm, yyyy, link] = this.get_citation_info()
const a = document.createElement("a")
a.style = "display: none"
a.setAttribute("download", `${lemma}_${this.article.dictionary}.ris`)
const dict = {"bm":"Bokmålsordboka", "nn": "Nynorskordboka"}[this.article.dictionary]
const text = `TY - DICT\nTI - ${lemma}\nT2 - ${dict}\nPB - Språkrådet og Universitetet i Bergen\nUR - ${link}\nY2 - ${yyyy}/${mm}/${dd}/\nER - `
a.setAttribute('href', 'data:application/x-research-info-systems;charset=utf-8,' + encodeURIComponent(text));
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
},
}
}
</script>
<style scoped>
.v-icon {
color: var(--v-primary-base) !important;
}
.toolbar-button {
margin-right: 8px;
margin-top: 8px;
font-size: 12px;
}
.article_footer {
color: var(--v-primary-base);
padding-top: 24px;
}
#citation {
margin-top: 12px;
padding: 12px;
background-color: var(--v-button-base) !important;
margin-bottom: 6px;
}
</style>
<template>
<li class="compound_list">
<ul>
<DefElement :body="body.intro" v-if="body.intro" />
<li :key="index" v-for="(item, index) in body.elements">
<router-link :to="item.article_id + (item.definition_id ? '#def'+item.definition_id : '')" @click.native="article_link_click(item)">
{{item.lemmas.join(',')}};
</router-link>
<DefElement :body="body.intro" v-if="body.intro" :dictionary="dictionary" />
<li
:key="index"
v-for="(item, index) in body.elements"
>{{' '}}<router-link
:to="'/' + dictionary + '/' + item.article_id + (item.definition_id ? '#def'+item.definition_id : '')"
@click.native="article_link_click(item)"
>{{item.lemmas[0].lemma}}</router-link>
</li>
</ul>
</li>
......@@ -17,7 +20,8 @@ import DefElement from './DefElement.vue'
export default {
name: 'CompoundList',
props: {
body: Object
body: Object,
dictionary: String
},
components: {
DefElement
......@@ -33,4 +37,12 @@ export default {
li.compound_list ul li {
display: inline;
}
li.compound_list li:not(:last-child):not(:first-child):after {
content: ",";
}
ul {
padding-left: 0px !important;
}
</style>
<template>
<v-list>
<v-list-item>
<div>
<h2>{{$t('contact.content[0]')}}</h2><p>
{{$t('contact.content[2]')}} <a href="mailto:ordbok@uib.no">ordbok@uib.no</a></p>
<h2>{{$t('contact.content[1]')}}</h2><p>
{{$t('contact.content[3]')}} <span style="white-space: nowrap;"><a href="mailto:ordbok-teknisk@uib.no">ordbok-teknisk@uib.no</a></span></p>
</div>
</v-list-item>
<v-list-item>
<v-list-item-title>
<h2>{{$t('contact.faq.title')}}</h2>
</v-list-item-title>
</v-list-item>
<v-list-group dense prepend-icon="help">
<template v-slot:activator>
<v-list-item-content>{{$t('contact.faq.items[0].title')}}</v-list-item-content>
</template>
<v-list-item><p><em>{{$t('dicts.bm')}}</em>{{$t('and')}}<em>{{$t('dicts.nn')}}</em>{{$t('contact.faq.items[0].text[0]')}}<router-link to="/om" @click.native="$emit('close')">{{$t('contact.faq.items[0].text[1]')}}</router-link></p></v-list-item>
</v-list-group>
<v-list-group prepend-icon="help">
<template v-slot:activator>
<v-list-item-content>{{$t('contact.faq.items[1].title')}}</v-list-item-content>
</template>
<v-list-item>{{$t('contact.faq.items[1].text')}}</v-list-item>
</v-list-group>
<v-list-group prepend-icon="help">
<template v-slot:activator>
<v-list-item-content>{{$t('contact.faq.items[2].title')}}</v-list-item-content>
</template>
<v-list-item>{{$t('contact.faq.items[2].text')}}</v-list-item>
</v-list-group>
</v-list>
</template>
<script>
export default {
name: "Contact",
}
</script>
<template>
<li :class="body.type_">
<span v-for="(item, index) in assemble_text"
:class="item.type_"
:key="index">
{{item.html}}
<router-link v-if="item.type == 'article_ref'" :to="item.ref" @click.native="article_link_click(item)" v-html="item.label">
</router-link>
</span>
</li>
<li :is="tag" :class="body.type_"><!--
--><span :is="item.tag || 'span'" v-for="(item, index) in assemble_text"
:class="item.type"
@error="article_error"
:key="index"
v-bind="item.props"><!--
-->{{item.html}}<!--
--><router-link class="article_ref" v-if="item.type == 'article_ref'" :to="item.ref" @click.native="article_link_click(item)" :key="index"><!--
--><DefElement tag='span' v-if="item.link_text.type_" :dictionary="dictionary" :key="item.id+'_sub'" :body='item.link_text'/><span v-else>{{item.link_text}}</span><!--
--><span class="homograph" v-if="item.lemmas[0].hgno" :aria-label="`${dictionary=='bm'? 'Betydning': 'Tyding'} ${item.lemmas[0].hgno}`" :title="`${dictionary=='bm'? 'Betydning': 'Tyding'} ${item.lemmas[0].hgno}`" :key="index"><!--
--> ({{roman_hgno(item.lemmas[0])}}{{item.definition_order ? '': ')'}}</span>
<span class="def_order" v-if="item.definition_order" :aria-label="'definisjon '+item.definition_order">{{item.lemmas[0].hgno ? ', ': ' ('}}{{item.definition_order}})</span>
</router-link>
<!--
--><span class="numerator" v-if="item.type == 'fraction'">{{item.num}}</span><!--
-->{{item.type == 'fraction' ? '' : ''}}<!--
--><span class="denominator" v-if="item.type == 'fraction'">{{item.denom}}</span><!--
--></span></li>
</template>
<script>
import entities from '../utils/entities.js'
import languages from '../utils/languages.js'
import helpers from '../utils/helpers.js'
function replace_grammar_id(item, lang) {
let content = item.content
if (content.includes('$') && (item.items[0].id)){
let replacement_item = entities[lang][item.items[0].id]['expansion']
content = content.replace('$', replacement_item)}
return content
}
export default {
name: 'DefElement',
props: {
body: Object
body: Object,
tag: {
type: String,
default: 'li'
},
dictionary: String
},
data: function() {
return {
path: this.$route.fullPath
}
},
computed: {
fulltext_highlight: function() {
return this.$store.state.fulltextHighlight
},
unparsed: function(){
return this.body.items.map(
function(item){
if (item.type_ == 'usage') return {type: item.type_, html: item.text}
else if (item.type_ == 'article_ref') return {
type: item.type_,
html: '',
label: item.lemmas.join(',') + (item.definition_order ? ` (${item.definition_order})` : ''),
ref: item.article_id + (item.definition_id ? '#def' + item.definition_id : ''),
article_id: item.article_id,
definition_id: item.definition_id
}
else if (item.type_ == 'pronunciation') return {type: item.type_, html: item.string}
else if (item.id) return {type: item.type_, html: entities[item.id] || languages[item.id] || item.id}
else return {type: item.type_ || 'plain', html: item}
try {
let lang = this.dictionary
let path = this.path
return this.body.items.map(
function(item){
if (item.type_ == 'usage') {
if (item.items) {
item.content = item.text
return {type: item.type_, html: '', tag: 'DefElement', props: {body: item, tag: 'i', dictionary: lang}}
}
else {
return {type: item.type_, html: item.text, tag: 'i'}
}
}
else if (item.type_ == 'article_ref') {
return {
type: item.type_,
html: '',
lemmas: item.lemmas,
link_text: item.word_form || item.lemmas[0].annotated_lemma || item.lemmas[0].lemma,
ref: '/' + lang + '/' + item.article_id + (item.definition_id ? '#def' + item.definition_id : ''),
article_id: item.article_id,
definition_id: item.definition_id,
definition_order: item.definition_order,
source: path
}
}
else if (item.type_ == 'pronunciation') return {type: item.type_, html: item.string}
else if (item.type_ == 'pronunciation_guide') return {type: item.type_, body: item, html: '', tag: 'DefElement', props: {body: item, tag: 'i', dictionary: lang}}
else if (item.type_ == 'superscript') return {type: item.type_, html: item.text, tag: 'sup'}
else if (item.type_ == 'subscript') return {type: item.type_, html: item.text, tag: 'sub'}
else if (item.type_ == 'quote_inset') return {type: item.type_, body: item, html: '', tag: 'DefElement', props: {body: item, tag: 'i', dictionary: lang}}
else if (item.type_ == 'fraction') return helpers.fraction(item.numerator, item.denominator)
else if (item.id) return {type: item.type_, html: (entities[lang][item.id] || {})['expansion'] || item.id}
else return {type: item.type_ || 'plain', html: item}
}
)
}
catch(error) {
this.$emit('error', {location: "unparsed", message: error.message} )
return {type: 'plain', html: item}
}
},
assemble_text: function(){
var old_parts = this.body.content.split(/(\$)/)
try {
var old_parts = this.body.content.split(/(\$)/)
var text_items = this.unparsed.slice(0).reverse()
var new_parts = []
old_parts.forEach(function(item){
......@@ -50,25 +112,77 @@ export default {
}
})
return new_parts
}
catch(error) {
this.$emit('error', {location: "assemble_text", message: error.message} )
return []
}
}
},
methods: {
article_link_click: function(item) {
this.$emit('article-click', item)
}
},
article_error: function(payload) {
this.$emit('error', payload)
},
roman_hgno: helpers.roman_hgno
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
span.usage, span.pronunciation {
.usage {
font-style: italic;
}
span.language {
font-weight: bold;
.pronunciation_guide {
font-size: smaller;
}
.numerator{
vertical-align: super;
padding-right: 2px;
font-size: smaller;
}
.denominator {
vertical-align: sub;
padding-left: 2px;
font-size: smaller;
}
mark {
background: rgba(255, 255, 255, 0);
color: inherit;
}
i {
font-style: normal;
}
.link_text {
text-decoration: underline;
}
.homograph, .def_order{
text-decoration: none !important;
color: black
}
q:before {
content: none;
}
q:after {
content: none;
}
</style>
<template>
<li class="definition" :ref="'def' + body.id" :id="'def' + body.id">
<ul>
<li :is="element_wrapper.template" :body="element_wrapper.element" v-for="(element_wrapper, index) in template_name_added" :key="index" @article-click="article_link_click">{{element_wrapper.element}}</li>
<li :class="['definition', 'level'+level]" :ref="level != 9 ? 'def' + body.id : ''" :id="level != 9? 'def' + body.id : ''">
<span v-if="level!=9"/>
<ul class="explanations">
<DefElement :body="explanation" :dictionary="dictionary" :has_article_ref=has_article_ref(explanation) v-for="(explanation, index) in explanations" :key="index" @article-click="article_link_click" />
</ul>
<div v-if="examples.length">
<h5 :lang="lang_tag_locale" v-if="level < 3">{{$t('article.headings.examples', content_locale)}}</h5>
<ul class="examples">
<Example :body="example" :dictionary="dictionary" v-for="(example, index) in examples" :key="index" @article-click="article_link_click" />
</ul>
</div>
<ul class="compound_lists">
<CompoundList :body="compound_list" :dictionary="dictionary" v-for="(compound_list, index) in compund_lists" :key="index" @article-click="article_link_click" />
</ul>
<div :is="level < 3 ? 'ol' : 'ul'" class="sub_definitions" v-if="subdefs.length">
<Definition :def_number='index+1' :level="level+1" :body="subdef" v-for="(subdef, index) in subdefs" :dictionary="dictionary" :key="index" @article-click="article_link_click" />
</div>
</li>
</template>
<script>
import DefElement from './DefElement.vue'
import Example from './Example.vue'
import SubArticle from './SubArticle.vue'
import CompoundList from './CompoundList.vue'
var Definition = {
name: 'Definition',
props: {
body: Object
body: Object,
level: Number,
dictionary: String,
def_number: Number
},
components: {
DefElement,
Definition,
Example,
SubArticle,
CompoundList
},
computed: {
template_name_added: function(){
return this.body.elements.map(
function(element){
return {
'template': {
'explanation': 'DefElement',
'definition': 'Definition',
'example': 'Example',
'sub_article': 'SubArticle',
'compound_list': 'CompoundList'
}[element.type_] || 'li',
'element': element
}
})
explanations: function() {
try {
return this.body.elements.filter(el => el.type_ == 'explanation')
} catch (error) {
this.$emit('error', {location: "explanations", message: error.message})
return []
}
},
examples: function() {
try {
return this.body.elements.filter(el => el.type_ == 'example')
} catch (error) {
this.$emit('error', {location: "examples", message: error.message})
return []
}
},
compund_lists: function() {
try {
return this.body.elements.filter(el => el.type_ == 'compound_list')
} catch (error) {
this.$emit('error', {location: "compound_lists", message: error.message})
return []
}
},
subdefs: function() {
try {
return this.body.elements.filter(el => el.type_ == 'definition').filter(def => def.elements.filter(el => el.type_ != 'sub_article').length > 0)
} catch (error) {
this.$emit('error', {location: "subdefs", message: error.message})
return []
}
// filtrerer bort definisjoner som bare inneholder underartikler
},
content_locale: function() {
return this.$parent.content_locale
},
lang_tag_locale: function() {
return this.$parent.lang_tag_locale
}
},
},
mounted: function() {
let ref = 'def' + this.body.id
if(location.hash.substring(1) == ref){
this.$refs[ref].scrollIntoView()
this.$refs[ref].classList.add('highlighted')
this.$refs[ref].scrollIntoView({block: 'center'})
this.$refs[ref].classList.add('highlighted')
}
},
methods: {
article_link_click: function(item) {
this.$emit('article-click', item)
},
has_article_ref: function(item){
if(item.items.length && item.items[0].type_ == "article_ref" && item.items[0].definition_id === undefined)
{
return "true";
}
else{
return "false";
}
}
},
watch:{
$route(to, from) {
let ref = 'def' + this.body.id
if (this.$refs[ref]) {
if(location.hash.substring(1) == ref){
this.$refs[ref].classList.add('highlighted')
}else {
this.$refs[ref].classList.remove('highlighted')
}
}
}
}
}
......@@ -58,12 +123,22 @@ var Definition = {
export default Definition
</script>
<style>
li.quote {
q {
font-style: italic;
}
.highlighted {
background-color: #ddddff;
border-radius: 5px;
.highlighted, mark {
background-color: var(--v-tertiary-darken1);
}
mark {
font-weight: bold;
}
li[has_article_ref="true"] {
margin-top: 8px;
margin-left: -25px;
}
</style>
<template>
<main tabindex="-1" ref="main" id="main" class="dict-container">
<span class="chosen_api" v-if="chosen_api">API: {{chosen_api}}</span>
<SearchForm ref="SearchForm"
v-on:submit="select_result"
v-on:update-lang-form="update_lang_form"
@updatePos="update_pos"
@updateScope="update_scope">
</SearchForm>
<div id="notifications"
v-if="$route.name && !error"
:class="$vuetify.breakpoint.name">
<div id="suggestions"
v-if="!article && !no_results">
<div class="search_notification"
v-if='inflection_suggestions && inflection_suggestions.length && this.queryString.slice(-1) != "."'>
<v-icon left
color="primary">info</v-icon><em>{{queryString}}</em> {{$t('notifications.inflected')}}<!--
--><span v-for="(item,index) in inflection_suggestions"
:key="index"><!--
--><router-link :to="generate_path({q: item[0]})"
@click.native="inflection_link(item[0])">{{item[0]}}</router-link><!--
-->{{index == inflection_suggestions.length-1? '.' : ', '}}</span>
</div>
<div class="search_notification"
v-if="lang=='bm,nn' && similar && similar.length > 0 && (search_results.nn && search_results.nn.length == 0)">
<v-icon left
color="primary">info</v-icon>{{$t('notifications.similar_nn')}}<!--
--><span v-for="(item,index) in similar"
:key="index"><!--
--><router-link :to="generate_path({q: queryString+'|'+item[0]})"
@click.native="other_dict(item[0])">{{item[0]}}</router-link><!--
-->{{index == similar.length-1? '.' : ', '}}
</span>
</div>
<div class="search_notification"
v-if="lang=='bm,nn' && similar && similar.length > 0 && (search_results.bm && search_results.bm.length == 0)">
<v-icon left
color="primary">info</v-icon>{{$t('notifications.similar_bm')}}<!--
--><span v-for="(item,index) in similar"
:key="index"><!--
--><router-link :to="generate_path({q: queryString+'|'+item[0]})"
@click.native="other_dict(item[0])">{{item[0]}}</router-link><!--
-->{{index == similar.length-1? '.' : ', '}}
</span>
</div>
</div>
<div id="return_to_results"
v-if="$vuetify.breakpoint.mdAndUp && article && $store.state.searchRoute">
<router-link id="return_link"
:to="$store.state.searchRoute"
@click.native="return_to_results()">
<v-icon left
class="nav_arrow">chevron_left</v-icon>{{$t("notifications.back")}}
</router-link>
</div>
<div class="no_results"
v-if="no_results && !error">
<div>
<p>
<v-icon left
color=primary>error</v-icon> <strong role="heading" aria-level="2" id="result0">{{no_results}}<span
v-if="pos_selected">{{$t('notifications.no_pos_results', {pos: $t('pos_tags_plural.'+pos_selected)})}}</span></strong>
</p>
<p class="below-notification" v-if="!article && inflection_suggestions && inflection_suggestions.length">
<em>{{this.queryString}}</em>{{$t('notifications.inflected')}}
<span v-for="(item,index) in inflection_suggestions"
:key="index"><!--
--><router-link :to="generate_path({q: item[0]})"
@click.native="inflection_link(item[0])">{{item[0]}}</router-link><!--
-->{{index == inflection_suggestions.length-1? '.' : ', '}}</span>
</p><p class="below-notification"
v-if="lang=='bm' && suggest_other_dict">{{$t('notifications.suggest_dict[1]')}}
<router-link :to="generate_lang_path('nn')"
@click.native="language_link('nn')">{{$t('dicts.nn')}}</router-link><!--
--></p>
<p class="below-notification"
v-if="lang=='nn' && suggest_other_dict">{{$t('notifications.suggest_dict[0]')}}<br>{{$t('notifications.suggest_dict[1]')}}
<router-link :to="generate_lang_path('bm')"
@click.native="language_link('bm')">{{$t('dicts_inline.bm')}}</router-link>
</p>
<div v-if="suggest_exact.length"
:class="'v-sheet v-card rounded-xl did_you_mean article ' + $vuetify.breakpoint.name">
<span class="similar-label" role="heading" aria-level="1">{{$t('notifications.similar')}}</span>
<v-list>
<template v-for="(item, index) in suggest_exact">
<v-list-item :key="index">
<router-link :to="generate_path({q: item[0], scope})"
@click.native="exact_link()">{{item[0]}}</router-link>
<span class="dict-parentheses"
v-if="lang=='bm,nn'">&nbsp;({{["bokmål","nynorsk","bokmål, nynorsk"][item[1]-1]}})</span>
</v-list-item>
</template>
</v-list>
</div>
<div v-if="suggest_fulltext.length"
:class="'v-sheet v-card rounded-xl did_you_mean article ' + $vuetify.breakpoint.name">
<span class="similar-label" role="heading" aria-level="1">{{$t('notifications.fulltext')}}</span>
<v-list>
<template v-for="(item, index) in suggest_fulltext">
<v-list-item :key="index">
<router-link :to="generate_path({q: item[0], scope: scope+'f'})"
@click.native="fulltext_link()">{{item[0]}}</router-link>
<span class="dict-parentheses"
v-if="lang=='bm,nn'">&nbsp;({{["bokmål","nynorsk","bokmål, nynorsk"][item[1]-1]}})</span>
</v-list-item>
</template>
</v-list>
</div>
<div v-if="similar && similar.length"
:class="'v-sheet v-card rounded-xl did_you_mean article ' + $vuetify.breakpoint.name">
<span class="similar-label" role="heading" aria-level="1">{{$t('notifications.similar')}}</span>
<v-list>
<template v-for="(item, index) in similar">
<v-list-item :key="index">
<router-link :to="generate_path({q: item[0]})"
@click.native="similar_link(item[0])">{{item[0]}}</router-link>
<span class="dict-parentheses"
v-if="lang=='bm,nn'">&nbsp;({{["bokmål","nynorsk","bokmål, nynorsk"][item[1]-1]}})</span>
</v-list-item>
</template>
</v-list>
</div>
</div>
</div>
</div>
<SearchResults :results_bm="search_results.bm || []"
:results_nn="search_results.nn || []"
:lang="lang"
:queryPattern="queryPattern"
:scope="scope"
@article-click="article_link_click"
@details-click="details_click"
@update-page="update_page"
v-if="$route.name && !article && !error && !no_results" />
<div id="spinner"
v-if="waiting">
<v-progress-circular indeterminate
color="secondary"
size="120"></v-progress-circular>
</div>
<div id="single_article_container"
v-if="article && !error && !no_results" :class="$store.state.searchRoute && $vuetify.breakpoint.mdAndUp && lang == 'bm,nn' ? article.dictionary : null">
<Article :key="article_key"
:article="article"
title_id="result0"
@article-click="article_link_click"
@details-click="details_click"
articleLookup/>
</div>
<div class="welcome-container" :class="$vuetify.breakpoint.name"
v-show="!error && ($route.name=='/' || !$route.name)">
<div class="welcome" :class="$vuetify.breakpoint.name">
<div class="monthly-title"><h2><span>{{$t('monthly')}}</span></h2></div>
<div class="monthly"
:class="$vuetify.breakpoint.name">
<div>
<Article :article="monthly_bm"
title_id="result0"
@article-click="article_link_click"
@details-click="details_click" />
</div>
<div>
<Article :article="monthly_nn"
title_id="result1"
@article-click="article_link_click"
@details-click="details_click" />
</div>
</div>
</div>
</div>
<div class="error"
v-if="error">
<div>
<h1 tabindex="0"
id="result0">{{error.title}}</h1>
<p>{{error.description}}</p>
</div>
</div>
<div v-if="$route.name && $route.name != 'lookup' && $store.state.currentLocale != 'ukr' && !$parent.waiting" class="betalink notification mx-auto mb-10"
centered
>
<div class="d-flex flex-column align-md-center flex-md-row mx-2">
<div class="shrink justify-top mr-8" cols="12" sm="6">
<img aria-hidden="true" width="96" height="96" src="https://test.ordbokene.no/favicon.ico">
</div>
<div>
<div v-if="$store.state.currentLocale == 'nob'">
<h2>Betaversjon</h2>
Vi har lansert en betaversjon av denne nettsiden med bedre søkeforslag og forslag til oversettelser mellom bokmål og nynorsk.<div class="mt-2"> <a :href="beta_search">Søk i betaversjonen</a><v-icon small color="white">launch</v-icon></div>
</div>
<div v-if="$store.state.currentLocale == 'nno'">
<h2>Betaversjon</h2>
Vi har lansert ein betaversjon av denne nettstaden med betre søkjeforslag og forslag til omsetjingar mellom bokmål og nynorsk. <div class="mt-2"><a :href="beta_search">Søk i betaversjonen</a><v-icon small color="white">launch</v-icon></div>
</div>
<div v-if="$store.state.currentLocale == 'eng'">
<h2>Beta version</h2>
We have launched a beta version of this website with better search suggestions and suggested translations between Bokmål and Nynorsk.<div class="mt-2"><a :href="beta_search">Search in the beta version</a><v-icon small color="white">launch</v-icon></div>
</div>
</div>
</div>
</div>
</main>
</template>
<script>
import axios from "axios"
import entities from '../utils/entities.js'
import Article from './Article.vue'
import SearchResults from './SearchResults.vue'
import SearchForm from './SearchForm.vue'
const ENDPOINTS = {
'oda_prod': process.env.VUE_APP_ODA_PROD,
'oda_dev': process.env.VUE_APP_ODA_DEV,
'odd_prod': process.env.VUE_APP_ODD_PROD,
'odd_dev': process.env.VUE_APP_ODD_DEV,
'ida_dev': process.env.VUE_APP_IDA_DEV,
'ida_prod': process.env.VUE_APP_IDA_PROD,
}
const ENDPOINT = ENDPOINTS[process.env.VUE_APP_ENDPOINT]
const FALLBACK_ENDPOINT = ENDPOINTS[process.env.VUE_APP_FALLBACK_ENDPOINT]
function navigate_to_article(self, origin) {
self.article = null
self.waiting_for_articles = true
const lang = self.$route.params.lang
self.api.get(lang + '/article/' + self.$route.params.id + ".json")
//self.api.get("https://httpstat.us/502")
.then(function(response){
self.article = Object.assign(response.data, {'dictionary': lang, results: self.search_results})
self.error = null
})
.catch(function(error){
self.handle_error(error, {retry: navigate_to_article, arg: origin, article: true})
})
.then(function(response){
self.waiting_for_articles = false
self.replace_history()
if (origin) self.$plausible.trackEvent(' incoming', {props: {origin}})
})
}
async function load_articles(self, query, offset, n, dict) {
let article_IDs = self.article_info.articles[dict]
if (article_IDs)
{
if (offset > article_IDs.length) {
n = 0
}
else if (offset + n > article_IDs.length) {
n = article_IDs.length % n
}
if (n > 0 && (self.lang == dict || self.lang == "bm,nn")) {
article_IDs = article_IDs.slice(offset, offset + n)
return Promise.all(article_IDs.map((article_id) => {
return self.api.get(`${dict}/article/${article_id}.json`)
//return self.api.get(`https://httpstat.us/502`)
}))
.then((response) => {
let results = response.map((element, index) => {
return Object.assign(element.data, {
dictionary: dict
})
})
self.article = null
self.search_results[dict] = results
})
.catch(error => {
self.handle_error(error, {})
})
}
else {
self.search_results[dict] = []
}
}
return Promise.resolve()
}
function navigate_to_query(self, word, keep_page) {
self.error = null
self.no_results = null
self.waiting_for_articles = true
self.inflection_suggestions = []
self.similar = []
self.suggest_fulltext = []
self.suggest_exact = []
self.suggest_other_dict = false
if (!self.event) {
self.event = {match: word}
}
let query = self.event
let q = query.match
let words = q.split(/ |\|/)
if (words.length > 20) {
self.no_results = self.$t('notifications.ignored_words')
self.waiting_for_articles = false
self.replace_history()
return
}
for (let i = 0; i < words.length; i++) {
if (words[i].length > 40) {
self.no_results = self.$t('notifications.ignored_chars')
self.waiting_for_articles = false
self.replace_history()
return
}
}
if (!keep_page) {
self.page = 1
}
let advanced_search = /[?_*%|]/.test(q)
// Get inflections
if (!advanced_search && self.$route.name == 'search') {
let params = {q, dict: self.lang, dform: 'int', include: "i", meta: 'n', wc: self.pos_selected}
self.api.get('api/suggest?', {params})
//self.api.get('https://httpstat.us/502')
.then((response) => {
self.inflection_suggestions = response.data.a.inflect && response.data.a.inflect.filter((item) => item[0][0] != "-" && item[0][item.length-1] != "-")
console.log(self.inflection_suggestions)
}).catch(error =>{
self.handle_error(error, {retry: navigate_to_query, arg: q})
self.replace_history()
})
}
// Get article IDs
let params = {w: query.match, dict: self.lang, scope: self.scope}
let offset = 0
if (self.page) {
offset = self.perPage * (self.page -1)
}
if (self.pos_selected) params.wc = self.pos_selected
self.api.get('api/articles?', {params}).then((response) => {
//self.api.get('https://httpstat.us/502', {params}).then((response) => {
self.article_info = response.data
self.search_results = {}
let bm_length = response.data.articles.bm ? response.data.articles.bm.length : 0
let nn_length = response.data.articles.nn ? response.data.articles.nn.length : 0
let total_length = bm_length + nn_length
let dict = self.lang
// Similar
if (bm_length == 0 || nn_length == 0) {
if (!advanced_search) {
if (dict == 'bm,nn' && total_length > 0) {
dict = bm_length == 0? 'bm' : 'nn'
}
let params = {q, dict, dform: 'int', include: "s", wc: self.pos_selected}
self.api.get('api/suggest?', {params})
//axios.get('https://httpstat.us/502')
.then((response) => {
if (self.suggest_exact && self.suggest_exact.length == 0) {
self.similar = response.data.a.similar
}
self.replace_history()
}).catch(error => {
self.handle_error(error, {retry: navigate_to_query, arg: q})
self.replace_history()
})
} else {
self.similar = []
}
}
if (total_length == 0) {
self.waiting_for_articles = false
self.no_results = self.$t('notifications.no_results')
let params = {q, dict, n: 2, dform: 'int', include: 'ef', wc: self.pos_selected}
self.api.get('api/suggest?', {params}).then((response) => {
if (response.data.a.exact && response.data.a.exact[0][0].toUpperCase() == q) {
console.log(response.data.a.exact)
self.suggest_exact = response.data.a.exact || []
self.suggest_fulltext = []
self.similar = []
}
else {
self.suggest_fulltext = response.data.a.freetext || []
self.suggest_exact = []
}
}).catch(error => {
self.handle_error(error, {retry: navigate_to_query, arg: q})
self.replace_history()
})
if (dict != 'bm,nn') {
let params = {q, n: 2, dict: dict=='bm'?'nn':'bm', dform: 'int', include: 'e', wc: self.pos_selected}
self.api.get('api/suggest?', {params}).then((response) => {
self.suggest_other_dict = response.data.cnt > 0 && response.data.a.exact[0][0] == q
}).catch(error => {
self.handle_error(error, {retry: navigate_to_query, arg: q})
self.replace_history()
})
}
self.replace_history() // fixes routing bug when going back from suggested search
}
else {
self.no_results = false
Promise.all([
load_articles(self, query, offset, self.perPage, "bm"),
load_articles(self, query, offset, self.perPage, "nn")
])
.then(() => {
self.waiting_for_articles = false
self.$store.commit('setSearchRoute', self.$route.fullPath)
self.replace_history()
})
}
}).catch(error =>{
self.handle_error(error, {retry: navigate_to_query, arg: q})
self.replace_history()
})
}
export default {
name: 'DictionaryView',
data: function() {
return {
api: null,
chosen_api: null,
fallback: false,
article_key: 0,
search_results: {},
lang: this.$store.state.defaultDict,
waiting_for_articles: true,
waiting_for_metadata: true,
article: null,
error: null,
no_results: false,
monthly_nn: null,
monthly_bm: null,
event: null,
scope: "ei",
pos_selected: "ALL",
article_info: null,
page: 1,
perPage: 10,
inflection_suggestions: null,
similar: null,
selected: null,
suggest_fulltext: [],
suggest_exact: [],
suggest_other_dict: false
}
},
computed: {
beta_search: function(){
const q = this.queryPattern
const advanced_search = this.scope.includes('f') || this.pos_selected || /[?_*%|]/.test(q)
const base = "https://beta.ordbokene.no/" + this.$i18n.locale
if (advanced_search) {
return `${base}/search?q=${q}&dict=${this.lang}&scope=${this.scope}${this.pos ? '&pos=' + this.pos : ''}`
}
else {
return `${base}/${this.lang}?q=${q}`
}
},
queryString: function() {
let q = this.$route.query.q || this.$route.params.q
return q ? q.trim() : ""
},
queryPattern: function() {
if (this.queryString) {
if (/[_%|]/.test(this.queryString)) {
return this.queryString.replaceAll(/[*%]/g, ".*").replaceAll(/[_?]/g, ".")
}
else {
return this.queryString
}
}
},
waiting: function() {
return (this.waiting_for_articles || this.waiting_for_metadata) && this.$route.name != 'root'
}
},
metaInfo() {
let advanced = /[?_*%|]/.test(this.queryString)
if (this.no_results || advanced || this.scope.includes("f")) {
return {meta: [{name: "robots", content: 'noindex'}]}
}
else if (!this.articleLookup) {
let title
let meta
let link = []
let q = ""
if (this.queryString) {
q = this.queryString + (this.lang == 'bm,nn' ? ' - ' : ' | ')
link = [{rel: "canonical", href: `https://ordbokene.no/${this.lang}/${this.queryString}`} ]
}
let desc = " viser skrivemåte og bøying i tråd med norsk rettskriving. Språkrådet og Universitetet i Bergen står bak ordbøkene."
if (this.lang == 'bm,nn') {
title = q+'ordbøkene.no'
meta = [{name: "description", vmid: 'description', content: "Bokmålsordboka og Nynorskordboka"+desc}]
}
if (this.lang == 'bm') {
title = q+"Bokmålsordboka"
meta = [{name: "description", vmid: 'description', content: "Bokmålsordboka"+desc}]
}
if (this.lang == 'nn') {
title = q+"Nynorskordboka"
meta = [{name: "description", vmid: 'description', content: "Nynorskordboka"+desc}]
}
return {title,
meta,
link}
}
},
components: {
Article,
SearchForm,
SearchResults
},
methods: {
load_welcome_and_metadata: function() {
let self = this
Promise.all([
self.api.get('bm/concepts.json').then(function(response){
let concepts = response.data.concepts
entities.bm = concepts
}),
self.api.get('nn/concepts.json').then(function(response){
let concepts = response.data.concepts
entities.nn = concepts
})
]).then(function(_) {
self.waiting_for_metadata = false
if (self.$route.name == 'search') {
if (self.queryString) {
navigate_to_query(self, self.queryString, true)
}
else {
self.$router.push( "/"+self.lang)
self.waiting_for_articles = false
self.replace_history()
self.load_monthly("bm")
self.load_monthly("nn")
}
}
else if(self.$route.name == 'word') {
self.scope = 'ei'
self.pos = null
navigate_to_query(self, self.queryString, true)
}
else if(self.$route.name == 'lookup'){
navigate_to_article(self, self.$route.path)
}
else {
self.waiting_for_articles = false
self.replace_history()
self.load_monthly("bm")
self.load_monthly("nn")
}
}).catch(function(error){
self.api = axios.create({baseURL: FALLBACK_ENDPOINT})
if (!self.error || !self.error.response) {
if (self.fallback) {
if (error.response) {
self.error = {title: self.$t('error.server.title'), description: self.$t('error.server.description', {code: error.response.status}), response: error.response}
}
else if (error.message == "Network Error") {
self.error = {title: self.$t('error.network.title'), description: self.$t('error.network.description')}
}
else {
self.error = {title: self.$t('error.generic.title'), description: self.$t('error.generic.description')}
}
self.waiting_for_metadata = false
self.waiting_for_articles = false
}
else {
self.fallback = true
self.load_welcome_and_metadata()
}
}
})
},
replace_history: function() {
history.replaceState({article: this.article,
search_results: this.search_results,
article_info: this.article_info,
lang: this.lang,
error: this.error,
no_results: this.no_results,
pos_selected: this.pos_selected,
scope: this.scope,
page: this.page,
perPage: this.perPage,
inflection_suggestions: this.inflection_suggestions,
similar: this.similar,
suggest_fulltext: this.suggest_fulltext,
suggest_exact: this.suggest_exact,
suggest_other_dict: this.suggest_other_dict}, '')
},
total_results: function() {
if (this.article_info) {
let total = 0
if (this.article_info.articles.bm) {
total += this.article_info.articles.bm.length
}
if (this.article_info.articles.nn) {
total += this.article_info.articles.nn.length
}
return total
}
},
load_monthly: function(dict) {
let self = this
this.api.get(dict + '/parameters.json').then(function(response) {
let front_article_id = response.data.front_article.value
self.api.get(dict + `/article/${front_article_id}.json`).then(function(response){
if (dict == "nn") {
self.monthly_nn = Object.assign(response.data, {dictionary: 'nn'})
}
else {
self.monthly_bm = Object.assign(response.data, {dictionary: 'bm'})
}
})
})
},
handle_error: function(error, retry_params) {
console.log(error)
this.waiting_for_articles = false
this.no_results = false
this.search_results = {}
this.inflection_suggestions = []
this.similar = []
this.suggest_fulltext = []
this.suggest_exact = []
this.suggest_other_dict = false
if (!this.chosen_api) {
this.api = axios.create({baseURL: FALLBACK_ENDPOINT})
}
if (!this.error || !this.error.response) {
if (this.fallback || !retry_params.retry) {
this.fallback = true
if (error.response) {
if (error.response.status == 404) {
if (retry_params.article) {
this.error = {title: this.$t('error.404.title'), description: this.$t('error.no_article', {id: this.$route.params.id}), article: true, response: error.response}
}
else {
this.error = {title: this.$t('error.404.title'), description: this.$t('error.404.description'), article: retry_params.article, response: error.response}
}
}
else if (error.response.status == 503) {
this.error = {title: this.$t('error.503.title'), description: this.$t('error.503.description'), article: retry_params.article, response: error.response}
}
else if (String(error.response.status)[0] == "5") {
this.error = {title: this.$t('error.server.title'), description: this.$t('error.server.description', {code: error.response.status}), article: retry_params.article, response: error.response}
}
else {
this.error = {title: this.$t('error.generic_code.title'), description: this.$t('error.generic_code.description', {code: error.response.status}), article: retry_params.article, response: error.response}
}
} else if (error.message == "Network Error") {
this.error = {title: this.$t('error.network.title'), description: this.$t('error.network.description'), article: retry_params.article, response: error.response}
}
else {
this.error = {title: this.$t('error.generic.title'), description: this.$t('error.generic.description'), article: retry_params.article, response: error.response}
}
} else {
this.fallback = true
retry_params.retry(this, retry_params.arg)
}
}
},
inflection_link: function (word) {
this.$plausible.trackEvent('inflection link', {props: {lang: this.previous.params.lang, from: this.previous.query.q, to: word}})
this.event = null
navigate_to_query(this, word)
},
other_dict: function(word) {
let lang = this.previous.params.lang
let from = this.previous.query.q
let to = word
this.$plausible.trackEvent('other dict', {props: {lang, from, to , words: lang+": "+from + " => " + to}})
this.event = null
navigate_to_query(this, this.queryString)
},
similar_link: function (word) {
let lang = this.previous.params.lang
let from = this.previous.query.q
let to = word
this.$plausible.trackEvent('similar link', {props: {lang, from, to , words: lang+": "+from + " => " + to}})
this.event = null
navigate_to_query(this, this.queryString)
},
fulltext_link: function () {
this.event = null
this.scope = this.scope + "f"
navigate_to_query(this, this.queryString)
},
exact_link: function () {
this.event = null
this.scope = this.scope + "ei"
navigate_to_query(this, this.queryString)
},
language_link: function (lang) {
this.lang = lang
this.event = null
navigate_to_query(this, this.queryString)
},
select_result: function (event) {
this.event = event
let path = `/${this.lang}/search`
let pos = this.pos_param()
let query = {q: event.match || event.q}
if (pos) query["pos"] = pos
if (this.scope) query["scope"] = this.scope
this.$router.push({path, query})
navigate_to_query(this)
// Tracking
let track_props = {query: event.q}
if (event.match) track_props.match = event.match
this.$plausible.trackEvent('dropdown selection', { props: track_props })
},
pos_param: function() {
if (this.pos_selected) return this.pos_selected.toLowerCase()
return null
},
update_page: function() {
this.waiting_for_articles = true
let q = this.queryString
let path = `/${this.lang}/search`
let pos = this.pos_param()
let query = {q: q, page: this.page}
if (pos != 'all') query.pos = pos
if (this.scope) query.scope = this.scope
if (this.perPage) query.perPage = this.perPage
this.$router.push({path, query})
let offset = 0
if (this.page) {
offset = this.perPage * (this.page -1)
}
let self = this
Promise.all([
load_articles(this, query, offset, this.perPage, "bm"),
load_articles(this, query, offset, this.perPage, "nn")]).then(() => {
self.replace_history()
self.$forceUpdate()
/*
// Debugging
if (self.page < Math.ceil(Math.max(self.article_info.articles.bm.length, self.article_info.articles.nn.length)/self.perPage)) {
self.page+=1
self.update_page()
}
*/
}
).then(() => {
this.$store.commit('setSearchRoute', this.$route.fullPath)
this.waiting_for_articles = false
})
},
generate_path: function(params) {
if (this.$route.name == "word") {
return this.$router.resolve({name: "search", query: {q: this.queryString, ...params}}).href
}
else {
return this.$router.resolve({query: {...this.queryString, ...params}}).href
}
},
generate_lang_path: function(dict) {
return this.$route.fullPath.replace(/\/(bm|nn|bm,nn)\//, "/"+dict+"/")
},
reload_params: function() {
let q = this.queryString
if (q) {
let path = `/${this.lang}/search`
let pos = this.pos_param()
let query = {q}
if (pos) query.pos = pos
if (this.scope) query.scope = this.scope
if (this.scope) query.scope = this.scope
if (this.perPage) query.perPage = this.perPage
this.$router.push({path, query})
navigate_to_query(this, q)
}
else {
this.$router.push({path: '/'+this.lang})
this.replace_history()
}
},
update_lang_form: function (lang) {
this.lang = lang
this.$store.commit("setDefaultDict", lang)
this.page = 1
},
update_scope: function(scope) {
this.scope = scope
if (this.$route.name && this.$route.name != 'lookup') {
this.page = 1
this.reload_params()
}
},
update_pos: function (pos) {
this.pos_selected = pos
if (this.$route.name && this.$route.name != 'lookup') {
this.page = 1
this.reload_params()
}
},
update_per_page: function(perPage) {
this.perPage = perPage
this.$store.commit('setPerPage', this.perPage)
this.page = 1
this.reload_params()
},
article_link_click: function(item) {
let event = window.event
if (!(event.ctrlKey || event.shiftKey || event.metaKey)) {
if (this.article && this.article.article_id == item.article_id){
this.article_key++
this.replace_history()
}else{
navigate_to_article(this, item.source)
}
}
},
details_click: function(item) {
let event = window.event
if (!(event.ctrlKey || event.shiftKey || event.metaKey )) {
this.article = item.article
this.replace_history()
}
},
return_to_results: function() {
this.article = null
this.replace_history()
},
set_fulltext_highlight: function() {
if (this.queryString && this.scope.includes("f")) {
let q = this.queryString
q = q.replace(/\*|%/, "[^\\s]*")
q = q.replace(/_|\?/, "[^\\s]")
this.$store.commit('setFulltextHighlight', q)
}
else {
this.$store.commit('setFulltextHighlight', false)
}
}
},
mounted: function(){
this.chosen_api = this.$route.query.api
if (this.chosen_api) {
this.api = axios.create({baseURL: ENDPOINTS[this.chosen_api]})
}
else {
this.api = axios.create({baseURL: ENDPOINT})
}
this.lang = this.$route.params.lang || this.$store.state.defaultDict || 'bm,nn'
if (this.$route.query.pos) {
this.pos_selected = this.$route.query.pos.toUpperCase()
} else this.pos_selected = null
if (this.$route.query.scope) {
this.scope = this.$route.query.scope
this.set_fulltext_highlight()
}
if (this.$route.query.page) this.page = parseInt(this.$route.query.page)
if (this.$route.query.perPage) {
this.perPage = parseInt(this.$route.query.perPage)
}
else {
this.perPage = parseInt(this.$store.state.perPage)
}
this.load_welcome_and_metadata()
},
watch: {
$route(to, from) {
this.previous = from
if (to.fullPath == "/") {
this.load_monthly("bm")
this.load_monthly("nn")
}
if (to.name == 'lookup' && from.fullPath == '/') {
this.$store.commit('setSearchRoute', null)
}
if (to.name == 'search') {
this.set_fulltext_highlight()
}
}
},
created: function() {
let self = this
window.onpopstate = function (event) {
if (event.state) {
if (event.state.lang) {
if (self.$refs.SearchForm.$refs.autocomplete.$refs.input == document.activeElement) {
self.$refs.SearchForm.$refs.autocomplete.$refs.input.select()
}
self.article = event.state.article
self.search_results = event.state.search_results
self.article_info = event.state.article_info
self.lang = event.state.lang
self.pos_selected = event.state.pos_selected
self.scope = event.state.scope
self.error = event.state.error
self.no_results = event.state.no_results
self.page = event.state.page,
self.perPage = event.state.perPage
self.inflection_suggestions = event.state.inflection_suggestions,
self.similar = event.state.similar,
self.suggest_fulltext = event.state.suggest_fulltext,
self.suggest_exact = event.state.suggest_exact,
self.suggest_other_dict = event.state.suggest_other_dict
if (!self.$route.hash && self.$route.name != 'search') {
history.scrollRestoration = 'manual'
window.scrollTo(0,0)
}
else {
history.scrollRestoration = 'auto'
}
}
else {
console.log("Navigation error")
}
}
}
}
}
</script>
<style>
.dict-container {
display: flex;
flex-flow: column;
height: 100%;
}
div.welcome-container.lg, div.welcome-container.md, div.welcome-container.xl {
background-image: url("../assets/background.jpg");
background-repeat: no-repeat;
background-position-x: center;
background-size: cover !important;
flex: 1 1 auto;
}
div.welcome.lg, div.welcome.md, div.welcome.xl {
padding-top: 10px;
margin-bottom: auto;
flex: 1 1 auto;
flex-direction: column;
}
div.welcome-container.sm {
background-position-y: -128px;
}
div.welcome-container.md {
background-position-y: -160px;
}
div.welcome-comtainer.lg {
background-position-y: -256px;
}
div.welcome-container.xl {
background-position-y: -512px;
}
div.welcome .article {
border-style: none;
}
#spinner {
margin: auto;
}
.dict-container>div, .dict-container>section, .welcome {
padding-left: calc((100vw - 1200px) / 2);
padding-right: calc((100vw - 1200px) / 2);
}
.dict-container>.welcome-container {
padding: 0 !important;
}
div.welcome {
padding-left: calc((100vw - 917px) / 2);
padding-right: calc((100vw - 917px) / 2);
}
#single_article_container {
box-shadow: 0px 3px 1px -2px rgb(0 0 0 / 20%), 0px 2px 2px 0px rgb(0 0 0 / 14%), 0px 1px 5px 0px rgb(0 0 0 / 12%);
background-color: white;
height: 100%;
}
#single_article_container.nn {
justify-content: flex-end !important;
display: flex;
}
#single_article_container.bm .article{
width: 50%;
}
#notifications .search_notification {
padding-top: 10px;
padding-bottom: 0px;
margin-left: 10px;
font-size: 18px;
}
#suggestions {
padding-left: 10px;
}
.error p, .no_results p {
margin-left: 15px;
}
.no_results {
padding-top: 24px;
}
.error div{
padding: 10px;
padding-top: 24px;
}
#spinner {
padding-top: 40px;
}
div.monthly {
display: flex;
width: 100%;
}
div.monthly > div {
flex: 50%;
}
div.monthly.sm, div.monthly.xs {
flex-direction: column;
}
.v-label span {
color: var(--v-primary-base);
}
.lang_select_container {
padding-left: 10px;
}
.pos_select_container {
padding-left: 10px;
padding-right: 10px;
padding-bottom: 0px;
padding-top: 10px;
}
li.suggestion {
font-weight: bold;
padding-left: 20px;
padding-top: 5px;
padding-bottom: 5px;
border: 0px;
background-image: none;
}
::selection {
background: var(--v-secondary-base);
color: white;
}
#return_to_results {
padding-left: 10px;
padding-top: 10px;
padding-bottom: 10px;
display: table-cell;
}
#return_to_results a {
color: var(--v-text-base) !important;
text-decoration: none;
}
.nav_arrow {
color: var(--v-primary-base) !important;
}
.col {
padding: 10px;
}
.below-notification {
padding-left: 10px;
}
.did_you_mean.md, .did_you_mean.lg, .did_you_mean.xl {
max-width: 40%;
}
.dict-parentheses {
color: rgba(0,0,0,0.6);
font-size: 85%;
}
.monthly-title {
text-align: center;
font-size: 1.17em;
color: var(--v-primary-base);
margin-bottom: 10px;
margin-top: 10px;
}
.monthly-title h2 {
display: flex;
width: 100%;
justify-content: center;
align-items: center;
text-align: center;
}
.xl .monthly-title h2, .lg .monthly-title h2, .md .monthly-title h2 {
padding-right: 10px;
padding-left: 10px;
}
.xl .monthly-title, .lg .monthly-title, .md .monthly-title {
background: linear-gradient(90deg, rgba(255,255,255,0) 10%, rgba(255, 255, 255, 0.75) 50%, rgba(255,255,255,0) 90%);
margin: 24px;
}
.monthly-title h2:after {
margin: 0 0 0 20px;
}
.xl .monthly-title, .lg .monthly-title, .md .monthly-title {
margin-top: 24px;
margin-bottom: 24px;
}
.xs .monthly-title h2:before,
.sm .monthly-title h2:before,
.xs .monthly-title h2:after,
.sm .monthly-title h2:after {
content: '';
margin: 0 24px 0 24px;
border-top: 2px solid;
flex: 1 0 0px;
color: var(--v-secondary-base);
}
.similar-label {
color: var(--v-primary-base) ;
font-weight: bold;
position: absolute;
padding-left: 10px;
top: 0;
font-variant-caps: all-small-caps;
font-size: 1.17em;
}
.chosen_api {
position: absolute;
top: 0px;
left: 0px;
color: white;
width: 100px;
}
.v-text-field--rounded > .v-input__control > .v-input__slot {
padding-left: 12px !important;
}
.betalink>div {
border-radius: 16px;
margin-top: 10px;
padding-left: 32px;
padding-right: 32px;
padding-top: 10px;
padding-bottom: 24px;
color: white;
background: black;
}
.betalink h2 {
font-variant: all-small-caps;
font-size: 2rem;
margin-bottom: 6px;
}
.betalink a {
color: white !important;
font-size: 1.25rem;
}
</style>
<template>
<li class="example">
<ul>
<DefElement :body="body.quote" :class="'quote'" @article-click="article_link_click" />
<DefElement :body="body.explanation" v-if="body.explanation" @article-click="article_link_click" />
</ul>
<DefElement tag="q" :body="body.quote" @article-click="article_link_click" :dictionary="dictionary" /><span v-if="body.explanation && body.explanation.content.length"></span>
<DefElement tag="span" :body="body.explanation" v-if="body.explanation && body.explanation.content.length" @article-click="article_link_click" :dictionary="dictionary" />
</li>
</template>
......@@ -13,7 +11,8 @@ import DefElement from './DefElement.vue'
export default {
name: 'Example',
props: {
body: Object
body: Object,
dictionary: String
},
components: {
DefElement
......
<template>
<span>
<v-btn v-if="$route.name!='about'" to="/om" small dark text>
<v-icon small left>info</v-icon>{{$t('menu.about')}}
</v-btn>
<v-btn v-if="$route.name=='about'" to="/" small dark text>
<v-icon small left>home</v-icon>{{$t('home')}}
</v-btn>
<v-dialog :fullscreen="$vuetify.breakpoint.smAndDown" max-width="800px" v-model="help_dialog">
<template v-slot:activator="{ on, attrs }">
<v-btn small dark text v-on="on" v-bind="attrs">
<v-icon small left>help</v-icon>{{$t('menu.help')}}
</v-btn>
</template>
<v-card>
<v-toolbar elevation="0" dark color="primary">
<v-toolbar-title>{{$t('menu.help')}}</v-toolbar-title><v-spacer></v-spacer>
<v-toolbar-items><v-btn @click.native="help_dialog=false" text>{{$t('close')}}<v-icon right>close</v-icon></v-btn></v-toolbar-items>
</v-toolbar>
<v-card-text class="text--primary">
<br>
<Help/>
</v-card-text>
</v-card>
</v-dialog>
<v-dialog :fullscreen="$vuetify.breakpoint.smAndDown" max-width="800px" v-model="settings_dialog">
<template v-slot:activator="{ on, attrs }">
<v-btn small dark text v-on="on" v-bind="attrs">
<v-icon small left>settings</v-icon><span>{{$t('settings.title')}}</span>
</v-btn>
</template>
<v-card>
<v-toolbar elevation="0" dark color="primary">
<v-toolbar-title><span role="heading" aria-level="1">{{$t('settings.title')}}</span></v-toolbar-title><v-spacer></v-spacer>
<v-toolbar-items><v-btn @click.native="settings_dialog=false" text>{{$t('close')}}<v-icon right>close</v-icon></v-btn></v-toolbar-items>
</v-toolbar>
<Settings/>
</v-card>
</v-dialog>
<v-dialog :fullscreen="$vuetify.breakpoint.smAndDown" max-width="800px" v-model="contact_dialog">
<template v-slot:activator="{ on, attrs }">
<v-btn small dark text v-on="on" v-bind="attrs">
<v-icon small left>mail</v-icon><span>{{$t('contact.title')}}</span>
</v-btn>
</template>
<v-card>
<v-toolbar elevation="0" dark color="primary">
<v-toolbar-title><span role="heading" aria-level="1">{{$t('contact.title')}}</span></v-toolbar-title><v-spacer></v-spacer>
<v-toolbar-items><v-btn @click.native="contact_dialog=false" text>{{$t('close')}}<v-icon right>close</v-icon></v-btn></v-toolbar-items>
</v-toolbar>
<Contact @close="contact_dialog = false"/>
</v-card>
</v-dialog>
</span>
</div>
</template>
<script>
import Help from './Help.vue'
import Contact from './Contact.vue'
import Settings from './Settings.vue'
export default {
name: "FooterMenu",
components: {
Help,
Contact,
Settings
},
data: function() {
return {
contact_dialog: false,
help_dialog: false,
settings_dialog: false
}
}
}
</script>
\ No newline at end of file
<!-- eslint-disable -->
<template>
<VueTooltipster :showClosebutton="false">
<h1>{{header_text}}</h1><span class="word-classification">{{group_list}}</span>
<div slot="content" class="tooltip">
<div v-for="(lemma, index) in lemmas" :key="index">
<h4>{{lemma.lemma}}</h4>
<table v-for="(std, index) in lemma.standardisations" :key="index">
<tr>
<th rowspan="2">{{std.tags ? std.tags.join(', ') : ''}}</th>
<th v-for="(inflection, index) in std.inflection" :key="index">{{inflection.tags.join(', ')}}</th>
</tr>
<tr>
<td v-for="(inflection, index) in std.inflection" :key="index">{{inflection.word_form}}</td>
</tr>
</table>
</div>
</div>
</VueTooltipster>
<div class="header">
<router-link v-if="$route.name != 'lookup'"
:id="title_id"
:to="$parent.link_to_self.ref"
@click.native="heading_click"
v-bind:class="{'long_lemma': long_lemma}"
class="article_header">
<HeaderTitle :lemma_groups="lemma_groups" :secondary_header_text="secondary_header_text"/>
</router-link>
<span v-else>
<HeaderTitle :lemma_groups="lemma_groups" :secondary_header_text="secondary_header_text"/>
</span>
<InflectionButton :lemmas="$parent.article.lemmas" :dictionary="dictionary" :article_id="$parent.article.article_id"/>
<SplitInf v-if="!$parent.collapsed" :lemmas="lemmas"/>
<p v-if="!lemma_groups[1] && $parent.collapsed && $parent.snippet && $parent.has_content" v-bind:class="{'under_inflection_button': !$store.state.inflectionExpanded}">
{{$parent.snippet}}
</p>
<span v-if="$parent.collapsable" >
<v-btn class="expand_icon" v-if="$parent.collapsed"
text
small
right
@click="$emit('toggle-collapse')">
{{$t('article.show')}}
<v-icon right>expand_more</v-icon></v-btn>
<v-btn class="expand_icon" v-else
text
small
@click="$emit('toggle-collapse')">
<v-icon small>expand_less</v-icon></v-btn>
</span>
</div>
</template>
<script>
/* eslint-disable */
import helpers from '../utils/helpers.js'
import VueTooltipster from './vue-tooltipster.vue'
import jQuery from 'jquery'
window.jQuery = jQuery
import SplitInf from './SplitInf.vue'
import InflectionButton from './InflectionButton.vue'
import HeaderTitle from './HeaderTitle.vue'
export default {
name: 'Header',
props: {
lemmas: Array
lemmas: Array,
dictionary: String,
article_id: Number,
title_id: String
},
data: function() {
return {
long_lemma: false
}
},
components: {
SplitInf,
InflectionButton,
HeaderTitle
},
mounted: function() {
if (this.$el.scrollWidth > this.$el.offsetWidth) {
this.long_lemma = true
}
},
methods: {
heading_click: function() {
this.$plausible.trackEvent('article head click', {props: {article: `${this.dictionary} ${this.article_id}`}})
this.$parent.details_click(this.$parent.link_to_self)
},
inflection_classes: function(lemmas) {
let inf_classes = new Set()
let ureg = false
lemmas.forEach((lemma, i) => {
if (lemma.inflection_class) inf_classes.add(lemma.inflection_class)
else ureg = true
})
if (inf_classes.size){
let class_array = Array.from(inf_classes).sort()
if (ureg) class_array.push("ureg.")
let class_list
if (class_array.length < 3) {
class_list = class_array.join(" og ")
}
else {
class_list = class_array.slice(0, -1).join(", ") + " og " + class_array[class_array.length -1]
}
return " ("+ class_list +")"
}
}
},
computed: {
header_text: function() {
return this.lemmas.map(
function(item){
return item.lemma
content_locale: function() {
return this.$parent.content_locale
},
lang_tag_locale: function() {
return this.$parent.lang_tag_locale
},
secondary_header_text: function() {
let a_forms = []
this.lemmas.forEach((lemma, i) => {
if (lemma.paradigm_info[0] && lemma.paradigm_info[0].inflection[1] && lemma.paradigm_info[0].inflection[1].tags[0] == 'Inf') {
let inf2 = lemma.paradigm_info[0].inflection[1].word_form
if (inf2 && inf2.length) {
a_forms.push(inf2)
}
}
});
return a_forms.join(', ')
},
hgno_arabic: function() {
let hgnos = []
this.lemmas.forEach(lemma => {
let hgint = parseInt(lemma.hgno)
if (hgint > 0) {
hgnos.push(hgint)
}
).join(', ')
})
return hgnos
},
group_list: function() {
return helpers.group_list(this.lemmas)
lemma_groups: function() {
let groups = [{lemmas: this.lemmas}]
try {
if (this.lemmas[0].paradigm_info[0].tags[0] == "DET" && this.lemmas[0].paradigm_info[0].tags.length > 1) {
groups = [{description: this.$t('tags.'+this.lemmas[0].paradigm_info[0].tags[0], this.content_locale), pos_group: ["Quant", "Dem", "Poss"].includes(this.lemmas[0].paradigm_info[0].tags[1]) ? this.$t('determiner.' + this.lemmas[0].paradigm_info[0].tags[1], this.content_locale) : '', lemmas: this.lemmas}]
}
else if (this.lemmas[0].paradigm_info[0].tags[0] == 'NOUN') {
let genus_map = {}
let self = this
this.lemmas.forEach(lemma =>{
let genera = new Set()
lemma.paradigm_info.forEach(paradigm => {
if (paradigm.tags[1]) {
genera.add(paradigm.tags[1])
}
})
let genus_description = ""
if (genera.size == 3) {
genus_description += self.$t('tags.Masc') + ', ' + self.$t('tags.Fem', self.content_locale) + self.$t('or') + self.$t('tags.Neuter', self.content_locale)
} else {
genus_description += Array.from(genera).map(code => self.$t('tags.'+code, self.content_locale)).sort().join(self.$t('or'))
}
if (genus_map[genus_description]) {
genus_map[genus_description].push(lemma)
}
else {
genus_map[genus_description] = [lemma]
}
})
groups = Object.keys(genus_map).map(key => {
return {description: self.$t('tags.NOUN', self.content_locale), pos_group: key, lemmas: genus_map[key], }
})
}
else if (this.lemmas[0].paradigm_info[0].tags[0] != 'EXPR') {
groups = [{description: this.$t('tags.'+this.lemmas[0].paradigm_info[0].tags[0], this.content_locale), lemmas: this.lemmas}]
}
groups.forEach((lemma_group, index) => {
groups[index]['inflection_classes'] = this.inflection_classes(lemma_group.lemmas)
})
} catch(error) {
console.log("lemma_groups",this.article_id, this.dictionary, '"'+error.message+'"')
this.$parent.invalid = true
//console.error(error)
}
},
components: {
VueTooltipster
return groups
},
}
}
</script>
<style>
.article h3 {
padding-top: 4px !important;
padding-bottom: 0px !important;
font-family: Inria Serif;
}
.article .sm h3, .article .xs h3, .long_lemma h3 {
font-size: 1.3em;
}
.sm .long_lemma, .xs .long_lemma h3 {
font-size: 1em;
}
.article h3 {
font-size: 1.5em;
}
h3 a {
text-decoration: none !important;
color: var(--v-primary-base) !important;
}
.article h1.secondary_header {
padding-top: 0px;
padding-bottom: 4px;
}
.info-button {
margin-left: 6px;
margin-right: -2px;
height: 10px;
width: 10px;
}
.word-classification {
text-decoration: underline dashed;
}
h1 {
display: inline;
div.lemma {
display: none;
}
.article_header {
overflow:auto;
word-wrap: normal;
text-decoration: none;
}
.hgno {
color: var(--v-text-base) !important;
font-family: unset;
font-size: 16px;
font-weight: normal;
}
.expand_icon {
justify-content: center;
position: absolute;
bottom: 0px;
left: 0px;
padding-right: 24px !important;
width: 100%;
border-bottom-right-radius: 28px;
border-bottom-left-radius: 28px;
}
.subheader {
color: var(--v-text-base);
font-weight: normal;
font-style: italic;
font-size: 14px;
padding-right: 10px;
}
.tooltip {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
color: #2c3e50;
.inflection_classes {
font-style: normal;
}
.tooltip table {
border-collapse: collapse;
margin: 10px;
.header_group_list {
font-variant: all-small-caps;
font-style: normal;
font-size: 18px;
}
.tooltip td, .tooltip th {
border: solid;
border-width: 1px;
margin: 0px 0px 0px 0px;
padding: 3px;
p.under_inflection_button {
padding-top:10px !important;
}
</style>
<template>
<span>
<span v-bind:class="{ 'lookup': $route.name=='lookup'}" v-for="(lemma_group, i) in lemma_groups" :key="i">
<h3>
<!--
--><span v-for="(lemma, index) in lemma_group.lemmas"
:key="index"><DefElement v-if="lemma.annotated_lemma" :body="lemma.annotated_lemma" tag="span"/><span v-else>{{lemma.lemma}}</span><!--
--><span v-if="lemma.hgno"
:aria-label="$t('accessibility.homograph') + parseInt(lemma.hgno)"
:title="$t('accessibility.homograph')+parseInt(lemma.hgno)"
class="hgno">{{" "+roman_hgno(lemma)}}</span><!--
--><span
class="title_comma"
v-if="lemma_group.lemmas[1] && index < lemma_group.lemmas.length-1">{{", "}}
</span>
</span>
</h3>
<h3 v-if="secondary_header_text">{{secondary_header_text}}</h3>
<span :lang="$parent.$parent.lang_tag_locale" v-if="lemma_group.description" class="subheader">
<span class="header_group_list">{{lemma_group.description}}</span>
{{lemma_group.pos_group}}
<span v-if="$store.state.showInflectionNo" class="inflection_classes">{{lemma_group.inflection_classes}}</span>
</span>
</span>
</span>
</template>
<script>
import helpers from '../utils/helpers.js'
import DefElement from './DefElement.vue'
export default {
name: 'HeaderTitle',
components: {
DefElement
},
props: {
lemma_groups: Array,
secondary_header_text: String
},
methods: {
roman_hgno: helpers.roman_hgno,
}
}
</script>
<template id="">
<div class='help' :class="$vuetify.breakpoint.name">
<div v-if="$store.state.currentLocale == 'nno'">
<p>Du søkjer ved å skrive inn ordet og trykkje på returtasten (<kbd>enter</kbd>) eller velje eit søkjeforslag i nedtrekksmenyen. Tast <kbd>Shift</kbd>+<kbd>7</kbd> dersom du vil hoppe tilbake til søkjefeltet etter å ha søkt.
Overskrifta i toppen av kvart søkjetreff er ei lenkje til ei ny artikkelside for det aktuelle ordet. Om du ikkje får meir enn eitt treff i kvar ordbok, viser heile artikkelen i resultatlista, og du treng ikkje trykkje på lenkja. Er det fleire treff, kan du òg sjå artikkelinnhaldet i resultatlista ved å trykkje på "Vis artikkel" i botnen av søkjetreffet. Sjå innstillingane nedanfor om du ønskjer at resultatlista alltid skal vise fullstendige artiklar.
</p><p>
Kva ordbok du får treff i, avheng av kva ordbok du har valt å søkje i, og om ordet blir brukt i begge skriftspråka. Det ligg per i dag ikkje inne koplingar mellom ordbøkene, men vi har utvikla ein meinte-du-funksjon, som vi håpar blir til hjelp for å finne dei riktige orda både i bokmål og nynorsk.</p>
<p>Du kan søkje direkte på faste uttrykk, t.d. <em>gi katten i</em>. Alternativt finn du uttrykka samla til slutt i artikkelen eller artiklane dei er knytte til. Når du skriv inn eit enkelt ord i søkjefeltet, viser nedtrekksmenyen òg dei faste uttrykka som ordet er ein del av.</p>
<h2>Søk med jokerteikn</h2>
<p>Dersom du er usikker på skrivemåten av eit ord eller ønskjer treff i meir
enn éin artikkel, kan du bruke <kbd>%</kbd> og <kbd>*</kbd> for å få treff på null, eitt eller fleire teikn.
Symbolet <kbd>_</kbd> erstattar berre eitt teikn. Du kan plassere jokerteikna fleire stader i søkjeordet.</p>
Døme:
<p>Søkjer du på «<a href="https://ordbokene.no/bm,nn/search?q=arbeid%2ar&scope=ei">arbeid*r</a>», er dei første treffa i nedtrekksmenyen «arbeider» i <em>Bokmålsordboka</em> og «arbeidar» i <em>Nynorskordboka</em>.</p>
<p>Søket «<a href="https://ordbokene.no/bm,nn/search?q=inter%25es%25ant&scope=ei">inter%es%ant</a>» gjev treff på «interessant» i begge ordbøkene. </p>
<p>Søket «<a href="https://ordbokene.no/bm,nn/search?q=f%C3%B8rsk%25l%C3%A6r_r&scope=ei">førsk%lær_r</a>» gjev treff på «førskolelærer» i <em>Bokmålsordboka</em> og «førskolelærar/førskulelærar» i <em>Nynorskordboka</em>.</p>
<p>Søket «<a href="https://ordbokene.no/bm,nn/search?q=ku__&scope=e">ku__</a>» gjev treff på ord på fire bokstavar som startar på «ku».</p>
<h2>Kombiner søkjeord</h2>
<p>Symbolet <kbd>|</kbd> gjer det mogleg å søkje med fleire søkjeord samtidig. Det er òg mogleg å kombinere søkjeord som inneheld jokerteikn.</p>
Døme:
<p>Søket «<a href="https://ordbokene.no/bm,nn/search?q=kj%C3%A6rlighet%7Ckj%C3%A6rleik&scope=ei">kjærlighet|kjærleik</a>» gjev treff på «kjærlighet» i <em>Bokmålsordboka</em> og «kjærleik» i <em>Nynorskordboka</em>.</p>
<p>Søket «<a href="https://ordbokene.no/bm,nn/search?q=undervis_r%7Cl%C3%A6r_r&scope=ei">undervis_r|lær_r</a>» gjev treff på «underviser» og «lærer» i <em>Bokmålsordboka</em> og «undervisar» og «lærar» i <em>Nynorskordboka</em>.</p>
</div>
<div v-if="$store.state.currentLocale == 'nob'">
<p>Du søker ved å skrive inn ordet og trykke på returtasten (<kbd>enter</kbd>) eller velge et søkeforslag i nedtrekksmenyen. Tast <kbd>Shift</kbd>+<kbd>7</kbd> hvis du vil hoppe tilbake til søkefeltet etter å ha søkt.
Overskriften i toppen av hvert søketreff er en lenke til en ny artikkelside for det aktuelle ordet. Hvis du ikke får mer enn ett treff i hver ordbok, vises hele artikkelen i resultatlisten, og du trenger ikke trykke på lenken. Er det flere treff, kan du også vise artikkelinnholdet i resultatlisten ved å trykke på "Vis artikkel" i bunnen av søketreffet. Se innstillingene nedenfor hvis du ønsker at resultatlisten alltid skal vise fullstendige artikler.
</p><p>
Hvilken ordbok du får treff i, avhenger av hvilken ordbok du har valgt å søke i, og om ordet blir brukt i begge skriftspråkene. Det ligger per i dag ikke inne koblinger mellom ordbøkene, men vi har utviklet en mente-du-funksjon, som vi håper blir til hjelp for å finne de riktige ordene både i bokmål og nynorsk.
</p><p>Du kan søke direkte på faste uttrykk, f.eks. <em>gi katten i</em>. Alternativt finner du uttrykkene samlet til slutt i artikkelen eller artiklene de er knyttet til. Når du skriver inn et enkelt ord i søkefeltet, viser nedtrekksmenyen også de faste uttrykkene som ordet inngår i.</p>
<h2>Søk med jokertegn</h2>
<p>Dersom du er usikker på skrivemåten av et ord eller ønsker treff i mer enn én artikkel, kan du bruke <kbd>%</kbd> og <kbd>*</kbd> for å få treff på null, ett eller flere tegn.
Symbolet <kbd>_</kbd> erstatter kun ett tegn. Du kan plassere jokertegnene flere steder i søkeordet.</p>
Eksempler:
<p>Søker du på «<a href="https://ordbokene.no/bm,nn/search?q=arbeid%2ar&scope=ei">arbeid*r</a>», er de første treffene i nedtrekksmenyen «arbeider» i <em>Bokmålsordboka</em> og «arbeidar» i <em>Nynorskordboka</em>.</p>
<p>Søket «<a href="https://ordbokene.no/bm,nn/search?q=inter%25es%25ant&scope=ei">inter%es%ant</a>» gir treff på «interessant» i begge ordbøkene. </p>
<p>Søket «<a href="https://ordbokene.no/bm,nn/search?q=f%C3%B8rsk%25l%C3%A6r_r&scope=ei">førsk%lær_r</a>» gir treff på «førskolelærer» i <em>Bokmålsordboka</em> og «førskolelærar/førskulelærar» i <em>Nynorskordboka</em>.</p>
<p>Søket «<a href="https://ordbokene.no/bm,nn/search?q=ku__&scope=e">ku__</a>» gir treff på ord på fire bokstaver som begynner med «ku».</p>
<h2>Kombiner søkeord</h2>
<p>Symbolet <kbd>|</kbd> gjør det mulig å søke med flere søkeord samtidig. Det er også mulig å kombinere søkeord som inneholder jokertegn.</p>
Eksempler:
<p>Søket «<a href="https://ordbokene.no/bm,nn/search?q=kj%C3%A6rlighet%7Ckj%C3%A6rleik&scope=ei">kjærlighet|kjærleik</a>» gir treff på «kjærlighet» i <em>Bokmålsordboka</em> og «kjærleik» i <em>Nynorskordboka</em>.</p>
<p>Søket «<a href="https://ordbokene.no/bm,nn/search?q=undervis_r%7Cl%C3%A6r_r&scope=ei">undervis_r|lær_r</a>» gir treff på «underviser» og «lærer» i <em>Bokmålsordboka</em> og «undervisar» og «lærar» i <em>Nynorskordboka</em>.</p>
</div>
<div v-if="$store.state.currentLocale == 'eng'">
<p>Search the website by entering a word, press <kbd>return</kbd> or pick a search suggestion in the drop-down menu. Press <kbd>/</kbd> whenever you want to jump back to the search box.
The heading of each search result is a link to a lookup page for the article in question. If you get no more than one result in each dictionary, the entire article is shown in the list of results, and you won't need to click the link. If there are more resutls, you may expand the article content in the results list by clicking "Show article" at the bottom of the result item. You can make the articles expand by default in the settings below.
</p><p>
The dictionary from which to get search results depends on the dictionary selected, and if the word is used in both written languages. Currently, the two dictionaries are not linked at word level. Thus a ‘Did you mean’ function has been developed. The hope is that this function will be helpful in finding the right words in both Bokmål and Nynorsk. It is possible to search for fixed expressions, e.g.
<em>gi katten i</em> (not give a damn). It is also possible to find such expressions at the end of each article or the articles they are linked to. When typing a single word in the search field, the drop-down menu also shows the common expressions the word is part of.
</p>
<h2>Wildcard search</h2>
<p>If unsure of the spelling of a word or want results from more than one article, it is possible to use <kbd>%</kbd> and <kbd>*</kbd> to replace zero, one or more characters.
Underscore (<kbd>_</kbd>) replaces only one character. You may use the wilcard symbols multiple times in your search expression.</p>
Examples:
<p>The search query “<a href="https://ordbokene.no/bm,nn/search?q=arbeid%2ar&scope=ei">arbeid*r</a>”, will result in results in the drop-down menu with “arbeider” (worker) in the Bokmål dictionary and “arbeidar” (worker) in the Nynorsk Dictionary.</p>
<p>The search query “<a href="https://ordbokene.no/bm,nn/search?q=inter%25es%25ant&scope=ei">inter%es%ant</a>” returns the result “interessant” (interesting) in both dictionaries. </p>
<p>The search query “<a href="https://ordbokene.no/bm,nn/search?q=f%C3%B8rsk%25l%C3%A6r_r&scope=ei">førsk%lær_r</a>” gives resutls for “førskolelærer” (pre-school teacher) in the Bokmål dictionary and “førskolelærar/førskulelærar” (pre-school teacher) in the Nynorsk dictionary.</p>
<p>The search query «<a href="https://ordbokene.no/bm,nn/search?q=ku__&scope=e">ku__</a>» returns four letter words starting with «ku».</p>
<h2>Combine search terms</h2>
<p>The symbol <kbd>|</kbd> allows you to use in several search words at the same time. You can also combine search words that contain wildcard symbols.</p>
Examples:
<p>The search “<a href="https://ordbokene.no/bm,nn/search?q=kj%C3%A6rlighet%7Ckj%C3%A6rleik&scope=ei">kjærlighet|kjærleik</a>” yields the result “kjærlighet” in the Bokmål dictionary and “kjærleik” (love) in the Nynorsk dictionary.</p>
<p>The search “<a href="https://ordbokene.no/bm,nn/search?q=undervis_r%7Cl%C3%A6r_r&scope=ei">undervis_r|lær_r</a>” results in “underviser” (teacher) and “lærer” (teacher) in the Bokmål dictionary and “undervisar” and “lærar” in the Nynorsk dictionary.</p>
</div>
<div v-if="$store.state.currentLocale == 'ukr'">
<p>Для пошуку введіть слово і натисніть кнопку <kbd>enter</kbd> або виберіть варіант пошуку у спадному меню. Натисніть <kbd>Shift</kbd>+<kbd>7</kbd>, якщо ви хочете повернутися до поля пошуку після виконання пошуку.
Заголовок у верхній частині кожного результату пошуку - це посилання на сторінку нової статті про це слово. Якщо ви не знайдете більше одного збігу в кожному словнику, вся стаття з’явиться у списку результатів, і вам не потрібно переходити за посиланням. Якщо результатів декілька, ви також можете переглянути вміст статті у списку результатів, натиснувши "показати статтю" внизу результату пошуку. Дивіться налаштування нижче, якщо ви хочете, щоб у списку результатів завжди випадали повні статті.
</p>
<p>
У якому словнику ви отримаєте збіги, залежить від того, який словник ви вибрали для пошуку,
і чи використовується це слово в обох письмових мовах. Наразі між словниками немає посилань,
але ми розробили для вас функцію, яка, сподіваємось, допоможе знайти потрібні слова як у <em>букмолі</em>,
так і в <em>нюношку</em>.
</p>
<p>
Ви можете здійснювати пошук безпосередньо за фіксованими виразами,
напр., <em>gi katten i</em> (не заморочуватись нічим або ніким).
Крім того, ви знайдете вирази разом у статті чи статтях, з якими вони пов’язані.
Коли ви вводите в поле пошуку одне слово, у спадному меню також показуються фіксовані вирази, до
яких входить це слово.
</p>
<h2>Пошук за допомогою символів підстановки</h2>
<p>Якщо ви не впевнені в написанні слова або хочете знайти збіги в більш ніж одній статті, ви можете використовувати <kbd>%</kbd> і <kbd>*</kbd> щоб отримати збіги від нуля, одного або декількох символів.
Символ <kbd>_</kbd> замінює лише один символ. Ви можете розмістити символи підстановки в декількох місцях ключового слова.</p>
Приклади:
<p>Пошук за запитом “<a href="https://ordbokene.no/bm,nn/search?q=arbeid%2ar&scope=ei">arbeid*r</a>” покаже у спадному меню результатів слова “arbeider” (працівник) у <em>Словнику букмола</em> і “arbeidar” (працівник) у <em>Словнику нюношка</em>.</p>
<p>Пошук “<a href="https://ordbokene.no/bm,nn/search?q=f%C3%B8rsk%25l%C3%A6r_r&scope=ei">førsk%lær_r</a>” надає результати за словом “førskolelærer” (вчитель дошкільної освіти) у <em>Словнику букмола</em> та “førskolelærar/førskulelærar” (вчитель дошкільної освіти) у <em>Словнику нюношка</em>.</p>
<p>Пошук “<a href="https://ordbokene.no/bm,nn/search?q=ku__&scope=e">ku__</a>” забезпечує відповідність словами з чотирьох букв, що починаються на “ku”.</p>
<h2>Поєднайте ключові слова</h2>
<p>Символ <kbd>|</kbd> дозволяє здійснювати пошук за кількома ключовими словами одночасно. Також можливо комбінувати ключові слова, що містять символи підстановки.</p>
Приклади:
<p>Пошук “<a href="https://ordbokene.no/bm,nn/search?q=kj%C3%A6rlighet%7Ckj%C3%A6rleik&scope=ei">kjærlighet|kjærleik</a>” надає результати за словом “kjærlighet” (любов) у <em>Словнику букмола</em> і “kjærleik” (любов) у <em>Словнику нюношка</em>.</p>
<p>Пошук “<a href="https://ordbokene.no/bm,nn/search?q=undervis_r%7Cl%C3%A6r_r&scope=ei">undervis_r|lær_r</a>” надає результати за словом “underviser” (навчання) та “lærer” (вчитель) у <em>Словнику букмола</em> і “undervisar” (навчання) та “lærar” (вчитель) у <em>Словнику нюношка</em>.</p>
</div>
</div>
</template>
<style scoped>
ul.bullet > li {
list-style: disc;
margin-left: 20px;
}
a {
text-decoration: none;
}
blockquote {
margin-left:50px;
}
kbd {
border-radius: 5px !important;
background-color: var(--v-tertiary-darken1) !important;
color: var(--v-text-base) !important;
}
</style>
<!-- eslint-disable -->
<template>
<span :is="$vuetify.breakpoint.smAndDown ? 'div' : 'span'" class="inflection-wrapper" v-if="inflected">
<v-btn :lang="$parent.$parent.lang_tag_locale" :aria-controls="'inflection-canvas'+$parent.title_id" :aria-expanded="inflection_expanded ? 'true' : 'false'" v-if="!($store.state.inflectionExpanded && $route.name)" class="show-inflection" small depressed rounded @click.native="toggle" :class="$vuetify.breakpoint.name">
<span :lang="$parent.lang_tag_locale">{{inflection_expanded? $t('article.hide_inflection', $parent.content_locale):$t('article.show_inflection', $parent.content_locale)}}</span><span class = "inflection-arrow"><v-icon small right>{{this.inflection_expanded? "remove" : "add"}}</v-icon></span>
</v-btn>
<div :id="'inflection-canvas'+$parent.title_id" class="inflection-canvas">
<inflectionTable v-if="inflection_expanded || always_expand" :eng="$store.state.currentLocale == 'eng'" :ukr="$store.state.currentLocale == 'ukr'" :lemmaList="lemmas_with_word_class_and_lang" :mq="$vuetify.breakpoint.name" :context="$store.state.inflectionTableContext" :key="$store.state.currentLocale + $store.state.inflectionTableContext"/>
</div>
</span>
</template>
<script>
/* eslint-disable */
import inflectionTable from 'inflection-table'
export default {
name: 'InflectionButton',
props: {
lemmas: Array,
dictionary: String,
article_id: Number
},
computed: {
lemmas_with_word_class_and_lang: function() {
return this.lemmas.map(lemma => Object.assign({language: this.dictionary == 'bm' ? 'nob' : 'nno',
word_class: lemma.paradigm_info[0].inflection_group.split('_')[0]}, lemma))
},
inflected: function() {
return this.lemmas.reduce((acc, lemma) => acc + lemma.paradigm_info.reduce((acc2, digm) => digm.inflection_group.includes("uninfl") ? acc2 : acc2 + digm.inflection.length, 0), 0) > this.lemmas.length
},
always_expand: function() {
return !this.$parent.$parent.collapsed && this.$store.state.inflectionExpanded && this.$route.name
}
},
components: {
inflectionTable
},
data: function() {
return {
inflection_expanded: false
}
},
methods: {
toggle: function() {
if (!this.inflection_expanded) {
this.$plausible.trackEvent('inflection click', {props: {article: `${this.dictionary} ${this.article_id}`}})
}
this.inflection_expanded = !this.inflection_expanded
}
},
}
</script>
<style>
.show-inflection .v-icon {
color: var(--v-primary-base) !important;
margin-left: 4px !important;
}
@keyframes open {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
div.show-inflection {
padding-top: 10px;
}
.inflection-canvas {
overflow-x: auto;
/*position: absolute;*/
z-index: 5;
background-color: rgba(255, 255, 255, 0);
/*max-width: 100vw;*/
}
.inflection-canvas > div {
padding-top: 10px;
padding-bottom: 10px;
}
.inflection-wrapper {
color: var(--v-text-base);
font-size: 14px;
margin-top: 10px;
}
.context {
color: #545454 !important;
}
div.lemma {
display: none;
}
table {
border-collapse: collapse;
margin-top: 5px;
}
th, td {
border: solid 2px var(--v-button-darken1);
padding: 5px;
}
th {
background-color: var(--v-button-base);
}
.infl-label {
text-align: center;
vertical-align: top;
}
td.hilite {
background-color: var(--v-tertiary-base);
text-align: center
}
</style>
<template>
<v-card>
<v-list>
<v-list-group prepend-icon="help">
<template v-slot:activator>
<v-list-item-title>{{$t('menu.help')}}</v-list-item-title>
</template>
<v-list-item><Help/></v-list-item>
</v-list-group>
<v-list-item link to="/om" v-on:click="$emit('close')">
<v-list-item-icon><v-icon>info</v-icon></v-list-item-icon>
<v-list-item-title>{{$t('menu.about')}}</v-list-item-title>
<v-list-item-icon><v-icon>chevron_right</v-icon></v-list-item-icon>
</v-list-item>
<v-list-group sub prepend-icon="language">
<template v-slot:activator>
<v-list-item-title>{{$t('settings.locale.title')}}</v-list-item-title>
</template>
<v-list-item>
<v-list subheader>
<v-radio-group v-model="updateLocale" :label="$t('settings.locale.description')">
<v-radio value="nob" label="Bokmål (nob)"></v-radio>
<v-radio value="nno" label="Nynorsk (nno)"></v-radio>
<v-radio value="eng" label="English (eng)"></v-radio>
<v-radio value="ukr" label="Українська (ukr)"></v-radio>
</v-radio-group>
</v-list></v-list-item>
</v-list-group>
<v-list-group v-if="false" prepend-icon="book">
<template v-slot:activator>
<v-list-item-title>{{$t('settings.dict.title')}}</v-list-item-title>
</template>
<v-list-item>
<v-list subheader>
<v-radio-group mandatory v-model="updateDefaultDict" :label="$t('settings.dict.description')">
<v-radio value="bm,nn" :label="$t('dicts.bm,nn')"></v-radio>
<v-radio value="bm" :label="$t('dicts.bm')"></v-radio>
<v-radio value="nn" :label="$t('dicts.nn')"></v-radio>
</v-radio-group>
</v-list></v-list-item>
</v-list-group>
<v-list-group prepend-icon="settings">
<template v-slot:activator>
<v-list-item-title>{{$t('settings.title')}}</v-list-item-title>
</template>
<v-list-item><Settings/></v-list-item>
</v-list-group>
<v-list-item v-if="!$store.state.unavailable" v-on:click='$store.commit("resetStore")'>
<v-list-item-icon><v-icon>delete</v-icon></v-list-item-icon>
<v-list-item-title>{{$t("settings.reset")}}</v-list-item-title>
</v-list-item>
<v-list-group prepend-icon="mail">
<template v-slot:activator>
<v-list-item-title>{{$t('contact.title')}}</v-list-item-title>
</template>
<v-list-item><Contact @close="$emit('close')"/></v-list-item>
</v-list-group>
</v-list>
</v-card>
</template>
<script>
import Settings from './Settings.vue'
import Help from './Help.vue'
import Contact from './Contact.vue'
export default {
name: "Menu",
components: {
Settings,
Help,
Contact
},
computed: {
updateLocale: {
get () { return this.$store.state.currentLocale},
set(value) {
this.$store.commit("setLocale", {value: value, i18n: this._i18n})
}
},
updateDefaultDict: {
get () { return this.$store.state.defaultDict},
set(value) {
this.$store.commit("setDefaultDict", value)
}
}
},
}
</script>
<template>
<div v-bind:class="{'centered': bottom}">
<span color="tertiary" class = "pagination">
<v-pagination @input="update" v-model="$parent.$parent.page" :class="$vuetify.breakpoint.name" :total-visible="$vuetify.breakpoint.smAndDown && !bottom ? 5 : 8" circle :length="Math.ceil(Math.max($parent.count_bm, $parent.count_nn)/$parent.$parent.perPage)"></v-pagination>
<span class="result-counts" v-if="!bottom && $vuetify.breakpoint.smAndDown">
<span class="total-results">{{$parent.$parent.total_results()}} treff </span>
<span v-if="$parent.$parent.lang=='bm,nn'" class="dict-counts"> | {{$vuetify.breakpoint.mdAndDown? 'bokmål': 'Bokmålsordboka'}}: {{$parent.count_bm}} | {{$vuetify.breakpoint.mdAndDown? 'nynorsk': 'Nynorskordboka'}}: {{$parent.count_nn}}</span>
<span v-if="$parent.$parent.lang!='bm,nn'" class="dict-counts"> | {{$t('dicts_inline.'+$parent.lang)}}</span>
</span>
</span>
<v-btn v-if="bottom && $parent.$parent.total_results() > 6" text @click.native="to_top"><v-icon left>expand_less</v-icon>{{$t('to_top')}}</v-btn>
</div>
</template>
<script>
export default ({
name: "Pagination",
props: {
bottom: Boolean
},
methods: {
update: function(item) {
if (this.bottom) {
this.to_top()
}
this.$emit('update-page', item)
},
to_top: function() {
let first = document.getElementById("result0")
if (first) first.focus();
window.scrollTo(0,0)
}
},
})
</script>
<style scoped>
.centered {
text-align: center;
padding-bottom: 10px;
}
.centered > span {
justify-content: center;
padding-bottom: 10px
}
</style>
\ No newline at end of file
<template>
<div :class="$vuetify.breakpoint.name">
<form @submit.prevent="submit">
<v-combobox
v-model="select"
prepend-inner-icon="search"
autocapitalize = 'off'
:loading="loading"
:items="items"
append-icon=""
:search-input.sync="search"
item-text="match"
:menu-props="{maxHeight: $vuetify.breakpoint.name === 'xs' ? 190 : 500, transition: 'fade-transition', allowOverflow: true}"
return-object
rounded
clearable
:autofocus="!$route.hash && !$store.state.noMouse && $vuetify.breakpoint.mdAndUp"
hide-no-data
no-filter
auto-select-first
hide-details
:label="$t('search_placeholder') + $t(`dicts.${$parent.lang}`)"
:aria-label="$t('search_placeholder') + $t(`dicts.${$parent.lang}`)"
solo
full-width
:placeholder="$t('search_placeholder') + $t(`dicts.${$parent.lang}`)"
ref="autocomplete"
color="primary"
:dense="$vuetify.breakpoint.mdAndDown"
>
<template v-slot:prepend-inner>
<v-menu allowOverflow offsetY v-model="dictMenuOpened">
<template v-slot:activator="{ on, attrs }">
<v-btn v-bind="attrs"
v-on="on"
plain
depressed
color = "primary"
text
@click.native="items=[]">
<v-icon left>book</v-icon>
<span v-if="$vuetify.breakpoint.mdAndUp">
{{$t(`dicts.${$parent.lang}`)}}
<v-icon right>{{ dictMenuOpened? 'expand_less' : 'expand_more'}}</v-icon>
</span><span v-if="$vuetify.breakpoint.smAndDown">{{$t(`dicts_short.${$parent.lang}`)}}</span></v-btn>
</template>
<v-list>
<v-list-item v-for="item in ['bm,nn','bm','nn'].map(l => {return {label: $t(`dicts.${l}`), tag: l}})" :key="item.tag"
active-class="v-list-item--active" @click="update_lang_form(item.tag)">
<v-list-item-icon v-if="$parent.lang == item.tag"><v-icon color="primary">radio_button_checked</v-icon></v-list-item-icon>
<v-list-item-icon v-else><v-icon>radio_button_unchecked</v-icon></v-list-item-icon>
<v-list-item-title >{{ item.label }}</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
<v-divider vertical aria-hidden="true"/><v-icon right>search</v-icon>
</template>
<template v-slot:item="data">
<span v-if="data.item.type == 'empty' || data.item.type == 0">
Søk: <strong>{{data.item.match}}</strong> </span>
<span v-if="data.item.type == 'exact'">
<span class="searchLemma">
<strong>{{data.item.match}}</strong>
</span>
<span class="dict-parentheses" v-if="(get_lang()=='bm,nn')">
({{["bokmål","nynorsk","bokmål, nynorsk"][data.item.lang-1]}})
</span>
</span>
<span v-if="data.item.type == 'other'">
{{data.item.match}} </span>
</template>
</v-combobox>
<SearchToolbar @updatePos="update_pos"
@updateScope="update_scope" />
</form>
</div>
</template>
<script>
import SearchToolbar from './SearchToolbar.vue'
export default {
data: function() {
return {
loading: false,
items: [],
search: null,
select: this.$parent.queryString || null,
suggesting: null,
menuDialog: false,
dictMenuOpened: false
}
},
components: {
SearchToolbar
},
watch: {
search (val) {
const time = Date.now()
if (! val) {
this.items = []
} else {
this.run_query(val, time)
}
},
select(item) {
if (item) {
if (typeof item != 'string') {
this.items = []
this.suggesting = false
this.submit(item)
}
}
},
$route (to, from) {
this.select = to.query.q || ""
}
},
methods: {
hotkey(e) {
if (e.key !== "/") return;
if (this.$store.state.disableHotkey) return
if (e.altKey || e.ctrlKey || e.metaKey) return;
if (/^(?:input|textarea|select)$/i.test(e.target.tagName)) return;
e.preventDefault()
this.$refs.autocomplete.$refs.input.focus()
},
update_lang_form(lang) {
this.$emit('update-lang-form', lang)
// Submit if switching on front page
if (this.search && this.search!=this.$parent.queryString && !this.items[0]) {
this.submit({q: this.search, match: this.search, time: Date.now()})
}
else {
this.$parent.reload_params()
}
},
update_scope(scope) {
this.$emit('updateScope', scope)
},
update_pos(pos) {
this.$emit('updatePos', pos)
},
get_lang() {
return this.$parent.lang
},
run_query(q, time) {
q = q.trim()
if (this.items[0]) {
if (this.items[0].time < time) {
// Whitespace necessary in case option already exists in dropdown
this.items.splice(0,1, {q, match: q, time, type: 0})
}
}
else {
this.items.push({q, match: q, time, type: 0})
}
let words = q.split(/ |\|/)
if (words.length > 20) {
this.items = [{q, match: q, time, type: 0}]
return
}
for (let i = 0; i < words.length; i++) {
if (words[i].length > 40) {
this.items = [{q, match: q, time, type: 0}]
return
}
}
this.suggesting = true
let self = this
let params = {q, dict: self.get_lang(), n: 20, dform: 'int', meta: 'n', include: this.$parent.scope, wc: self.$parent.pos_selected}
this.$parent.api.get('api/suggest?', {params})
.then(async (response) => {
if (self.$refs.autocomplete.searchInput == q & self.suggesting) {
let suggestions = []
if (response.data.a.exact) {
suggestions = response.data.a.exact.map(item => ({q: q, match: item[0], time: time, lang: [item[1]], type: "exact"}))
}
if (response.data.a.inflect) {
let inf = response.data.a.inflect.map(item => ({q: q, match: q, inflected: item[0], time: time, type: "other"}))
suggestions = suggestions.concat(inf)
}
if (response.data.a.freetext) {
let fr = response.data.a.freetext.map(item => ({q: q, match: item[0], time: time, type: "other"}))
suggestions = suggestions.concat(fr)
}
if (suggestions.length) {
if (suggestions[0].q.toLowerCase() != suggestions[0].match.toLowerCase()) {
suggestions.unshift({q, match: q, time, type: "empty"})
}
self.items = suggestions
}
else {
self.items = [{q, match: q, time, type: "empty"}]
}
}
})
},
submit(item) {
if (!item.q) {
item = this.items[0] || {q: this.search, match: this.search, time: Date.now() }
this.items = []
}
this.$emit('submit', item)
let self = this
setTimeout(() => {
if (!self.$store.state.noMouse && this.$vuetify.breakpoint.mdAndUp) self.$refs.autocomplete.$refs.input.select()
else self.$refs.autocomplete.$refs.input.blur()
self.suggesting = false
}, 1)
}
},
mounted: function() {
document.addEventListener("keydown", this.hotkey);
}
}
</script>
<style scoped>
.searchResult {
margin-right: 5px;
}
.searchLemma {
color: var(--v-primary-base);
}
form {
padding-left: 10px;
padding-right: 10px;
padding-top: 10px;
}
.accessibility_link {
display: inline;
position: absolute;
left: -10000px;
}
.accessibility_link:focus {
position: absolute;
left: 48px;
top : 48px;
background-color: white;
padding: 10px;
z-index: 10000;
}
</style>
<template>
<section class="">
<h2 v-if="hits.length">Søkeresultater</h2>
<ul>
<li v-for="(result, index) in extended_results" :key="index">
<router-link :to="result.id" @click.native="article_link_click(result.article)">
{{result.label}};
</router-link>
({{result.classification}})
</li>
</ul>
<section id="search_results" :class="$vuetify.breakpoint.name">
<div v-if="show_per_page" class="pagination-container">
<Pagination v-if="show_pagination" @update-page="$emit('update-page')"/>
<span id="per-page">
<span id="per-page-label">{{$t('per_page')}}</span>
<v-select class="per-page-select"
aria-labelledby="per-page-label"
v-model="$parent.perPage"
:items="[10, 20, 50, 100]"
@input="$parent.update_per_page"
hide-details
dense
:menu-props="{ offsetY: true }"
append-icon="expand_more"/>
</span>
</div>
<div class="flex-container" v-if="!$parent.waiting" :class="$vuetify.breakpoint.name">
<div class="hits" v-if="$vuetify.breakpoint.smAndDown">
<div class="article_container" v-for="(result, index) in results_bm.concat(results_nn)" :key="index + both_hash"
:style="'order:'+(index < results_bm.length? 2*index : ((index-results_bm.length)*2) + 1)">
<Article
:article="result"
:title_id="`result${index}`"
:queryPattern="queryPattern"
:scope="scope"
@article-click="article_link_click"
@details-click="details_click">
</Article>
</div>
</div>
<div class="hits" v-if="$vuetify.breakpoint.mdAndUp && lang!= 'nn'" v-bind:class="{'wide': lang=='bm'}">
<div class="dict-label-top"> <span role="heading" aria-level="2" class="dict-label-title"> bokmålsordboka </span><span v-if="count_bm != 1"> | <span v-if="count_bm == 0">{{$t('notifications.no_results')}}</span><span v-else>{{count_bm}} {{$t('notifications.results')}}</span></span></div>
<div class="article_container" v-for="(result, index) in results_bm" :key="index + bm_hash">
<Article
:article="result"
:title_id="`result${index}`"
:queryPattern="queryPattern"
:scope="scope"
@article-click="article_link_click"
@details-click="details_click">
</Article>
</div>
</div>
<div class="hits" v-if="$vuetify.breakpoint.mdAndUp && lang!='bm'" v-bind:class="{'wide': lang=='nn'}">
<div class="dict-label-top"> <span role="heading" aria-level="2" class="dict-label-title"> nynorskordboka </span><span v-if="count_nn != 1"> | <span v-if="count_nn == 0">{{$t('notifications.no_results')}}</span><span v-else>{{count_nn}} {{$t('notifications.results')}}</span></span></div>
<div class="article_container" v-for="(result, index) in results_nn" :key="index + nn_hash">
<Article
:article="result"
:title_id="`result${index + results_bm.length}`"
:queryPattern="queryPattern"
:scope="scope"
@article-click="article_link_click"
@details-click="details_click">
</Article>
</div>
</div>
</div>
<Pagination v-if="show_pagination && !$parent.waiting" @update-page="$emit('update-page')" bottom/>
<div>
</div>
</section>
</template>
<script>
import helpers from '../utils/helpers.js'
import Article from './Article.vue'
import Pagination from './Pagination.vue'
export default {
name: 'SearchResults',
props: {
hits: Array,
lang: String
results_bm: Array,
results_nn: Array,
lang: String,
meta: Object,
queryPattern: String,
scope: String
},
computed: {
extended_results: function(){
return this.hits.map(
function(hit){
return {
id: hit._id,
label: hit._source.lemmas.map(x => x.lemma).join(', '),
classification: helpers.group_list(hit._source.lemmas),
article: hit._source
}
})
}
both_hash: function(){
return this.results_bm.concat(this.results_nn).reduce((hash, hit) => (hash + hit.article_id) % 10000, 0)
},
bm_hash: function(){
return this.results_bm.reduce((hash, hit) => (hash + hit.article_id) % 10000, 0)
},
nn_hash: function(){
return this.results_nn.reduce((hash, hit) => (hash + hit.article_id) % 10000, 0)
},
count_bm: function(){
if (this.$parent.article_info.articles.bm ){
return this.$parent.article_info.articles.bm.length
}
else {
return 0
}
},
count_nn: function(){
if (this.$parent.article_info.articles.nn ){
return this.$parent.article_info.articles.nn.length
}
else {
return 0
}
},
show_pagination: function() {
return !this.$parent.article && this.$parent.article_info && (this.count_bm > this.$parent.perPage || this.count_nn > this.$parent.perPage)
},
show_per_page: function() {
return this.$parent.article_info && (this.count_bm > 10 || this.count_nn > 10) && !this.$parent.article
},
},
methods: {
article_link_click: function(item) {
this.$emit('search-hit-click', item)
}
this.$emit('article-click', item)
},
details_click: function(item) {
this.$emit('details-click', item)
},
},
components: {
Article,
Pagination
}
}
</script>
<style>
.article h3 {
color: var(--v-primary-base);
margin: 0px;
padding: 20px 0px 20px 0px;
}
.flex-container {
padding-top: 0px;
display: flex;
}
.flex-container.sm, .flex-container.xs {
padding-top: 0px;
}
.hits {
min-width: 50%;
}
.hits.wide {
min-width: 50%;
}
.flex-container.sm .hits, .flex-container.xs .hits {
min-width: 100%;
display: flex;
flex-direction: column;
}
.results-count {
color: var(--v-primary-base);
margin-left: 24px;
}
.pagination {
display: flex;
flex-wrap: wrap;
}
.total-results {
font-weight: bold;
color: var(--v-primary-base);
}
.result-counts {
padding: 10px;
justify-content: right !important;
}
.total-results, .dict-counts {
white-space: nowrap;
}
.pagination ul {
padding-inline-start: 0px !important;
justify-content: right;
}
#per-page {
padding-bottom: 10px;
padding-right: 10px;
margin-left: 10px;
display: flex;
flex-direction: row;
gap: 10px;
align-items: baseline;
}
.per-page-select {
max-width: 64px;;
}
.pagination-container {
margin-left: 10px;
padding-bottom: 10px;
display: flex;
flex-wrap: wrap;
gap: 10px;
align-items: center;
}
.lg .pagination-container, .xl .pagination-container {
padding-top: 10px;
}
.dict-label-title {
color: var(--v-primary-base) ;
font-weight: bold;
font-size: 24px;
font-variant-caps: all-small-caps;
}
.dict-label-top {
padding: 10px;
padding-left: 24px;
}
</style>
<template>
<div id="search_toolbar" :class="$vuetify.breakpoint">
<v-card v-if="$vuetify.breakpoint.smAndDown" rounded="xl" min-height="38px">
<v-list two-line v-if="expanded" id="settings-list">
<v-list-item>
<v-select
v-model="$parent.$parent.pos_selected"
hide-details
:menu-props="{ offsetY: true }"
:aria-label="$t('options.pos')"
:items="pos_items"
append-icon="expand_more"
@input="updatePos">
</v-select>
</v-list-item>
<v-list-item>
<v-checkbox
v-model="fulltext"
hide-details
:label="$t('options.fulltext')"/>
</v-list-item>
<v-list-item>
<v-checkbox
v-model="inflected_results"
hide-details=""
:label="$t('options.inflected')"/>
</v-list-item>
<v-list-item v-if="($route.name == 'search' || $route.name == 'word') && $store.state.collapseArticles != 'auto'">
<v-switch hide-details dense v-model="updateCollapse" :label="$t('options.collapse')"></v-switch>
</v-list-item>
</v-list>
<v-btn v-if="$vuetify.breakpoint.smAndDown"
class="search_options"
v-bind:class="{'expanded': expanded}"
height="38px"
rounded
text
@click="expanded=!expanded"
:aria-expanded="expanded ? 'true' : 'false'"
aria-controls="settings-list">
{{expanded? '' : $t('options.title')}}<v-icon small color="primary" :right="!expanded">{{expanded ? 'expand_less': 'expand_more'}}</v-icon></v-btn>
</v-card>
<div id="desktop_toolbar" v-else>
<span>
<v-checkbox
v-model="inflected_results"
dense
hide-details
:label="$t('options.inflected')"/>
</span>
<span>
<v-checkbox
v-model="fulltext"
dense
hide-details
:label="$t('options.fulltext')"/>
</span>
<span id="toolbar-pos-select">
<v-select
v-model="$parent.$parent.pos_selected"
hide-details
:menu-props="{ offsetY: true }"
dense
:aria-label="$t('options.pos')"
:items="pos_items"
append-icon="expand_more"
@input="updatePos">
</v-select>
</span>
<span id="display-options" v-if="($route.name == 'search' || $route.name == 'word') && $store.state.collapseArticles != 'auto'">
<v-switch v-model="updateCollapse" hide-details dense :label="$t('options.collapse')"></v-switch>
</span>
</div>
</div>
</template>
<script>
export default {
name: "SearchToolbar",
data: function() {
return {
expanded: false
}
},
computed: {
updateCollapse: {
get () { return this.$store.state.collapseArticles != "never"},
set(value) {
if (value) this.$store.commit("setCollapse", "always")
else this.$store.commit("setCollapse", "never")
}
},
inflected_results: {
get() {
return this.$parent.$parent.scope.includes("i")
},
set() {
if (this.$parent.$parent.scope.includes("i")) {
this.$emit('updateScope', this.$parent.$parent.scope.replace("i",""))
}
else {
this.$emit('updateScope', this.$parent.$parent.scope + "i")
}
}
},
fulltext: {
get() {
return this.$parent.$parent.scope.includes("f")
},
set() {
if (this.$parent.$parent.scope.includes("f")) {
this.$emit('updateScope', this.$parent.$parent.scope.replace("f",""))
}
else {
this.$emit('updateScope', this.$parent.$parent.scope + "f")
}
}
},
pos_items: function() {
let items = ["VERB", "NOUN", "ADJ", "PRON", "DET", "ADV", "ADP", "CCONJ", "SCONJ", "INTJ"].map(tag =>{
return {text: this.$t("pos_tags_plural." + tag ), value: tag}
})
items.unshift({text: this.$t('all_pos'), value: null})
return items
}
},
methods: {
reset () {
this.$emit('updatePos', "ALL")
this.$emit('updateScope', "ei")
},
updatePos (pos) {
this.$emit('updatePos', pos)
}
}
}
</script>
<style scoped>
.v-card {
padding-top: 0px !important;
padding-bottom: 24px !important;
padding-top: 10px;
margin-top: 10px;
min-height: 36px;
}
.v-list-item {
padding-left: 24px;
padding-right: 24px;
}
.search_options {
position: absolute;
min-height: 36px;
bottom: 0px;
left: 0px;
border-radius: 28px;
float: left;
width: 100%;
}
.search_options.expanded {
border-top-left-radius: 0px;
border-top-right-radius: 0px;
min-height: 24px;
}
#desktop_toolbar {
display: flex;
padding-left: 10px;
margin-right: 10px;
gap: 24px;
}
#search_toolbar {
margin-bottom: 10px;
}
.md#search_toolbar, .lg#search_toolbar, .xl#search_toolbar {
padding-top: 10px;
}
#desktop_toolbar v-combobox {
width: 300px;
}
#toolbar-pos-select {
max-width: 200px;
}
.v-input {
margin-top: 0px;
}
</style>
<template>
<div>
<v-list subheader>
<v-list-item>
<v-checkbox
v-model="toggleInflectionExpanded"
:label="$t('settings.inflection_expanded')"
hide-details>
</v-checkbox>
</v-list-item>
<v-list-item>
<v-checkbox
v-model="toggleInflectionNo"
:label="$t('settings.inflection_no')"
hide-details>
</v-checkbox>
</v-list-item>
<v-list-item>
<v-checkbox
v-model="disableHotkey"
:label="$t('settings.disable_hotkey')"
hide-details>
</v-checkbox>
</v-list-item>
<v-list-item>
<v-checkbox
v-model="toggleInflectionTableContext"
:label="$t('settings.inflection_table_context')"
hide-details>
</v-checkbox>
</v-list-item>
<v-list-item>
<v-radio-group mandatory two-line v-model="updateCollapse" :label="$t('settings.collapse.description')">
<v-radio value="auto" :label="$t('settings.collapse.auto')"></v-radio>
<v-radio value="always" :label="$t('settings.collapse.always')"></v-radio>
<v-radio value="never" :label="$t('settings.collapse.never')"></v-radio>
</v-radio-group>
</v-list-item>
</v-list>
</div>
</template>
<script>
export default {
name: "Settings",
computed: {
toggleInflectionNo: {
get () { return this.$store.state.showInflectionNo},
set () { this.$store.commit("toggleInflectionNo")
}
},
disableHotkey: {
get () { return this.$store.state.disableHotkey},
set () { this.$store.commit("disableHotkey")
}
},
toggleInflectionExpanded: {
get () { return this.$store.state.inflectionExpanded},
set () { this.$store.commit("toggleInflectionExpanded")
}
},
toggleInflectionTableContext: {
get () {
return this.$store.state.inflectionTableContext},
set () {
this.$store.commit("toggleInflectionTableContext")
}
},
updateCollapse: {
get () { return this.$store.state.collapseArticles},
set(value) {
this.$store.commit("setCollapse", value)
}
},
},
}
</script>