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 3727 additions and 1027 deletions
src/assets/background.jpg

451 KiB

File added
File added
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="64"
height="64"
viewBox="0 0 16.933333 16.933334"
version="1.1"
id="svg8"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
sodipodi:docname="logo-icon.svg"
inkscape:export-filename="/home/has022/Documents/256.png"
inkscape:export-xdpi="170.66667"
inkscape:export-ydpi="170.66667">
<defs
id="defs2">
<linearGradient
inkscape:collect="always"
id="linearGradient4545">
<stop
style="stop-color:#560027;stop-opacity:1;"
offset="0"
id="stop4541" />
<stop
style="stop-color:#560027;stop-opacity:0;"
offset="1"
id="stop4543" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4545"
id="linearGradient4547"
x1="9.9130554"
y1="277.94998"
x2="28.186945"
y2="277.94998"
gradientUnits="userSpaceOnUse" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:zoom="3.959798"
inkscape:cx="233.45423"
inkscape:cy="-7.9212896"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
units="px"
inkscape:window-width="3840"
inkscape:window-height="2084"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-280.06665)">
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:35.27777863px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#bc477b;fill-opacity:1;stroke:none;stroke-width:0.26458332"
x="1.4181669"
y="295.72998"
id="text3715"><tspan
sodipodi:role="line"
x="1.4181669"
y="295.72998"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:21.16666603px;font-family:'Inria Serif';-inkscape-font-specification:'Inria Serif';fill:#bc477b;fill-opacity:1;stroke-width:0.26458332"
id="tspan21">O</tspan></text>
</g>
</svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="144"
height="144"
viewBox="0 0 38.099999 38.100001"
version="1.1"
id="svg8"
inkscape:version="0.92.5 (2060ec1f9f, 2020-04-08)"
sodipodi:docname="anchor-icon.svg"
inkscape:export-filename="/home/has022/Documents/logo-transparent.png"
inkscape:export-xdpi="170.66667"
inkscape:export-ydpi="170.66667">
<defs
id="defs2">
<linearGradient
inkscape:collect="always"
id="linearGradient4545">
<stop
style="stop-color:#560027;stop-opacity:1;"
offset="0"
id="stop4541" />
<stop
style="stop-color:#560027;stop-opacity:0;"
offset="1"
id="stop4543" />
</linearGradient>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient4545"
id="linearGradient4547"
x1="9.9130554"
y1="277.94998"
x2="28.186945"
y2="277.94998"
gradientUnits="userSpaceOnUse" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:zoom="1.979899"
inkscape:cx="180.06393"
inkscape:cy="31.926411"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
units="px"
inkscape:window-width="3840"
inkscape:window-height="2084"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-258.89998)">
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:35.27777863px;line-height:1.25;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#bc477b;fill-opacity:1;stroke:none;stroke-width:0.26458332"
x="8.4772501"
y="288.745"
id="text3715"><tspan
sodipodi:role="line"
x="8.4772501"
y="288.745"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:31.75px;font-family:'Inria Serif';-inkscape-font-specification:'Inria Serif';fill:#bc477b;fill-opacity:1;stroke-width:0.26458332"
id="tspan21">O</tspan></text>
</g>
</svg>
File added
File added
File added
<template id="">
<main>
<main tabindex="-1" ref="main" id="main">
<div class='about' :class="$vuetify.breakpoint.name">
<v-radio-group class='about_lang' row v-model="lang" @change="update_locale">
<template v-slot:label tabindex="1">
</template>
<v-radio value="nb" color="primary">
<template v-slot:label>
<span>bokmål
</span>
</template>
</v-radio>
<v-radio value="nn" color="primary">
<template v-slot:label>
<span>nynorsk
</span>
</template>
</v-radio>
</v-radio-group>
<Article v-if="lang == 'nn'">
<h2>Om betaversjonen</h2>
<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 ei ny visningside for standardordbøkene <em>Bokmålsordboka</em> og <em>Nynorskordboka</em>. Sida er
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>
Dersom du vil søkje i ordbøkene med det gamle grensesnittet, finn du dei
framleis her: <a href="http://www.ordbok.uib.no/">ordbok.uib.no</a>.
</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å <a href="mailto:ordbok-beta@uib.no">ordbok-beta@uib.no</a>.
</p>
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>
<h3>Hjelp til søk</h3>
</summary>
<p>
Du søkjer ved å skrive inn ordet og trykkje på returtasten eller klikke på
det aktuelle ordet i nedtrekksmenyen. 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 arbeider med 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>gje 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>
<p>
Dersom du er usikker på skrivemåten av eit ord eller ønskjer treff i meir
enn éin artikkel, kan du bruke følgjande teikn:
</p>
<p>
<ul class="bullet">
<li>
% og * erstattar null, eitt eller fleire teikn
</li>
<li>
_ erstattar eitt teikn
</li>
<li>%, * og _ kan kombinerast for å erstatte eitt eller fleire teikn</li>
<li>| gjer det mogleg å søkje i fleire oppslagsord samstundes</li>
</ul>
</p>
Døme:
<p>
Søkjer du på «arbeid*r», er dei første treffa i nedtrekksmenyen <em>arbeider</em> i Bokmålsordboka og
<em>arbeidar</em> i Nynorskordboka.
</p>
<p>
Søket «inter%es%ant» gjev treff på <em>interessant</em> i begge ordbøkene.
</p>
<p>
Søket «førsk%lær_r» gjev treff på <em>førskolelærer</em> i <em>Bokmålsordboka</em> og
<em>førskolelærar</em>/<em>førskulelærar</em> i
Nynorskordboka.
</p>
<p>
Søket «kjærlighet|kjærleik» gjev treff i på <em>kjærlighet</em> i <em>Bokmålsordboka </em>og <em>kjærleik </em>i
<em>Nynorskordboka</em>.
Søket «undervis_r|lær_r» gjev treff på <em>underviser </em>og<em>lærer</em> i <em>Bokmålsordboka</em> og
<em>undervisar</em> og <em>lærar</em> i <em>Nynorskordboka</em>.
</p>
</details>
<details>
<summary>
<h3>Kva betyr det om du ikkje finn eit ord i ordboka?</h3>
<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 000 oppslagsord
og<em>Nynorskordboka </em>rundt 90 000, men etter <a href="https://www.uib.no/lle/revisjonsprosjektet">den
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
......@@ -120,8 +227,8 @@
<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>skogsarbeid</em>;
<em>sakførar</em>, men <em>saksbehandlar</em>;<em> osteklokke</em>, men<em> dørklokke</em>)</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
......@@ -153,13 +260,13 @@
</p>
<p>
Dersom du ikkje finn ordet du leitar etter, kan du sjekke dei større og
dokumenterande ordbøkene <a href="http://no2014.uib.no/"><em>Norsk Ordbok</em></a> (for dialektord
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>
<h3>Kvalitetssikra innhald</h3>
<h2>Kvalitetssikra innhald</h2>
</summary>
<p>
......@@ -177,7 +284,7 @@
<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/101277/norsk-kulturarv-i-skrift-og-tale">
<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
......@@ -192,7 +299,7 @@
</details>
<details>
<summary>
<h3>Sitere ordbøkene?</h3>
<h2>Sitere ordbøkene</h2>
</summary>
<p>
Innhaldet i <em>Bokmålsordboka</em> og <em>Nynorskordboka</em> er verna av
......@@ -209,17 +316,35 @@
</p>
<p>
«Korleis». I: <em>Nynorskordboka</em>. Språkrådet og Universitetet i
Bergen. &lt;<a href="http://xn--ordbkene-84a.no/">http://ordbøkene.no</a>
&gt; (henta 4.10.2021).
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>
<h3>Opne data</h3>
<h2>Opne data</h2>
</summary>
<p>
<em>Innhaldet i Bokmålsordboka</em>
......@@ -230,7 +355,7 @@
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
......@@ -246,7 +371,7 @@
</details>
<details>
<summary>
<h3>Historikk</h3>
<h2>Historikk</h2>
</summary>
<p>
<em>Bokmålsordboka</em>
......@@ -259,8 +384,8 @@
etymologiar.
</p>
<p>
<a href="https://www.uib.no/sites/w3.uib.no/files/attachments/om_ordbokene_0.pdf">
Her finner du fororda til dei trykte utgåvene
<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.
......@@ -272,7 +397,7 @@
</details>
<details>
<summary>
<h3>Revisjonsprosjektet</h3>
<h2>Revisjonsprosjektet</h2>
</summary>
<div>
<p>
......@@ -340,11 +465,443 @@
</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>
<h3>Nyttige språklenkjer</h3>
<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
......@@ -365,6 +922,7 @@
</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
......@@ -398,12 +956,12 @@
</li>
</ul>
</p>
<h4>
<h3>
Andre kvalitetssikra og fritt tilgjengelege ordbøker:
</h4>
<ul class="bullet">
</h3>
<p><ul class="bullet">
<li>
<a href="http://no2014.uib.no/perl/ordbok/no2014.cgi">Norsk Ordbok</a>
<a href="https://alfa.norsk-ordbok.no">Norsk Ordbok</a>
: Ordboka over det norske folkemålet og det nynorske skriftmålet
</li>
<li>
......@@ -417,7 +975,7 @@
vaksenopplæring
</li>
<li>
<a href="http://www.islex.no/">Islex</a>
<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>
......@@ -429,96 +987,108 @@
<a href="http://www.svenska.se/">svenska.se</a>
: fleire svenske ordbøker
</li>
</ul>
</ul></p>
</details>
</Article>
<Article v-if="lang == 'nb'">
<h2>Om betaversjonen</h2>
<p>Dette er en ny visningsside for 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>Dersom du vil søke i ordbøkene med det gamle grensesnittet, kan du fortsatt finne dem her: <a aria-label="Lenke til forelda versjon av ordbøkene" href="https://ordbok.uib.no/">ordbok.uib.no</a></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å <a aria-label="skriv e-post til Ordbøkene" href="mailto:ordbok-beta@uib.no">ordbok-beta@uib.no</a>. </p>
<details>
<summary><h3>Hjelp til søk</h3></summary>
<p>Du søker ved å skrive inn ordet og trykke på returtasten eller klikke på det aktuelle ordet i nedtrekksmenyen. 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 arbeider med en mente-du-funksjon, som vi håper blir til hjelp for å finne de riktige ordene både i bokmål og nynorsk.
Du kan søke direkte på faste uttrykk, f.eks. gi katten i. 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.
Dersom du er usikker på skrivemåten av et ord eller ønsker treff i mer enn én artikkel, kan du bruke følgende tegn:</p>
<p><ul class="bullet">
<li>% og * erstatter null, ett eller flere tegn</li>
<li> _ erstatter ett tegn </li>
<li>• %, * og _ kan kombineres for å erstatte ett eller flere tegn </li>
<li>| gjør det mulig å søke i flere oppslagsord samtidig</li>
</ul></p>
<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>
Eksempler:
<p>
Søker du på «arbeid*r», er de første treffene i nedtrekksmenyen arbeider i Bokmålsordboka og arbeidar i Nynorskordboka.
Søket «inter%es%ant» gir treff på interessant i begge ordbøkene.
Søket «førsk%lær_r» gir treff på førskolelærer i Bokmålsordboka og førskolelærar/førskulelærar i Nynorskordboka.
Søket «kjærlighet|kjærleik» gir treff på kjærlighet i Bokmålsordboka og kjærleik i Nynorskordboka. Søket «undervis_r|lær_r» gir treff på underviser og lærer i Bokmålsordboka og undervisar og lærar i Nynorskordboka.</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><h3>Hva betyr det om du ikke finner et ord i ordboka?</h3></summary><div>
<p><em>Bokmålsordboka</em> og <em>Nynorskordboka</em> er mellomstore nettordbøker. <em>Bokmålsordboka</em> har hatt rundt 65 000 oppslagsord og <em>Nynorskordboka</em> rundt 90 000, men etter <a href="http://www.uib.no/lle/revisjonsprosjektet">den revisjonen som pågår</a>
<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>skogsarbeid</em>; <em>sakefall</em>, men <em>sakesløs</em>; <em>sakfører</em>, men <em>saksbehandler</em>; <em>osteklokke</em>, men <em>dørklokke</em>)</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 aria-label="Lenke til informasjon om ordudvalget i ordbøkene" 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 aria-label="Lenke til Norsk Ordbok, ordboka over det norske folkemålet og det nynorske skriftmålet" href="http://no2014.uib.no/">Norsk Ordbok</a> (for dialektord og nynorsk) og <a aria-label="Lenke til NAOB, det Norske Akademis Ordbok´på bokmål og riksmål" href="https://naob.no/">NAOB</a> (for bokmål).</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><h3>Kvalitetssikret innhold</h3></summary><div>
<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 aria-label="Lenke til Språkrådet" 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/101277/norsk-kulturarv-i-skrift-og-tale">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>
<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><h3>Sitere ordbøkene</h3></summary><div>
<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 Bokmålsordboka eller Nynorskordboka, 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 4.10.2021).</p></blockquote>
Ø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><h3>Åpne data</h3></summary><div>
<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><h3>Opphavsrett</h3></summary><div>
<p>Innholdet i <em>Bokmålsordboka</em> og <em>Nynorskordboka</em> er beskyttet av opphavsrett, jf. lov om opphavsrett til åndsverk m.v. Det må ikke kopieres fra denne boken i strid med åndsverksloven eller avtale om kopiering inngått med Kopinor, interesseorgan for rettshavere til åndsverk. Kopiering i strid med lov eller avtale kan medføre erstatningsansvar og inndragning, og kan straffes med bøter eller fengselsstraff.</p>
<p>Ønsker du å sitere en artikkel i <em>Bokmålsordboka</em> eller <em>Nynorskordboka</em>, anbefaler vi å oppgi når artikkelen ble henta (lest), f.eks. slik:</p>
<blockquote>
<p>«Hvordan». I: <em>Bokmålsordboka</em>. Språkrådet og Universitetet i Bergen.<br>
‹http://ordbok.uib.no› (henta 4.12.2020).</p>
</blockquote>
<p>Begge eierne av ordboka, Språkrådet og Universitetet i Bergen, bør oppgis i referansen.</p>
<p><em>Bokmålsordboka</em> og <em>Nynorskordboka</em> ligger åpent tilgjengelig for nedlasting. De kan brukes til hvilke formål som helst, inkludert kommersielle, i samsvar med gitte vilkår. Les mer om den åpne lisensen <a aria-label="Lenke til informasjon om Lisensen til Ordbøkene" href="https://www.uib.no/ub/fagressurser/spesialsamlingene/142334/lisens-bokm%C3%A5lsordboka-og-nynorskordboka">her</a>.</p>
</div></details>
<details>
<summary><h3>Historikk</h3></summary><div>
<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 aria-label="Lenke til PDF med forordene til de trykte utgavene og annen informasjon om ordbøkene" href="https://www.uib.no/sites/w3.uib.no/files/attachments/om_ordbokene_0.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><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><h3>Revisjonsprosjektet</h3></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 aria-label="Lenke til informasjon om Revisjonsprojsektet" href="https://www.uib.no/lle/revisjonsprosjektet">nettsiden til Revisjonsprosjektet</a>.</p>
<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>
......@@ -543,34 +1113,736 @@ Søket «kjærlighet|kjærleik» gir treff på kjærlighet i Bokmålsordboka og
<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><h3>Nyttige språklenker</h3></summary><div>
<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>
<h4>Språkressurser på nettet</h4>
<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 aria-label="Lenke til Norsk ordbanks fullformslister for bokmål" 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 aria-label="Lenke til Norsk ordbanks i fullformslister for nynorsk" 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 aria-label="Lenke til Metaordboka, felles database over alle dokumenterte ord sortert på normert nynorsk oppslagsord" 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 aria-label="Lenke til Ordbokshotellet, elektronisk indeks med en rekke lokale ordsamlinger" 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 aria-label="Lenke til alle digitale språkressurser under språksamlingene" href="http://inger.uib.no/perl/search/search.cgi">Alle digitale språkressurser under språksamlingene</a></li>
</ul>
<p><a aria-label="Lenke til Språkrådet" href="http://www.sprakradet.no/">Språkrådet</a> har mange språkressurser samlet under menyen Språkhjelp, gå til <a aria-label="Lenke til nettsted for Språkrådets skriveregler" href="http://www.sprakradet.no/sprakhjelp/Skriveregler/">skriveregler</a>, <a aria-label="Lenke til Språkrådets nettsted for praktisk grammatikk" href="http://www.sprakradet.no/sprakhjelp/Praktisk-grammatikk/">praktisk grammatikk</a> eller <a aria-label="Lenke til skriveråd på Språkrådets nettsted" href="http://www.sprakradet.no/sprakhjelp/Skriverad/">skriveråd</a>.</p>
<p>Norsk ordbank ligger også tilgjengelig for nedlasting hos <a aria-label="Lenke til Språkbanken ved Nasjonalbiblioteket" 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>
<h4>Andre kvalitetssikrede og fritt tilgjengelige ordbøker</h4>
<ul class="bullet">
<li><a aria-label="Lenke til Norsk Ordbok, ordboka over det norske folkemålet og det nynorske skriftmålet" href="http://no2014.uib.no/perl/ordbok/no2014.cgi">Norsk Ordbok:</a> Ordboka over det norske folkemålet og det nynorske skriftmålet</li>
<li><a aria-label="Lenke til NAOB, det Norske Akademis Ordbok´på bokmål og riksmål" 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 aria-label="Lenke til LEXIN, ordbøker for minoritetsspråklige elever" href="http://lexin.udir.no/">LEXIN:</a> ordbøker for minoritetsspråklige elever i grunnskolen, videregående og voksenopplæring</li>
<li><a aria-label="Lenke til Islex, ordbok fra islandsk til nordiske språk" href="http://www.islex.no/">Islex:</a> ordbok fra islandsk til norsk (bokmål og nynorsk), svensk, dansk, færøysk og finsk</li>
<li><a aria-label="Lenke til ordnet.dk, nettsted med danske ordbøker og korpus" href="http://ordnet.dk/">ordnet.dk:</a> flere danske ordbøker og korpus</li>
<li><a aria-label="Lenke til svenska.se, nettsted med svenske ordbøker" href="https://svenska.se/">svenska.se:</a> flere svenske ordbøker</li>
<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>
</Article>
<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>
......@@ -578,33 +1850,15 @@ Søket «kjærlighet|kjærleik» gir treff på kjærlighet i Bokmålsordboka og
<script>
export default {
data() {
return {
lang: this.update_locale()
}
},
methods: {
update_locale: function(event) {
if (event) {
localStorage.setItem('locale', event)
return event
}
let stored_locale = localStorage.getItem('locale')
if (stored_locale) {
return stored_locale
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'} ]
}
if (navigator.languages.includes('nb')) {
return "nb"
}
return "nn"
}
}
}
</script>
<style scoped>
......@@ -619,14 +1873,13 @@ main {
}
.about {
padding-left: calc((100vw - 1000px) / 2);
padding-right: calc((100vw - 1000px) / 2);
padding-left: calc((100vw - 1200px) / 2);
padding-right: calc((100vw - 1200px) / 2);
}
h2, h3, h4, p{
h1, h2, h3, p{
padding: 3px;
font-variant: normal !important;
}
ul.bullet > li {
......@@ -645,10 +1898,15 @@ summary {
margin-bottom: 10px;
padding-bottom: 10px;
text-align: left;
border-bottom: solid 1px var(--v-border-base) !important;
}
blockquote {
margin-left:50px;
}
.ordbokene-icon {
width: 16px;
height: 16px;
}
</style>
<template>
<article v-if="article" :class="dictionary">
<Header :lemmas="article.lemmas" :dictionary="dictionary" :article_id="article.article_id" />
<div class="article_content" :class="$vuetify.breakpoint.name">
<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">
<h3>Uttale</h3>
<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" />
<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">
<h3>Opphav</h3>
<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" />
<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" tabindex="0">
<h3 tabindex="0">{{def_label}}</h3>
<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" />
<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">
<h3>Faste uttrykk</h3>
<h4 :lang="lang_tag_locale">{{$t('article.headings.expressions', content_locale)}}</h4>
<ul>
<SubArticle :body="subart" v-for="(subart, index) in sub_articles" :dictionary="dictionary" :key="index" @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>
<div class="fade">
<router-link class="choose" :to="link_to_self.ref" @click.native="details_click(link_to_self)">
Velg <v-icon large class="nav_arrow">arrow_right</v-icon>
</router-link>
</div>
</div>
<ArticleFooter :article="article"/>
</article>
<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 src="/dist/vue-social-sharing.js"></script>
<script>
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 = []
let sub_definitions = definition.elements.filter(el => el.type_ == 'definition')
sub_definitions.forEach((subdef, i) => {
sub_art_list = sub_art_list.concat(find_sub_articles(subdef))
})
let sub_articles = definition.elements.filter(el => el.type_ == 'sub_article' && el.lemmas)
sub_art_list = sub_art_list.concat(sub_articles)
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
}
function find_content(definition) {
let content_list = []
let sub_definitions = definition.elements.filter(el => el.type_ == 'definition')
sub_definitions.forEach((subdef, i) => {
content_list = content_list.concat(find_content(subdef))
})
let content_nodes = definition.elements.filter(el => ['explanation', 'example', 'compound_list'].includes(el.type_))
content_list = content_list.concat(content_nodes)
}
catch(error) {
console.log("find_sub_articles", this.article.article_id, this.dictionary, '"'+error.message+'"')
return content_list
return []
}
}
export default {
name: 'Article',
props: {
article: Object
article: Object,
articleLookup: Boolean,
title_id: String,
queryPattern: String,
scope: String,
},
computed: {
link_to_self: function() {
return {
ref: '/' + this.dictionary + '/' + this.article.article_id + '/' + encodeURIComponent(this.article.lemmas[0].lemma),
article: this.article
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
},
def_label: function() {
return this.dictionary == 'bob' ? 'Betydning og bruk' : 'Tyding og bruk'
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]
}
},
example_label: function() {
return this.dictionary == 'bob' ? 'Eksempel' : 'Døme'
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() {
return this.article.body.definitions.reduce((acc, val) => acc.concat(find_content(val)), []).length > 0
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: {
......@@ -106,11 +213,115 @@ export default {
Header,
ArticleFooter
},
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});
}
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)
}
}
......@@ -118,37 +329,43 @@ export default {
</script>
<style>
article {
.article {
position: relative;
padding: 24px;
margin: 10px;
border-radius: 30px;
border: solid 1px var(--v-border-base);
padding-bottom: 12px;
margin-bottom: 20px;
margin-right: 10px;
margin-left: 10px;
background-color: #ffffff;
}
#single_article_container article {
border: solid 2px var(--v-primary-base);
section.xs .article, section.sm .article {
margin-bottom: 10px !important;
}
.fade {
display: none;
section.md .article, section.lg .article, section.xl .article {
padding-top: 10px;
}
section {
padding-top: 1em;
.welcome .article_footer {
display: block;
}
h3 {
color: var(--v-primary-base);
font-variant: small-caps;
#single_article_container .article {
border: none;
margin-top: 10px;
}
section {
padding-top: 10px;
padding-bottom: 10px
}
section.etymology > h3, section.pronunciation > h3 {
section.etymology > h4, section.pronunciation > h4 {
display: inline;
font-size: 14px;
font-variant: revert;
}
section.etymology ul, section.pronunciation ul, section.etymology li, section.pronunciation li {
......@@ -211,13 +428,35 @@ ul li.definition {
list-style: disc;
}
.fade .nav_arrow {
vertical-align: sub;
}
.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;
}
......
<template>
<div class="article_footer">
<span v-if="hasPointer">
<button aria-label="Del ordboksartikkel på Facebook" class="share_button" tabindex="0">
<ShareNetwork network="facebook"
title=""
:url="share_link"
tabindex="-1">
<v-icon dense>$vuetify.icons.facebook</v-icon>
</ShareNetwork>
</button>
<button aria-label="Del del ordboksartikkel på Twitter" class="share_button" tabindex="0">
<ShareNetwork
network="twitter"
:url="share_link"
:title="dict_label"
hashtags="#ordbøkene"
tabindex="-1">
<v-icon dense>$vuetify.icons.twitter</v-icon>
</ShareNetwork>
</button>
</span>
<button v-if="webShareApiSupported" aria-label="Del ordboksartikkelen med andre" class="share_button" tabindex="0" @click="shareViaWebShare">
<span v-if="!hasPointer" class = "share_text">Del ordet</span>
<v-icon dense>$vuetify.icons.share</v-icon>
</button>
<div class = "footer_title" tabindex="0">Ordbøkene.no
</div>
<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>
......@@ -36,50 +64,112 @@ export default {
article: Object
},
computed: {
dict_label: function() { // TODO: reuse code used in header
return {
'bob': 'Fra bokmålsordboka',
'nob': 'Frå nynorskordboka'
}[this.article.dictionary] + ': ' + this.article.lemmas[0].lemma || ''
},
webShareApiSupported() {
return navigator.share
},
showLinkCopy() {
return (!navigator.share || this.$vuetify.breakpoint.mdAndUp) && navigator.clipboard
},
hasPointer() {
return window.matchMedia('(hover: hover) and (pointer: fine)').matches
},
share_link: function() {
let host = window.location.hostname === 'localhost'? 'https://dev.ordbok.uib.no/' : window.location.href
return host + this.article.dictionary + '/' + this.article.article_id + '/' + encodeURIComponent(this.article.lemmas[0].lemma)
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 + '/' + encodeURIComponent(this.article.lemmas[0].lemma)
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>
.share_text {
padding-right: 10px;
vertical-align: middle;
}
.v-icon {
color: var(--v-primary-base) !important;
}
.share_button {
padding-right: 4px;
font-weight: bold;
font-size: 14px;
.toolbar-button {
margin-right: 8px;
margin-top: 8px;
font-size: 12px;
}
......@@ -88,11 +178,11 @@ export default {
padding-top: 24px;
}
.footer_title {
font-family: Inria Serif;
font-weight: bold;
font-size: 18px;
float: right;
#citation {
margin-top: 12px;
padding: 12px;
background-color: var(--v-button-base) !important;
margin-bottom: 6px;
}
</style>
<template>
<div class="autocomplete-container" :class="$vuetify.breakpoint.name">
<v-combobox accesskey="s" aria-label="søkefelt"
v-model="select"
:loading="loading"
:items="items"
:search-input.sync="search"
item-text="label"
:menu-props="{maxHeight: $vuetify.breakpoint.name === 'xs' ? 190 : 500, transition: 'fade-transition', allowOverflow: true}"
prepend-inner-icon="search"
:append-icon="null"
return-object
rounded
hide-no-data
auto-select-first
no-filter
hide-details
label="Søk..."
solo
full-width
flat
outlined
placeholder="Søk her"
ref="autocomplete"
color="primary"
:dense="$vuetify.breakpoint.smAndDown"
>
<template v-slot:item="data">
<span class="search-hit">
{{data.item.label}}
</span>
({{{"b": "bm", "n": "nn", "bn": "bm, nn" }[data.item.lang] || ["søker...","ingen treff","avansert søk"][data.item.search]}})
</template>
<template slot="no-data">
<div></div>
</template>
</v-combobox>
</div>
</template>
<script>
export default {
props: {
api: Function,
},
data: function() {
return {
loading: false,
items: [],
search: null,
select: null,
suggesting: null,
}
},
watch: {
search (val) {
const time = Date.now()
if (! val) {
this.items = []
} else {
this.run_query(val, time)
}
},
select(item) {
if (item) {
this.items = []
if (typeof item != 'string') {
this.suggesting = false
this.submit(item)
}
}
}
},
methods: {
run_query(q, time) {
this.suggesting = true
// Search options while waiting for response
var search = 0
if (this.items[0]) {
if (this.items[0].time < time) {
if (/_|\*|\|/.test(q)) {
search = 2
}
// Whitespace necessary in case option already exists in dropdown
this.items.splice(0,1, {q: q, label: q +" ", time: time, search: search})
}
}
else {
this.items.push({q: q, label: q, time: time, search: search})
}
let self = this
self.api.get('suggest?', {params: {q: q, dict: self.$parent.lang, n: 80, scope: 'w', stage: self.$parent.stage}})
.then(async (response) => {
if (self.$refs.autocomplete.searchInput == q & self.suggesting) {
let suggestions = response.data.a.w.map(item => ({q: q, match: item[0], label: item[0], time: time, lang: item[1]}))
if (/_|\*|\|/.test(q)) {
suggestions.unshift({q: q, label: q, time: time, search: 2})
}
if (!suggestions.length) {
self.items = [{q: q, label: q, time: time, search: 1}]
} else {
self.items = suggestions
}
}
self.loading = false
})
},
submit(item) {
this.$emit('submit', item)
let self = this
setTimeout(() => {
self.$refs.autocomplete.$refs.input.select()
this.items = []
this.suggesting = false
}, 1)
}
},
}
</script>
<style scoped>
.search-hit {
font-weight: bold;
margin-right: 5px;
color: var(--v-primary-base);
}
.autocomplete-container {
padding-left: 10px;
padding-right: 10px;
}
</style>
......@@ -5,10 +5,10 @@
<li
:key="index"
v-for="(item, index) in body.elements"
><router-link
>{{' '}}<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>
>{{item.lemmas[0].lemma}}</router-link>
</li>
</ul>
</li>
......
<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>
......@@ -2,12 +2,19 @@
<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 v-if="item.type == 'article_ref'" :to="item.ref" @click.native="article_link_click(item)"><!--
-->{{item.link_text}}{{item.definition_order ? ` (${item.definition_order})` : ''}}<!--
--></router-link><!--
--><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><!--
......@@ -43,34 +50,58 @@ export default {
}
},
computed: {
fulltext_highlight: function() {
return this.$store.state.fulltextHighlight
},
unparsed: function(){
let lang = this.dictionary
let path = this.path
return this.body.items.map(
function(item){
if (item.type_ == 'usage') return {type: item.type_, html: item.text, tag: 'mark'}
else if (item.type_ == 'article_ref') return {
type: item.type_,
html: '',
link_text: item.word_form || item.lemmas[0].lemma,
ref: '/' + lang + '/' + item.article_id + '/' + encodeURIComponent(item.word_form || item.lemmas[0].lemma) + (item.definition_id ? '#def' + item.definition_id : ''),
article_id: item.article_id,
definition_id: item.definition_id,
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}
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){
......@@ -81,12 +112,23 @@ 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>
......@@ -123,8 +165,16 @@ i {
font-style: normal;
}
.homograph {
vertical-align: sub;
.link_text {
text-decoration: underline;
}
.homograph, .def_order{
text-decoration: none !important;
color: black
}
q:before {
......
<template>
<li :class="['definition', 'level'+level]" :ref="'def' + body.id" :id="'def' + body.id">
<ul class="explanations" tabindex="0">
<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" tabindex="0">
<h4>{{example_header}}</h4>
<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>
......@@ -12,8 +13,8 @@
<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" tabindex="0">
<Definition :level="level+1" :body="subdef" v-for="(subdef, index) in subdefs" :dictionary="dictionary" :key="index" @article-click="article_link_click" />
<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>
......@@ -28,7 +29,9 @@ var Definition = {
props: {
body: Object,
level: Number,
dictionary: String
dictionary: String,
def_number: Number
},
components: {
DefElement,
......@@ -38,26 +41,54 @@ var Definition = {
},
computed: {
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')
},
example_header: function() {
return this.dictionary == 'bob' ? 'Eksempel' : 'Døme'
} 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
return this.body.elements.filter(el => el.type_ == 'definition').filter(def => def.elements.filter(el => el.type_ != 'sub_article').length > 0)
},
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].scrollIntoView({block: 'center'})
this.$refs[ref].classList.add('highlighted')
}
},
......@@ -78,10 +109,12 @@ var Definition = {
watch:{
$route(to, from) {
let ref = 'def' + this.body.id
if(location.hash.substring(1) == ref){
this.$refs[ref].classList.add('highlighted')
}else{
this.$refs[ref].classList.remove('highlighted')
if (this.$refs[ref]) {
if(location.hash.substring(1) == ref){
this.$refs[ref].classList.add('highlighted')
}else {
this.$refs[ref].classList.remove('highlighted')
}
}
}
}
......@@ -94,18 +127,15 @@ q {
font-style: italic;
}
.highlighted {
.highlighted, mark {
background-color: var(--v-tertiary-darken1);
border-radius: 5px;
}
h4 {
color: var(--v-primary-base);
font-size: 14px;
padding-left: 12px;
padding-top: 6px;
mark {
font-weight: bold;
}
li[has_article_ref="true"] {
margin-top: 8px;
margin-left: -25px;
......
<template>
<main>
<div class="search_container">
<div class="lang_select_container">
<v-radio-group row v-model="lang" @change="update_lang_form">
<template v-slot:label tabindex="1">
<span aria-label="Vis resultat i begge ordbøkene eller bruk radioknapp for bokmålsordboka eller radioknapp for nynorskordboka">VIS</span>
</template>
<v-radio value="bob,nob" color="primary">
<template v-slot:label>
<span>
begge{{$vuetify.breakpoint.smAndDown ? '' : ' ordbøkene'}}
</span>
</template>
</v-radio>
<v-radio value="bob" color="primary">
<template v-slot:label>
<span>
{{$vuetify.breakpoint.xs ? 'bm' : 'bokmål (bm)'}}
</span>
</template>
</v-radio>
<v-radio value="nob" color="primary">
<template v-slot:label>
<span>
{{$vuetify.breakpoint.xs ? 'nn' : 'nynorsk (nn)'}}
</span>
</template>
</v-radio>
</v-radio-group>
<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>
<Autocomplete v-on:submit="select_result" :api="get_search_endpoint">
</Autocomplete>
<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>
<div id="spinner" v-if="waiting">
<v-progress-circular indeterminate color="secondary" size="120"></v-progress-circular>
<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>
<SearchResults :hits="search_results"
:lang="lang"
:key="lang"
@article-click="article_link_click"
@details-click="details_click"
v-if="search_results.length && ! waiting && ! article" />
<div id="single_article_container" v-if="article">
<div class="return_to_results" v-if="search_results && search_results.length">
<router-link :to="article.source" @click.native="return_to_results()">
<v-icon class="nav_arrow">arrow_left</v-icon>Tilbake til {{article.dictionary == 'bob' ? 'søkeresultater' : 'søkjeresultat'}}
</router-link>
</div>
<Article :key="article_key" :article="article" @article-click="article_link_click" />
<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" v-if="! (article || error || search_results.length || waiting)">
<div class="monthly" :class="$vuetify.breakpoint.name">
<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" @article-click="article_link_click" />
<Article :article="monthly_bm"
title_id="result0"
@article-click="article_link_click"
@details-click="details_click" />
</div>
<div>
<Article :article="monthly_nn" @article-click="article_link_click" />
<Article :article="monthly_nn"
title_id="result1"
@article-click="article_link_click"
@details-click="details_click" />
</div>
</div>
</div>
<div class="error" v-if="error">
<h1>Ingen treff</h1>
<p v-if="error[0]">{{error[0]}}</p>
<p v-if="error[1]">{{error[1]}}</p>
</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>
......@@ -72,159 +224,229 @@ import axios from "axios"
import entities from '../utils/entities.js'
import Article from './Article.vue'
import SearchResults from './SearchResults.vue'
import Autocomplete from './Autocomplete.vue'
import { setup } from 'axios-cache-adapter'
const SEARCH_ENDPOINT = process.env.VUE_APP_SEARCH_ENDPOINT
const ARTICLE_ENDPOINT= process.env.VUE_APP_ARTICLE_ENDPOINT
const API_STAGE = process.env.VUE_APP_API_STAGE
const dicts = {'nob': 'Nynorskorboka',
'bob': 'Bokmålsordboka',
'bob,nob': 'ordbøkene'}
const api = setup({
baseURL: SEARCH_ENDPOINT,
cache: {
maxAge: 15 * 60 * 1000,
exclude: {
query: false,
paths: ["articles"] // Disable caching for articles
}
}
})
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
function navigate_to_article(self, source) {
/*
if ((self.$route.query.nocache || '').toLowerCase() == 'true') {
config.headers.cachebuster = Date.now()
}*/
axios.get(ARTICLE_ENDPOINT + self.$route.params.lang + '/article/' + self.$route.params.id + ".json")
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': self.$route.params.lang, results: self.search_results})
self.search_results = []
self.article = Object.assign(response.data, {'dictionary': lang, results: self.search_results})
self.error = null
})
.catch(function(error){
if (error.response && error.response.status == 404) {
self.error = ["Vi har ingen artikkel med id " + self.$route.params.id]
} else {
self.error = []
if (self.lang !== 'bob') self.error.push(`Noko gjekk gale...`)
if (self.lang !== 'nob') self.error.push(`Noe gikk galt...`)
}
self.handle_error(error, {retry: navigate_to_article, arg: origin, article: true})
})
.then(function(response){
self.waiting_for_articles = false
history.replaceState({article: self.article, search_results: [], lang: self.lang, error: self.error}, '')
if (source) {
self.$plausible.trackEvent('internal link incoming', {props: {origin: source}})
}
self.replace_history()
if (origin) self.$plausible.trackEvent(' incoming', {props: {origin}})
})
}
/*
function navigate_to_search(self, query) {
axios.get(self.api_pref + 'search?q=' + query, { headers: {"x-api-key":"ZkYiyRVXxH86ijsvhx3cH4SY5Iik2ijI3BKVJGMm"}}) // API-key to be removed or reimplemented with a ci-variable with the new API
.then(function(response){
self.search_results = response.data
if (! self.search_results.length) {
self.error = `Søk på «${query}» gir ingen treff i ${dicts[self.lang]}. Søk med * inne i ordet dersom du er usikker på skrivemåten. Bruk knappen «begge ordbøkene» om du har søkt i feil ordbok.`
} else {
self.error = null
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
}
})
.catch(function(error){
self.articles = null
if (error.response && error.response.status == 400) {
self.error = "Søkeuttrykket inneholder feil"
} else if (error.response) {
self.error = "Noe gikk galt på serversiden"
} else {
self.error = "Nettverksproblemer, prøv igjen"
}
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()
})
}
})
.then(function(_){
self.waiting_for_articles = false
history.replaceState({article: self.article, search_results: self.search_results, lang: self.lang, error: self.error}, '')
})
}
*/
function navigate_to_query(self, word) {
let query = self.event ? self.event : {q: word}
// Get article IDs
api.get('articles?', {params: {w: query.match || query.q, dict: self.lang, scope: "w", stage: self.stage}}).then((response) => {
let article_ids = response.data
let unwrapped = []
for (const d in article_ids) {
article_ids[d].forEach(i => unwrapped.push({
dictionary: d,
id: i
}))
}
// Get individual articles
Promise.all(unwrapped.map((article) => {
return axios.get(`${ARTICLE_ENDPOINT}${article.dictionary}/article/${article.id}.json`)
}))
.then((response) => {
self.search_results = response.map((element, index) => {
return Object.assign(element.data, {
dictionary: unwrapped[index].dictionary
})
})
self.article = null
if (! self.search_results.length) {
if (query.match) {
self.error = []
if (self.lang !== 'bob') {
self.error.push(`Ordet «${query.match}» finst ikkje i Nynorskordboka. Bruk knappen «bokmål (bm)» om du har søkt i feil ordbok.`)
}
if (self.lang !== 'nob') self.error.push(`Ordet «${query.match}» finnes ikke i Bokmålsordboka. Bruk knappen «nynorsk (nn)» om du har søkt i feil ordbok.`)
} else {
self.error = [`Søk på «${query.q}» gir ingen treff i ${dicts[self.lang]}.`]
// If not advanced search
if (query.search != 2) self.error[0] += " Søk med * eller % dersom du er usikker på skrivemåten. Søketips kan du finne i «OM ORDBØKENE»."
if (self.lang == "bob") self.error[0] += ` Bruk knappen «nynorsk (nn)» om du har søkt i feil ordbok.`
if (self.lang == "nob") self.error[0] += ` Bruk knappen «bokmål (nn)» om du har søkt i feil ordbok.`
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 = []
}
}
}
else {
self.error = null
}
})
.catch(error => {
self.search_results = []
if (error.response) {
self.error = []
if (self.lang !== 'bob') self.error.push(`Noko gjekk gale på serversida`)
if (self.lang !== 'nob') self.error.push(`Noe gikk galt på serversiden"`)
} else {
self.error = []
if (self.lang !== 'bob') self.error.push(`Nettverksproblem, prøv igjen`)
if (self.lang !== 'nob') self.error.push(`Nettverksproblemer, prøv igjen`)
}
})
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
history.replaceState({
article: self.article,
search_results: self.search_results,
lang: self.lang,
error: self.error
}, '')
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()
})
}
......@@ -232,179 +454,652 @@ export default {
name: 'DictionaryView',
data: function() {
return {
api: null,
chosen_api: null,
fallback: false,
article_key: 0,
search_results: [],
lang: 'bob,nob',
search_results: {},
lang: this.$store.state.defaultDict,
waiting_for_articles: true,
waiting_for_metadata: true,
article: null,
error: null,
monthly_bm: null,
no_results: false,
monthly_nn: null,
monthly_bm: null,
event: null,
stage: API_STAGE
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: {
waiting: function() {
return (this.waiting_for_articles || this.waiting_for_metadata) && this.$route.name != 'root'
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() : ""
},
get_search_endpoint: function() {
return api
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,
Autocomplete,
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 name = event.search ? 'search' : 'w'
let route = `/${this.lang}/${name}/${event.match || event.q}`
this.$router.push(route)
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(event.update_lang ? "language" : 'dropdown selection', {
props: track_props
})
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
let name = null
let query = null
if(this.$route.name == 'word') {
name = "w"
query = this.$route.params.word
this.$router.push(`/${this.lang}/${name}/${query}`)
navigate_to_query(this, query)
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()
}
else if (this.$route.name == 'search') {
name = "search"
query = this.$route.params.query
this.$router.push(`/${this.lang}/${name}/${query}`)
navigate_to_query(this, query)
},
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) {
if (this.article && this.article.article_id == item.article_id){
this.article_key++
history.replaceState({article: this.article, search_results: this.search_results, lang: this.lang, error: this.error}, '')
}else{
this.article = null
this.waiting_for_articles = true
navigate_to_article(this, item.source)
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) {
item.article.source = this.$route.path
this.article = item.article
history.replaceState({article: this.article, search_results: [], lang: this.lang, error: null}, '')
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(){
let self = this
this.lang = 'bob,nob'
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})
}
Promise.all([
axios.get(ARTICLE_ENDPOINT + 'bob/concepts.json').then(function(response){
let concepts = response.data.concepts
entities.bob = concepts
}),
axios.get(ARTICLE_ENDPOINT + 'nob/concepts.json').then(function(response){
let concepts = response.data.concepts
entities.nob = concepts
})
]).then(function(_) {
self.waiting_for_metadata = false
if(self.$route.name == 'search') {
self.lang = self.$route.params.lang
navigate_to_query(self, self.$route.params.query)
}
else if(self.$route.name == 'word') {
self.lang = self.$route.params.lang
navigate_to_query(self, self.$route.params.word)
}
else if(self.$route.name == 'lookup'){
navigate_to_article(self, self.$route.path)
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")
}
else {
self.lang = self.$route.params.lang || 'bob,nob'
self.waiting_for_articles = false
history.replaceState({article: self.article, search_results: self.search_results, lang: self.lang, error: self.error}, '')
if (to.name == 'lookup' && from.fullPath == '/') {
this.$store.commit('setSearchRoute', null)
}
// words of the month
axios.get(ARTICLE_ENDPOINT + 'bob/article/5607.json').then(function(response){
self.monthly_bm = Object.assign(response.data, {dictionary: 'bob'})
})
axios.get(ARTICLE_ENDPOINT + 'nob/article/78569.json').then(function(response){
self.monthly_nn = Object.assign(response.data, {dictionary: 'nob'})
})
}).catch(function(_){
self.error = []
if (self.lang !== 'bob') self.error.push(`Eit nettverksproblem hindra lasting av sida. Prøv å laste sida på nytt`)
if (self.lang !== 'nob') self.error.push(`Et nettverksproblem hindret lasting av siden. Prøv å laste siden på nytt`)
self.waiting_for_metadata = false
self.waiting_for_articles = false
})
if (to.name == 'search') {
this.set_fulltext_highlight()
}
}
},
created: function() {
let self = this
window.onpopstate = function (event) {
if (event.state) {
self.article = event.state.article
self.search_results = event.state.search_results
self.lang = event.state.lang
self.error = event.state.error
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>
main {
flex: 1 0 auto;
background-color: var(--v-tertiary-base);
.dict-container {
display: flex;
flex-direction: column;
flex-flow: column;
height: 100%;
}
div.welcome {
flex-grow: 10;
background-image: url('../assets/books.jpg');
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 article {
div.welcome-comtainer.lg {
background-position-y: -256px;
}
div.welcome-container.xl {
background-position-y: -512px;
}
div.welcome .article {
border-style: none;
}
.search_container {
background-color: var(--v-tertiary-base);
padding-top: 1px;
padding-bottom: 10px;
#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;
}
#search_results, #spinner, #single_article_container, div.welcome, div.search_container, .error {
padding-left: calc((100vw - 1000px) / 2);
padding-right: calc((100vw - 1000px) / 2);
#single_article_container.bm .article{
width: 50%;
}
#notifications .search_notification {
padding-top: 10px;
padding-bottom: 0px;
margin-left: 10px;
font-size: 18px;
}
.error > p {
#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;
}
......@@ -422,17 +1117,7 @@ div.monthly.sm, div.monthly.xs {
flex-direction: column;
}
div.monthly article.bob .dict-label::before {
content: "fra ";
}
div.monthly article.nob .dict-label::before {
content: "frå ";
}
div.monthly details, div.monthly h3 {
display: none;
}
.v-label span {
color: var(--v-primary-base);
......@@ -442,6 +1127,13 @@ div.monthly details, div.monthly h3 {
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;
......@@ -456,17 +1148,130 @@ li.suggestion {
color: white;
}
.return_to_results {
#return_to_results {
padding-left: 10px;
padding-top: 10px;
padding-bottom: 10px;
display: table-cell;
}
.return_to_results a {
color: var(--v-primary-base) !important;
#return_to_results a {
color: var(--v-text-base) !important;
text-decoration: none;
}
.nav_arrow {
vertical-align: top !important;
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>
<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>
<div class = "header">
<span class="dict-label" tabindex="0">{{dict_label}}</span>
<h2 class="article_header" tabindex="0">{{header_text}}</h2>
<h2 class="secondary_header" v-if="secondary_header_text.length" tabindex="0">{{secondary_header_text}}</h2>
<span class="header_group_list" v-if="group_list.length" tabindex="0">{{group_list}}</span>
<span v-if="split_inf" tabindex="0"> (kløyvd infinitiv: <i>-a</i>
<v-menu rounded="0" v-model="menu" offset-x max-width="200px">
<template v-slot:activator="{ on, attrs }">
<v-btn aria-label="Mer informasjon om kløyvd infinitiv" x-small icon v-on="on" v-bind="attrs" class="info-button">
<v-icon color="primary" size="14px">$vuetify.icons.value.info</v-icon>
</v-btn>
</template>
<v-card rounded="0" class="info-card">
Dersom du bruker kløyvd infinitiv, skal dette verbet ha <i>-a</i> i infinitiv. Les meir
<a target="_blank" href="https://www.sprakradet.no/svardatabase/sporsmal-og-svar/kloyvd-infinitiv-/">her</a>.
</v-card>
</v-menu>)
<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>
<details :title="inflect_tooltip" @toggle="toggle()" v-if="inflected" :class="$vuetify.breakpoint.name">
<summary :class="dictionary" onclick="this.blur()" tabindex="0">bøying</summary>
<div class="inflection-canvas">
<inflectionTable :lemmaList="lemmas_with_word_class_and_lang" :mq="$vuetify.breakpoint.name" />
</div>
</details>
<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 inflectionTable from 'inflection-table'
import SplitInf from './SplitInf.vue'
import InflectionButton from './InflectionButton.vue'
import HeaderTitle from './HeaderTitle.vue'
export default {
name: 'Header',
props: {
lemmas: Array,
dictionary: String,
article_id: Number
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(lemma => lemma.lemma).join(', ')
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_group == 'VERB') {
let inf2 = lemma.paradigm_info[0].inflection[1] && lemma.paradigm_info[0].inflection[1].word_form
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)
}
......@@ -58,58 +114,66 @@ export default {
});
return a_forms.join(', ')
},
inflect_tooltip: function() {
return this.dictionary == 'bob' ? 'Klikk for å se bøyinger' : 'Klikk for å sjå bøyingar'
},
dict_label: function() {
return {
'bob': 'bokmålsordboka',
'nob': 'nynorskordboka'
}[this.dictionary] || ''
},
group_list: function() {
return helpers.group_list(this.lemmas, this.dictionary)
},
inflection_groups_by_lemma: function() {
let components = Object.keys(this.$options.components)
return this.lemmas.map(
function(lemma_){
let inflection_groups = lemma_.paradigm_info.reduce((acc, std) => Object.assign(acc, {[std.inflection_group]: []}), {})
lemma_.paradigm_info.forEach(std => inflection_groups[std.inflection_group].push(std))
return {
lemma: lemma_.lemma,
inflection_groups: Object.fromEntries(Object.entries(inflection_groups).filter(e => components.includes(e[0].replace('/', '_'))))
}
hgno_arabic: function() {
let hgnos = []
this.lemmas.forEach(lemma => {
let hgint = parseInt(lemma.hgno)
if (hgint > 0) {
hgnos.push(hgint)
}
)
},
lemmas_with_word_class_and_lang: function() {
return this.lemmas.map(lemma => Object.assign({language: this.dictionary == 'bob' ? '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) => acc2 += digm.inflection.length, 0), 0) > 0
})
return hgnos
},
split_inf: function() {
return this.lemmas[0].split_inf
}
},
components: {
inflectionTable
},
data: function() {
return {
inflect_reported: false,
menu: false
}
},
methods: {
toggle: function() {
if (! this.inflect_reported) {
this.$plausible.trackEvent('open inflection', {props: {article: `/${this.dictionary}/${this.article_id}/${this.lemmas[0].lemma}`}})
}
this.inflect_reported = true
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)
}
return groups
},
}
}
......@@ -118,19 +182,34 @@ export default {
<style>
summary {
width: 30em;
text-align: center;
.article h3 {
padding-top: 4px !important;
padding-bottom: 0px !important;
font-family: Inria Serif;
}
article h2 {
padding-top: 4px;
padding-bottom: 0px;
font-family: Inria Serif;
font-size: 30px;
.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 h2.secondary_header {
.article h1.secondary_header {
padding-top: 0px;
padding-bottom: 4px;
}
......@@ -142,151 +221,68 @@ article h2.secondary_header {
width: 10px;
}
.info-card {
padding: 12px;
}
.word-classification {
text-decoration: underline dashed;
}
.dict-label {
color: var(--v-primary-base) ;
font-weight: bold;
padding-left: 5px;
position: absolute;
top: 0px;
left: 15px;
font-variant-caps: all-small-caps;
}
.header details {
margin-top: 10px;
position: relative;
}
.header summary {
position: relative;
max-width: 130px;
list-style: none;
border: solid 2px var(--v-primary-base);
border-radius: 30px;
padding-top: 6px;
padding-bottom: 6px;
padding-right: 10px;
color: var(--v-primary-base);
cursor: pointer;
}
.header details[open] > summary {
box-shadow: 2px 2px 0px var(--v-primary-base)
}
.header details > summary:after {
content: "⌄";
font-weight: bold;
position: absolute;
right: 0;
top: 1px;
margin-right: 3px;
}
.header details > summary.bob:before {
content: "Se ";
div.lemma {
display: none;
}
.header details > summary.nob:before {
content: "Sjå ";
}
.header details[open] > summary.bob:before, details[open] > summary.nob:before {
content: "Skjul ";
}
.header details[open] > summary:after {
content: "⌃";
font-weight: bold;
position: absolute;
right: 0;
top: 8px;
margin-right: 3px;
.article_header {
overflow:auto;
word-wrap: normal;
text-decoration: none;
}
@keyframes open {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.header details[open] summary ~ * {
animation: open 0.3s ease-in-out;
.hgno {
color: var(--v-text-base) !important;
font-family: unset;
font-size: 16px;
font-weight: normal;
}
.inflection-canvas {
overflow-x: auto;
/*position: absolute;*/
z-index: 5;
background-color: rgba(255, 255, 255, 0);
/*max-width: 100vw;*/
padding-top: 10px;
}
.header details > summary::-webkit-details-marker {
display: none;
.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;
}
.infl-wrapper {
background-color: #ffffff;
border: solid 1px;
color: var(--v-primary-base);
border-color: var(--v-border-base);
border-radius: 10px;
padding: 10px;
width: min-content;
margin: 5px;
.subheader {
color: var(--v-text-base);
font-weight: normal;
font-style: italic;
font-size: 14px;
padding-right: 10px;
}
.context {
color: var(--v-primary-lighten4) !important;
}
div.lemma {
display: none;
}
table {
border-collapse: collapse;
margin-top: 5px;
border-color: var(--v-primary-base);
}
th, td {
border: solid 1px;
padding: 5px;
.inflection_classes {
font-style: normal;
}
th {
background-color: var(--v-tertiary-darken1);
color: var(--v-primary-darken1);
}
.infl-label {
text-align: center;
vertical-align: top;
.header_group_list {
font-variant: all-small-caps;
font-style: normal;
font-size: 18px;
}
article:not(.righ_hand_column) .inflection-canvas {
left: -35px;
p.under_inflection_button {
padding-top:10px !important;
}
td.hilite {
background-color: var(--v-tertiary-base);
text-align: center
}
</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>