diff --git a/.envrc b/.envrc index 9a0efa8..b31f8da 100644 --- a/.envrc +++ b/.envrc @@ -1,3 +1,2 @@ layout ruby PATH_add $(pwd)/presentation/node_modules/.bin -PATH_add $(pwd)/presentation/node_modules/.bin diff --git a/README.md b/README.md index aa0a8f4..f580230 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,8 @@ Für Chef Ruby-Abhängigkeiten installieren: - $ cd chef-lctp && bundle + $ cd chef-lctp + $ bundle Es werden ein paar andere Cookbooks verwendet, diese werden mit diesem Befehl heruntergeladen diff --git a/Vagrantfile b/Vagrantfile index 5fed0dd..17ea8ef 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -10,10 +10,10 @@ def load_json(name) end boxes = [ - #{ name: "puppet0.lctp", provision: :puppet, mac: "5CA1AB1E0F01"}, # uncomment to enable puppet + { name: "puppet0.lctp", provision: :puppet, mac: "5CA1AB1E0F01"}, # uncomment to enable puppet { name: "node0.lctp", provision: :chef, role: :head_node, mac: "5CA1AB1E0001", json: load_json("node0.json") }, { name: "node1.lctp", provision: :chef, role: :compute_node, mac: "5CA1AB1E0002", json: load_json("node1.json") }, - #{ name: "node2.lctp", provision: :chef, role: :compute_node, mac: "5CA1AB1E0003", json: load_json("node2.json") } + { name: "node2.lctp", provision: :chef, role: :compute_node, mac: "5CA1AB1E0003", json: load_json("node2.json") } ] ["vbguest", "berkshelf"].each do |plugin| @@ -27,11 +27,11 @@ boxes = [ end end + Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vbguest.auto_update = true config.vbguest.auto_reboot = true - config.vm.provision(:shell){ |shell| shell.path = "script/fix_stdin_error.sh" } boxes.each do |box| config.vm.define box[:name] do |node| node.vm.provider :virtualbox do |vb| diff --git a/report/alphadin.bst b/report/alphadin.bst index 8496cac..0698026 100644 --- a/report/alphadin.bst +++ b/report/alphadin.bst @@ -1,104 +1,127 @@ -%% ALPHADIN.BST Ausgabe [8] 10/10/00 -%% (C) Klaus F. Lorenzen, Hamburg email: lorenzen.marxen@t-online.de -%% ersetzt ALPHADIN.BST Ausgabe [7,1] vom 23/11/99 -%% ersetzt DinAlpha.BST von 1994 +%% ALPHADIN.BST Ausgabe [8.2] 2006-01-02 +%% +%% ersetzt ABBRVDIN.BST Ausgabe [8.1b4] 15/12/2004 +%% wichtigste Aenderung gegenueber Version [8.1b4]: +%% die Standardergaenzung "Online-Ressource" bei Internetquellen +%% ist ersatzlos gestrichen worden (wegen ueberfluessiger Redundanz). +%% +% +%% K.F.Lorenzen (Copyright 1994-2006) email: lorenzen.marxen@t-online.de %% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -%% ALPHADIN.BST wurde entwickelt aus BibTeX standard bibliography style -%% `alpha'.Mit ALPHADIN.BST werden Literaturverzeichnisse gemaess der deutschen -%% Zitiernorm DIN 1505 Teil 2 formatiert. -%% Analog zu den 4 US standard styles wird ein vollstaendiger Satz von -%% 4 DIN-gerechten bst-style Dateien veroeffentlicht (alphadin.bst, -%% plaindin.bst, unsrtdin.bst, abbrvdin.bst). Die gueltige Version -%% ist am schnellsten aus dem WWW ueber folgende URL zu beziehen -%% http://www.fh-hamburg.de/pers/Lorenzen/bibtex/ -%% Stand: 16/6/99 +%% ALPHADIN.BST wurde entwickelt aus Oren Patashnik's BibTeX standard +%% bibliography style `alpha'. Eine vorgegebene Literaturdatenbank laesst sich +%% somit beliebig nach Us- oder deutscher DIN 1505-Zitierkonvention +%% verarbeiten. +%% Analog zu den 4 US standard styles werden 4 DIN-gerechte bst-style Dateien +%% veroeffentlicht (alphadin.bst, plaindin.bst, unsrtdin.bst, abbrvdin.bst). +%% Die gueltige Version ist am schnellsten aus dem WWW ueber folgende URL zu +%% beziehen: +%% http://www.haw-hamburg.de/pers/Lorenzen/bibtex/ +%% Stand: 2006-01-02 %% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ %% WAS IST ALPHADIN.BST ? %% Dieser style produziert "deutsche" Literaturzitate in Literaturverzeichnis- %% sen gemaess der deutschen Norm DIN 1505, Teil 2 vom Jan. 1984. -%% Die Literaturzitate werden alphabetisch nach Verfassern sortiert -%% und sind durch abgekuerzte Verfasserbuchstaben plus Erscheinungsjahr in -%% eckigen Klammern gekennzeichnet. -%% Es gibt Unterschiede zwischen der US- und der deutschen Zitierkonvention, -%% was die bibliographischen Typen und die verschiedenen Trennzeichen zwischen -%% den Feldern angeht. Daher ist auch keine 100%ige Abbildung der beiden -%% Regelwerke aufeinander moeglich. Dies ist aber immer durch eine achtsame -%% Erfassung beherrschbar! Die vorliegenden DIN-styles versuchen einige -%% bibliographische Beschraenkungen der Originalstyles zu ueberwinden. -%% Es laesst sich in fast allen Faellen problemlos ein Original-bib-file -%% (d.i. die Datenbank, die die bibliographischen Informationen enthaelt) -%% wahlweise nach US-Norm oder deutscher DIN-Norm verarbeiten. -%% [Beispiel: Produzieren Sie mit der XAMPL.bib-Datenbank aus dem Original- -%% paket 2 verschiedene Literaturverzeichnisse.] Zu Gunsten -%% der Allgemeingueltigkeit von bib-files ist bei den Publikationstypen -%% (entry-types) und den bibliographischen Kategorien (fields) in Zweifels- -%% faellen immer die originale US-Bedeutung beibehalten worden. -%% Bei der Erfassung von Literaturquellen in bib-files -%% gelten folglich die in der TEX-Literatur veroeffentlichten Regeln. -%% Kommt es dennoch zu kleineren "Schoenheitsfehlern" im fertig gesetzten -%% output, so koennen diese so gut wie immer durch eine leicht veraenderte -%% Erfassung im bib-inputfile beseitigt werden. Last but not least koennen +%% Die Literaturzitate werden alphabetisch nach Verfassern sortiert. +%% Die Zitiermarken im Text und die Ordnungsmarken im Literaturverzeichnis +%% bestehen aus abgekuerzten Verfasserbuchstaben plus Erscheinungsjahr in +%% eckigen Klammern. Die vorliegenden DIN-styles gehen ueber einige bibliogra- +%% phischen Beschraenkungen der Originalstyles hinaus. +% +%% Es werden nun auch Elektronische Online / Offline Ressourcen wie Internet- +%% quellen, CD-ROM usw. verarbeitet. Dazu kommen besondere Publikationsformen +%% wie Patente, Normen, Karten, Fernsehaufzeichnungen, Gesetzesstellen, Spiele. +% +%% Zur Gewaehrleistung der Allgemeingueltigkeit von bib-files gelten in den +%% DIN-styles die in der Tex-Literatur veroeffentlichten originalen +%% Definitionen und Regeln fuer die Publikationstypen (entry-types) und die +%% bibliographischen Felder (fields). +%% Treten kleinere "Schoenheitsfehler" im fertig gesetzten output auf, +%% lassen sich diese so gut wie immer durch eine veraenderte +%% Erfassung im bib-inputfile beseitigen. Oren Patashnik empfiehlt, die +%% Definition der Felder weit auszulegen. Last but not least koennen %% Sie im output-file < *.bbl > noch letzte Hand zur Korrektur ansetzen. % -%% UMGANG MIT FEHLERMELDUNGEN -%% Noch nicht alle ueberfluessigen Fehlermeldungen des Original-style sind -%% ausgemerzt. Die meisten Warnmeldungen beruhen auf -%% den andersartigen bibliographischen Regeln nach DIN 1505 und dem damit -%% verbundenen Ermessensspielraum, sind also in Wahrheit keine "Fehler". -%% Dennoch sollten Sie diese Warnungen beachten, um herauszufinden, ob -%% evtl. eine unzulaessige Kombination von Publikationstyp (=entry-type) und -%% "fields" vorgenommen worden ist. Das fuehrt mitunter zu Wasserfallartigen -%% Fehlermeldungen: meistens duerfen Sie das einfach ignorieren. +%% WARN- UND FEHLERMELDUNGEN +%% Ursache von Warnmeldungen sind meistens ausgelassene Felder oder +%% Erfassungs-"Fehler". Letztere haengen teilweise mit den gegenueber US- +%% Gepflogenheiten andersartigen bibliographischen Regeln nach DIN 1505 +%% zusammen. Sie sind also in Wahrheit keine "Fehler" und duerfen fast immer +%% ignoriert werden. Dennoch pruefen Sie diese Warnungen, um herauszufinden, +%% ob Publikationstyp (=entry-type) und "fields" eventuell unzulaessig +%% kombiniert worden sind. +%% Echte Fehler ("errors") treten nur noch in Verbindung mit falscher +%% Erfassung auf (nach meinen Tests!). Pruefen Sie die Syntax, den entry-type +%% und die fields. +%% Zu guter letzt: Qualitaetsmasstab ist einzig der DIN-konforme output! %% %% DANKSAGUNG -%% Hartmut Lueddecke, FH Hamburg habe ich fuer viele Verbesserungsvorschlaege -%% und stete Unterstuetzung zu danken. Vielen an dieser Stelle ungenannt -%% bleibenden Anwendern gilt mein Dank, die in den vergangenen Jahren durch -%% ihre Aufmerksamkeit dazu beigetragen haben, Fehler auszumerzen und -%% Verbesserungen vorzunehmen. +%% Hartmut Lueddecke, HAW Hamburg, hat viele Verbesserungsvorschlaege +%% in die frueheren Versionen eingebracht. Ihm danke ich herzlich. +%% Patrick W. Daly, dem Entwickler des Natbib-Stils, verdanke ich viele +%% Anregungen und den steten Ansporn, die DIN-Stile zu verbessern. +%% Viele an dieser Stelle ungenannt bleibende Anwender haben mich in +%% den vergangenen Jahren auf Fehler oder Verbesserungsmoeglichkeiten +%% aufmerksam gemacht und so diesen Stil mitentwickelt. Ihnen gilt mein +%% besonderer Dank. Ihr Feedback ist immer willkommen und eine Ermunterung. %% -%% HINWEIS: es gibt eine Kombination von ALPHADIN.BST mit dem NATBIB-Stil -%% von Patrick W.Daly), womit Literaturverzeichnisse komplett nach -%% DIN 1505 Teil 2 UND Teil 3 formatiert werden koennen. Naeheres -%% per URL http://www.fh-hamburg.de/pers/Lorenzen/bibtex/ +%% Klaus F. Lorenzen %% -%% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -%% Eine ausfuehrliches Internet-Tutorial mit Beispielen ist in Vorbereitung. -%% Fuer den Anfang ist diese Datei schon etwas kommentiert! -%% Kritik, Vorschlaege usw. bitte an : -%% FH Hamburg, Klaus F. Lorenzen, Grindelhof 30, 20146 Hamburg -%% e-mail: lorenzen.marxen@t-online.de -%% 16/6/99 -%% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -% version 0.99c for BibTeX versions 0.99c or later, LaTeX2e -% Copyright (C) 1985, all rights reserved. -% Copying of this file is authorized only if either -% (1) you make absolutely no changes to your copy, including name, or -% (2) if you do make changes, you name it something other than -% bstdin.doc, plaindin.bst, unsrtdin.bst, alphadin.bst, and abbrvdin.bst. -% This restriction helps ensure that all standard styles are identical. -%% ==> The file btxbst.doc has the original documentation for style 'alpha'. -%% +%% +%% +%% HINWEIS: Neben den vier bibliographischen DIN 1505 Standard-Stilen +%% nach den Original-styles von Oren Patashnik +%% gibt es noch vier DIN 1505 Adaptionen der NATBIB-style +%% Emulationen von Patrick W.Daly. Die Fuelle der darin +%% implementierten Zitierweisen geht weit ueber die urspruenglichen +%% Standardstyles hinaus. +%% Naeheres unter URL http://www.haw-hamburg.de/pers/Lorenzen/bibtex/ +%% +%%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +%% version 0.99c for BibTeX versions 0.99c or later, LaTeX2e version +%% Copyright (C) 1985, all rights reserved. +%% Copying of this file is authorized only if either +%% (1) you make absolutely no changes to your copy, including name, or +%% (2) if you do make changes, you name it something other than +%% alphadin.bst +%% This restriction helps ensure that all standard styles are identical. +%% +%% +%% +%%~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +%% NEUE FELDER +%% Zur Erfassung der neuen digitalen Online-Medien z.B. Internetquellen, E-journals, E-books, +%% E-mail u.a. gibt es die zusaetzlichen Felder: doi, url, urn, lastchecked +%% Internetquellen werden vorzugsweise mit dem BOOKLET-Typ erfasst. +%% Normen, Patente, Schutzrechte sind mit dem MISC-Typ zu erfassen. ENTRY - { address %% Verlagsort - author %% persoenlicher Urheber eines Werkes - booktitle %% a) Gesamttitel eines mehrbaendigen Werkes + { address %% Verlagsort (immer!) + author %% persoenlicher Urheber eines Werkes oder am Zustandekommen + %% beteiligte Personen(=Mitarbeiter, Uebersetzer, Redakteur u.a.) + booktitle %% a) Gesamttitel eines mehrbaendigen Werkes % %% b) Titel des Sammelwerks, das einzelne selbstaendige -% %% Beitraege mit eigenem Titel enthaelt (->incollection) +% %% Beitraege mit eigenem Titel enthaelt ->incollection chapter %% Kapitel in einem Buch (Monographie) - edition %% Auflagevermerk + doi %%% Digital Object Identifier ->article + edition %% a) Auflagevermerk +% %% b) bei selbst. elektron. Quellen == Version ->booklet editor %% Persoenl.Herausgeber oder Koerperschaftlicher Herausgeber - howpublished %% beliebiger Verlegervermerk: von wem, wo - institution %% Institution, die e.Verlagsfreie Veroeffentlichung betreibt + howpublished %% beliebiger Verlegervermerk: veroeffentlicht "von wem, wo" + institution %% Institution, die e.verlagsfreie Veroeffentlichung betreibt isbn %% Standardnr fuer Buecher issn %% - " - : Zeitschriften u. Serien journal %% Titel einer Zeitschrift key %% Zusaetzlich vergebener Sortierschluessel, mitunter notwend. - month %% naehere Bestimmung des Erscheinungsjahres (-> macro 's) - note %% freies Eingabefeld fuer zusaetzliche Informationen - number %% Mehrfachbedeutung in Abhaengigkeit vom Eingabetyp - organization %% a) Name der Organisation/des Veranstalters e. Tagung,Konferenz + lastchecked %% neues Feld fuer das Datum des Online-Abrufs +% %% einer Internetquelle (n. GRAY ) + month %% naehere Bestimmung des Erscheinungsjahres -> macro 's + note %% freies Eingabefeld fuer zusaetzliche Informationen z. Quelle + number %% Versch. Bedeutungen in Abhaengigkeit vom Eingabetyp: +% %% a) Bandnummer einer gezaehlten Reihe (series) +% %% b) Heftnummer einer Zeitschrift ->article +% %% c) Nummer eines Forschungsberichts ->techreport + organization %% a) Name der Organisation/des Organisators e. Tagung,Konferenz % %% b) Name einer Firma/Gesellschaft, die ein ->manual herausgab pages %% Umfangsangaben, meist Seitenzahlen publisher %% Verlag @@ -106,20 +129,63 @@ ENTRY series %% Titel e.Reihe, in der ein best. Buchtitel erschienen ist title %% Titel einer (namentlich gekennzeichneten) Veroeffentlichung type %% Zusatzfeld z.Kennzeichnung e.besonderen Publikationstyps - volume %% a) Zaehlung bei einem mehrbaendigen Werk (-> book) -% %% b) Jahrgang einer Zeitschrift (-> article + url %% neues Feld URL ( Uniform Resource Locator ): +% %% Serveradresse einer Internetquelle + urn %% neues Feld URN ( Uniform Resource Name ): +% %% Persistent Identifier einer Internetquelle + volume %% a) Zaehlung bei einem mehrbaendigen Werk ->book/->proceedings +% %% b) Jahrgang einer Zeitschrift ->article year %% Erscheinungsjahr } {} - { label extra.label sort.label } + { label extra.label sort.label short.list } + +%%%---------------------------------------------------------------------------- +% Einige Standardvorgaben, die vom Benutzer veraendert werden koennen. +%%%---------------------------------------------------------------------------- + +% Abkuerzung ("... und andere") bei Mehrverfasserquellen: + +FUNCTION { ua.etal } { " u.\,a." } %% evtl. auch in eckigen Klammern " [u.\,a.]" + +%% oder lateinisch: FUNCTION { ua.etal } { " et~al." } + +FUNCTION { und } { " u. " } + +%% oder ausgeschrieben: FUNCTION { und } { " und " } +% +% Einige elektronische Medien erhalten nach DIN 1505 eine "Ergaenzende Angabe" +% zusaetzlich zum materiellen Typ, z.B. CD ROM oder DVD u.a.: + +FUNCTION { eress } { "Elektronische Ressource" } + +%%%----------------------------------------------------------------------------------- INTEGERS { output.state before.all mid.sentence after.sentence after.block } -%% die folg. BOOLE'sche VAR steuern d. Ausg. ": " nach Urheber-Feldern -%% und ". - " vor ISBN oder Anmerkungen (NOTE) - INTEGERS { colon.after period.dash } +INTEGERS { after.firstblock } + +INTEGERS { zahl lang } + +INTEGERS { nameptr namesleft numnames } + +INTEGERS { ptr collation collrest } + +INTEGERS { len } + +INTEGERS { et.al.char.used } + +INTEGERS { longest.label.width last.extra.num } +%------------------------- +STRINGS { longest.label last.sort.label next.extra } + +STRINGS { h s t u v w } + +STRINGS { fkt } +%------------------------- + FUNCTION {init.state.consts} { #0 'before.all := #1 'mid.sentence := @@ -127,12 +193,8 @@ FUNCTION {init.state.consts} #3 'after.block := #4 'colon.after := #5 'period.dash := + #6 'after.firstblock := } -INTEGERS { zahl lang } - -STRINGS { h s t u v } - -%% neue DIN-Funktion, 16/2/94 FUNCTION {output.nonnull} { 's := @@ -142,7 +204,7 @@ FUNCTION {output.nonnull} "\newblock " write$ } { output.state before.all = - { write$ } + { write$ } { output.state colon.after = { ": " * write$ newline$ @@ -155,22 +217,33 @@ FUNCTION {output.nonnull} } { output.state mid.sentence = { ", " * write$ } - { write$ - newline$ - "\newblock " write$ + { output.state after.sentence = + { " " * write$ } + { output.state after.firstblock = + { add.period$ write$ + newline$ + "\newblock " write$ + } + { write$ + newline$ + "\newblock " write$ + } + if$ + } + if$ } if$ } - if$ + if$ } - if$ - } + if$ + } if$ - after.block 'output.state := - } - if$ - s -} + after.block 'output.state := + } + if$ + s + } FUNCTION {output} { duplicate$ empty$ @@ -187,64 +260,13 @@ FUNCTION {output.check} if$ } -FUNCTION {output.bibitem} -{ newline$ - "\bibitem[" write$ - label write$ - "]{" write$ - cite$ write$ - "}" write$ - newline$ - "" - before.all 'output.state := -} - -FUNCTION {fin.entry} %%$$$ nach DIN neu 16/2/94 -{ write$ - newline$ -} - -FUNCTION {set.period.dash} %% Wenn ein ". - " die Satzteile trennen soll.! +FUNCTION {new.block} { output.state before.all = 'skip$ - { period.dash 'output.state := } + { after.block 'output.state := } if$ } -%% neu 16/2/94 -%% prueft, ob PAGES, ISBN- oder NOTE-Feld vh. ist und setzt dann ". - " davor. - -FUNCTION {set.period.dash.check} -{ empty$ - 'skip$ - 'set.period.dash - if$ -} - -FUNCTION {set.colon.after} %%$$$ Wenn ein ": " d. Satzteile trennen soll! -{ output.state before.all = - 'skip$ - { colon.after 'output.state := } - if$ -} - -%% neu / alt 17/2/94 Wenn ein " " die Satzteile trennen soll.! -FUNCTION {new.sentence} -{ output.state before.all = - 'skip$ - { after.sentence 'output.state := } - if$ -} - -%% neu 17/2/94 Wenn ein ", " die Satzteile trennen soll.! -FUNCTION { part.of.sentence } -{ output.state before.all = - 'skip$ - { mid.sentence 'output.state := } - if$ -} - - FUNCTION {not} { { #0 } { #1 } @@ -263,6 +285,61 @@ FUNCTION {or} if$ } + +FUNCTION {output.bibitem} +{ newline$ + "\bibitem[" write$ + label write$% + "]{" write$ + cite$ write$ + "}" write$ + newline$ + "" + before.all 'output.state := +} + +FUNCTION {fin.entry} +{ write$ + newline$ +} + +FUNCTION {set.period.dash} %% Wenn ein ". - " die Satzteile trennen soll.! +{ output.state before.all = + 'skip$ + { period.dash 'output.state := } + if$ +} + +FUNCTION {set.period.dash.check} +{ empty$ + 'skip$ + 'set.period.dash + if$ +} + +FUNCTION {set.colon.after} %%$$$ Wenn ein ": " d. Satzteile trennen soll! +{ output.state before.all = + 'skip$ + { colon.after 'output.state := } + if$ +} + +%% Wenn ein " " die Satzteile trennen soll.! +FUNCTION {new.sentence} +{ output.state before.all = + 'skip$ + { after.sentence 'output.state := } + if$ +} + +%% Wenn ein ", " die Satzteile trennen soll.! +FUNCTION { part.of.sentence } +{ output.state before.all = + 'skip$ + { mid.sentence 'output.state := } + if$ +} + FUNCTION {new.sentence.checka} { empty$ 'skip$ @@ -277,10 +354,6 @@ FUNCTION {field.or.null} if$ } -INTEGERS { nameptr namesleft numnames } - -STRINGS { fkt } - FUNCTION {emphasize} { duplicate$ empty$ { pop$ "" } @@ -288,7 +361,6 @@ FUNCTION {emphasize} if$ } -%% neu, setzt Autor/Hrsg. in Kapitaelchen 9/3/94 FUNCTION { capitalize } { duplicate$ empty$ { pop$ "" } @@ -296,27 +368,9 @@ FUNCTION { capitalize } if$ } -%%$$$ DIN-Quellenangabe : spezieller unselbst. Teil ist erschienen "In: " -%% dem bibliogr. selbst. Werk, z.B. Zeitschrift, Buch -%% 1/4/96 -FUNCTION {article.in.journal} -{ duplicate$ empty$ - { pop$ "" } - { author missing$ - { title missing$ - { emphasize " " * * }%% wenn ein Zs-Heft als ganzes zitiert wird - { emphasize "{In: }" swap$ " " * * } - if$ - } - { emphasize "{In: }" swap$ " " * * } - if$ - } - if$ -} - -%% nach Vorschlag von H.Lueddecke, um Adelspraedikate beim Sortieren -%% nach den(m) Vornamen aufzufuehren. Lo, 2/11/94 +%% Adelspraedikate beim Sortieren nach den(m) Vornamen auffuehren +%% Abweichend v. DIN !!! FUNCTION {format.names} { 's := "" 'u := @@ -325,21 +379,21 @@ FUNCTION {format.names} numnames 'namesleft := { namesleft #0 > } { - s nameptr "{vv~}{ll}" format.name$ 't :=%% das ergibt DIN-Ansetzung - %% Lue's Vorschlag s nameptr "{ll}" format.name$ 't := + s nameptr "{ll}" format.name$ 't := t capitalize 't := - s nameptr "{, ff}" format.name$ 'u := - %% Lue's Vorschlag s nameptr "{, ff}{ vv}" format.name$ 'u := - u text.length$ 'lang := + s nameptr "{ jj}" format.name$ 'w := + s nameptr "{, ff}{ vv}{ jj}" format.name$ 'u := + u text.length$ 'lang := #1 'zahl := "" 'v := { zahl lang < } - { u zahl #1 substring$ "~" = + { u zahl #1 substring$ "~" = { v "" = { u #1 zahl #1 - substring$ 'v := } 'skip$ if$ - v u zahl #2 substring$ * "." * 'v := } + v u zahl #2 substring$ * "." * w * 'v := + } 'skip$ if$ zahl #1 + 'zahl := } @@ -348,9 +402,7 @@ FUNCTION {format.names} { u 'v := } 'skip$ if$ -%% der string fkt enthaelt " (Hrsg.)", wenn Editorfeld nicht leer ist - t v * fkt * 't := %% Komma nach Nachnamen wird oben erledigt! - %% t enthaelt nun d. formatierten Nnamen, Vnamen + t v * fkt * 't := nameptr #1 > { namesleft #1 > { " ; " * t * } @@ -358,20 +410,15 @@ FUNCTION {format.names} { " " * } 'skip$ if$ -%% %% n. schindle's hinweis 12/1/96 erweitert t "\textsc{others}" = t "\textsc{others} (Hrsg.)" = or - { " [u.~a.]" * }%% 13/2/94 -%%%% { "et~al." * } %% Geschmackssache, waehle eins von beiden - { " ; " * t * } + { ua.etal * } + { " ; " * t * } if$ } if$ %% Ende der namesleft-Pruefung } - 't - %% hierdurch wird bei jed. Schleifendurchgang das sich komplet- - %% tierende Zwischen-Namensergebnis wieder auf den stack gelegt - - if$ %% Ende der nameptr-Pruefung + 't + if$ %% Ende der nameptr-Pruefung nameptr #1 + 'nameptr := namesleft #1 - 'namesleft := @@ -380,8 +427,6 @@ FUNCTION {format.names} "" 'fkt := %% fkt wird zurueckgesetzt } -%%$$$ geaendert 14/2/94 - FUNCTION {format.authors} { author empty$ { "" } @@ -389,50 +434,104 @@ FUNCTION {format.authors} if$ } -%%$$$ geaend. 20/2/94 Anpassung an DIN, wonach Autor + Hrsg. zusammen vorkom- -%% men duerfen.!! - FUNCTION {format.editors} { editor empty$ { author empty$ - { "Weder Verfasser noch Hrsg. in " cite$ * warning$ } - 'skip$ + { "empty author and editor in " cite$ * warning$ "" } + 'skip$ if$ - } - { author empty$ - { " (Hrsg.)" 'fkt := - editor format.names + } + { author empty$ + { " (Hrsg.)" 'fkt := + editor format.names } - { " (Hrsg.)" 'fkt := + { " (Hrsg.)" 'fkt := " ; " * editor format.names * } if$ - } - if$ - } + } + if$ + } + +%% 2005-11-11 +FUNCTION { format.authors.organization } +{ type$ "misc" = + { organization empty$ + { author empty$ + { "" } + { author format.names " (Erfinder)" * } + if$ + } + { author empty$ + { organization } + { author format.names " (Erfinder); " * + organization * " (Anmelder)" * + } + if$ + } + if$ + } + { type$ "manual" = + { organization empty$ + { author empty$ + { "" } + { author format.names } + if$ + } + { author empty$ + { organization capitalize " (Hrsg.)" * } + { author format.names " ; " * + organization capitalize * " (Hrsg.)" * + } + if$ + } + if$ + } + 'skip$ + if$ + } + if$ +} -%% Lo, 12/5/99 neue Funktion fuer proceedings, misc usw. FUNCTION { format.editors.organization } { organization empty$ 'skip$ { type$ "misc" = { organization } - { " ; " * organization " (Veranst.)" *} + { * " ; " * organization " (Veranst.)" *} if$ } if$ } -%%$$$ Sonderfall: Herausgeber bei Typ incollection, 21/2/94 +FUNCTION { format.tr.institution } +{ institution empty$ + 'skip$ + { institution capitalize } + if$ +} + FUNCTION {format.ed.incoll} { editor empty$ { "" } - { " (Hrsg.)" 'fkt := - editor format.names + { " (Hrsg.)" 'fkt := + editor format.names + format.editors.organization } if$ -} +} + +FUNCTION {article.in.journal} +{ duplicate$ empty$ + { pop$ "" } + { author missing$ title missing$ and + { emphasize } + { emphasize "{In: }" swap$ * } + if$ + } + if$ +} FUNCTION {format.title} { title empty$ @@ -441,70 +540,244 @@ FUNCTION {format.title} if$ } +FUNCTION {format.number} +{ number empty$ + { "" } + { number " " * } %% Text so wie er im Feld number steht plus " " + if$ +} + + +FUNCTION {format.digital.type} +{ type empty$ + { "" } + { type #-1 #4 substring$ "mail" = + type #1 #4 substring$ "Mail" = + OR + { "" } + { type } %% Typ einer digitalen Ressource in Form einer + %% "Ergaenzenden Angabe", so wie er dasteht; + %% Alternativ kann dieser Text auch in NOTE erfasst werden. + if$ + } + if$ +} + FUNCTION {n.dashify} { 't := "" { t empty$ not } { t #1 #1 substring$ "-" = - { t #1 #2 substring$ "--" = not - { "--" * - t #2 global.max$ substring$ 't := - } - { { t #1 #1 substring$ "-" = } - { "-" * - t #2 global.max$ substring$ 't := - } - while$ - } - if$ - } - { t #1 #1 substring$ * - t #2 global.max$ substring$ 't := - } + { t #1 #2 substring$ "--" = not + { "--" * + t #2 global.max$ substring$ 't := + } + { { t #1 #1 substring$ "-" = } + { "-" * + t #2 global.max$ substring$ 't := + } + while$ + } + if$ + } + { t #1 #1 substring$ * + t #2 global.max$ substring$ 't := + } if$ } while$ } -%% geaendert 24/2/94 +%% Auflagenvermerke gibt man komplett, einschliesslich Abkuerzungen in +%% das Feld edition ein: ---> EDITION= { 3., erw. und verb. Aufl. } +%% oder fremdsprachlich: EDITION= { 2nd edition } + +FUNCTION {format.edition} +{ edition empty$ + { "" } + { edition } + if$ +} + FUNCTION {format.date} -{ year empty$ - { month empty$ - { "" } - { "there's a month but no year in " cite$ * warning$ - month - } +{ year duplicate$ empty$ + { "empty year in " cite$ * warning$ + pop$ "" } + 'skip$ + if$ + month empty$ + 'skip$ + { type$ "book" = + type$ "inbook" = + OR + 'skip$ + { month " " * swap$ * } if$ - } - { month empty$ %% b. Buechern nur Jahr, ohne Monat ausgeb. im Impressum - 'year - { month " " * year * } + } + if$ +} + + +FUNCTION {format.edition.or.date} +{ edition empty$ year empty$ and + { "" } + { edition empty$ + { type empty$ NOT + { type #-1 #4 substring$ "mail" = + type #1 #4 substring$ "Mail" = + OR + { " gesendet: " "-- " type * swap$ * + format.date * + } + { "\,Version:\," + format.date * + } + if$ + } + { "\,Version:\," + format.date * + } + if$ + } + { year empty$ + { "\,Version:\," edition * } + { "\,Version:\," edition * ", " * + format.date * + } + if$ + } if$ } if$ } -%% -%%$$$ neue Fkt., 16/2/94 u. 14/3/94 das sog. Impressum +FUNCTION {format.doi} +{ doi empty$ + { "" } + { new.block "\url{http://dx.doi.org/" doi * "}" * + %% { new.block "\url{http://dx.medra.org/" doi * "}" * + } + if$ +} + +FUNCTION {format.url} +{ urn missing$ + { doi missing$ + { url empty$ + { "" } + { type empty$ NOT + { type #-1 #4 substring$ "mail" = + type #1 #4 substring$ "Mail" = + OR + { type$ "incollection" = + { "" } + { "\,Absenderadresse: \url{" url * "}" * } + if$ + } + { "\url{" url * "}" * }%% evtl. "URL" oder "<...>" + if$ + } + { "\url{" url * "}" * } %% evtl. "URL" oder "<...>" + if$ + } + if$ + } + { format.doi } + if$ + } + { "\url{http://nbn-resolving.de/urn/resolver.pl?urn=" urn * "}" * + } + if$ +} + +FUNCTION {format.maillist.url} + { url empty$ + { "" } + { type empty$ + { "" } + { type #-1 #4 substring$ "mail" = + type #1 #4 substring$ "Mail" = + OR + { "\url{" url * "}" * } + { "" } + if$ + } + if$ + } + if$ + } + + +FUNCTION {format.version.url} +{ url empty$ doi empty$ urn empty$ and and + { type$ "techreport" = + { format.edition } + { "" } + if$ + } + { format.edition.or.date output format.url } + if$ +} + +FUNCTION {format.edition.or.version} +{ url empty$ doi empty$ urn empty$ and and + { format.edition } + { format.edition.or.date } + if$ +} + +FUNCTION {format.online.lastcheck} +{ lastchecked empty$ + { url empty$ doi empty$ urn empty$ and and + { skip$ } + { "" output } + if$ + } + { url empty$ doi empty$ urn empty$ and and + { "there's a lastchecked date but no url, urn or doi in " + cite$ * warning$ + } + { part.of.sentence + lastchecked "Abruf: " swap$ * output + } + if$ + } + if$ +} + + +FUNCTION {format.maillist.lastcheck} + { type empty$ NOT + { type #-1 #4 substring$ "mail" = + type #1 #4 substring$ "Mail" = + OR + { format.online.lastcheck } + 'skip$ + if$ + } + 'skip$ + if$ + } + FUNCTION {format.address.publisher.year} { publisher empty$ { address empty$ - { year empty$ + { year empty$ { "" } - { year } + { year } if$ } - { "Es gibt einen Verlagsort, aber keinen Verlag in " cite$ * warning$ - address ", " * format.date * + { "there's an address but no publisher in " cite$ * warning$ + address ", " * format.date * } if$ } { address empty$ { year empty$ - { "Es gibt nur eine Verlagsangabe in " cite$ * warning$ - publisher - } - { publisher ", " * format.date * } + { "neither address nor publication date in " cite$ * warning$ + publisher + } + { publisher ", " * format.date * } if$ } { year empty$ @@ -513,15 +786,133 @@ FUNCTION {format.address.publisher.year} if$ } if$ + } + if$ +} + +FUNCTION {format.address.publisher.year.alt} +{ publisher empty$ + { address empty$ + { year empty$ + { "" } + { url empty$ + { year } + { "" } + if$ + } + if$ + } + { "there's an address but no publisher in " cite$ * warning$ + address ", " * format.date * + } + if$ } + { url empty$%%%% wenn es URL gibt wird nur die service-provider Adresse +%%% ausgegeben, die im publisher-Feld steht + { address empty$ + { year empty$ + { "neither address nor publication date in " cite$ * warning$ + publisher + } + { publisher ", " * format.date * } + if$ + } + { year empty$ + { address " : " * publisher * } + { address " : " * publisher * ", " * format.date * } + if$ + } + if$ + } + { publisher } + if$ + } + if$ +} + +FUNCTION {format.howpublished} +{ url missing$ urn missing$ doi missing$ AND AND + { howpublished empty$ + { address empty$ + { type empty$ + { "" } + { type #-1 #4 substring$ "mail" = + { "(gesendet: " new.sentence + format.date * ")" * + } + { "" } + if$ + } + if$ + format.date * + } + { address ", " * format.date * } + if$ + } + { address empty$ + { howpublished ", " * format.date * } + { address " : " * howpublished * ", " * format.date * } + if$ + } + if$ + } + { howpublished empty$ + { "" } + { howpublished } + if$ + } if$ } +FUNCTION {format.lastchecked.or.type}%% nur in misc-Funktion +{ lastchecked empty$ + { url empty$ doi empty$ urn empty$ and and + { type empty$ + { skip$ } + { type set.period.dash.check + type output + } + if$ + } + { type empty$ + { skip$ } + { type #-1 #4 substring$ "mail" = + type #1 #4 substring$ "Mail" = + OR + { skip$ } + { type set.period.dash.check + type output } + if$ + } + if$ + } + if$ + } + { url empty$ doi empty$ urn empty$ and and + { "there's a lastchecked date but no url, urn or doi in " + cite$ * warning$ + } + { type empty$ + { "there's a URL and a lastchecked date but no type in " + cite$ * warning$ + } + { type set.period.dash.check + type output + part.of.sentence + lastchecked "Abruf: " swap$ * output + } + if$ + } + if$ + } + if$ +} + + FUNCTION {format.btitle} { title emphasize } - FUNCTION {tie.or.space.connect} { duplicate$ text.length$ #3 < { "~" } @@ -530,15 +921,6 @@ FUNCTION {tie.or.space.connect} swap$ * * } -FUNCTION {either.or.check} -{ empty$ - 'pop$ - { "can't use both " swap$ * " fields in " * cite$ * warning$ } - if$ -} - -%% neu 8/3/94 in dieser Funkt. steckt im volume empty-Teil noch ein bug, der -%% aber ignoriert werden kann; das Ergebnis ist ok. FUNCTION {format.btitle.vol} { number empty$ { series empty$ @@ -550,9 +932,9 @@ FUNCTION {format.btitle.vol} { volume empty$ { title emphasize }%% ein Buch, das zusaetzl. SERIES=Reihentitel besitzt %% jetzt kommt d. Fall des mehrbaendigen Werkes mit Gesamttitel=SERIES - %% Zaehlung=VOLUME und Bandtitel=TITLE; - { series emphasize ". Bd." * volume tie.or.space.connect - ": " * "{\emph{" * title * "}}" * } + %% Zaehlung=VOLUME und Bandtitel=TITLE; + { series emphasize ". Bd." * volume tie.or.space.connect + ": " * "{\emph{" * title * "}}" * } if$ } if$%% series-test @@ -561,32 +943,18 @@ FUNCTION {format.btitle.vol} if$%% Ende number-test } -%%$$$ neu 16/2/94 -%% Serien- / Reihentitel werden im Feld series gespeichert. Weist die -%% Serie eine Zaehlung der Einzeltitel auf, gibt man entweder nach DIN alles -%% in das Feld series so ein: ---> TITEL DER SERIE NR. (der Vorlage) <--- -%% z. B. SERIES= { Mensch und Computer 12 }. -%% [ Die Nummer der Vorlage darf auch durch " ; " abgesetzt werden. ] -%% oder: -%% man gibt die Zaehlung in das Feld NUMBER ein, z.B. NUMBER = {12}. -%% Achtung!! -%% Bei mehrbaendigen Werken steht d. Gesamttitel im Feld SERIES und die -%% Bandzaehlung im Feld VOLUME; NUMBER darf dann nicht besetzt sein! -%% Anderenfalls liegt ein Erfassungsfehler vor, da sich Reihe u. mehrbd. -%% Werk gegenseitig ausschliessen. - FUNCTION {format.series.number.din} { volume empty$ { number empty$ - { series empty$ - { "" }%% Ausstieg mit Nullstring - { "(" series * ")" * } %% d. Seriennr koennte auch gleich hier - %% im SERIES-Feld miterfasst werden - if$ - } { series empty$ - { "(" number tie.or.space.connect ")" * - "there's a number but no series in " cite$ * warning$ + { "" } + { "(" series * ")" * } %% d. Seriennr koennte auch gleich hier + %% im SERIES-Feld miterfasst werden + if$ + } + { series empty$ + { "(" number * ")" * + "there's a number but no series in " cite$ * warning$ } { "(" series * number tie.or.space.connect ")" * } if$ @@ -596,7 +964,8 @@ FUNCTION {format.series.number.din} { series empty$ { "" } { type$ "proceedings" = %% Sonderfall, es darf VOLUME und NUMBER ex. ! - { number empty$ + type$ "inproceedings" = OR + { number empty$ { "(" series * ")" * } { "(" series * number tie.or.space.connect ")" * } if$ @@ -604,14 +973,26 @@ FUNCTION {format.series.number.din} { "" }%% Ausstieg mit Nullstring, s. Kommentar if$ }%% bei gezaehlten Reihen MUSS die Reihennr. im Feld NUMBER stehen! - if$ %% wenn also d. Feld VOLUME nicht leer ist, dann liegt ausser bei + if$ %% wenn also d. Feld VOLUME nicht leer ist, dann liegt ausser bei %% Typ PROCEEDINGS falsche } %% Erfassung vor und es erfolgt d. Ausstieg mit d. Nullstring! - if$ + if$ } -%% seltener Fall bei MISC: Ausgabe einer Serie; die Nummer der Serie muss -%% in SERIES miterfasst werden 16/6/99 +FUNCTION {format.tr.series.or.number} +{ number empty$ + { series empty$ + { "" } + { "(" series * ")" * } + if$ + } + { series empty$ + { "(" number * ")" * } + { "(" series * number tie.or.space.connect ")" * } + if$ + } + if$ + } FUNCTION {format.misc.series} { series empty$ @@ -620,20 +1001,17 @@ FUNCTION {format.misc.series} if$ } - -%%$$$ 16/2/94 -%% Auflagenvermerke gibt man komplett, einschliesslich Abkuerzungen in -%% das Feld edition ein: ---> EDITION= { 3., erw. und verb. Aufl. } -%% oder fremdsprachlich: EDITION= { 2nd edition } - -FUNCTION {format.edition} -{ edition empty$ - { "" } - { edition } +FUNCTION { format.doi.urn } +{ urn empty$ + { doi empty$ + { "" } + { "DOI" doi n.dashify tie.or.space.connect } + if$ + } + { "URN" urn n.dashify tie.or.space.connect } if$ } -%%$$$ neu, 18/3/94 FUNCTION { format.isbn.issn } { isbn empty$ { issn empty$ @@ -645,88 +1023,138 @@ FUNCTION { format.isbn.issn } if$ } -%%$$$ geaendert, 21/2/94 gibt Seitenzahl bei BOOK-Typ und verwandten T. aus -FUNCTION {format.pages.book} -{ pages empty$ - { "" } - { "" pages n.dashify tie.or.space.connect " S" *} %% 17/12/95 - if$ -} - -%%$$$ alle anderen Seitenang. zB. Zeitschrft., INBOOK usw. a la Orig., 9/3/94 FUNCTION {format.pages} { pages empty$ { "" } - { "S." pages n.dashify tie.or.space.connect } + { url empty$ + { "S." pages n.dashify tie.or.space.connect } + { pages } + if$ + } if$ } -%% Angaben v. Jahrgang, Jahr, Heftnr., Seiten bei Artikel-Typ -%% 14/3/94, 26/2/97 +FUNCTION {format.pages.book} +{ pages empty$ + { "" } + { note empty$ isbn empty$ AND + { "" pages n.dashify tie.or.space.connect " S" * + add.period$ } + { "" pages n.dashify tie.or.space.connect " S" * } + if$ + } + if$ +} + +FUNCTION {format.pages.bkcollation} +{ pages empty$ + { "" } + { "" pages n.dashify tie.or.space.connect } + if$ +} + +FUNCTION {format.bkpages.collat.check} +{ 's := + #1 'ptr := + s text.length$ 'collation := + collation #1 = + { format.pages.book } + { + collation 'collrest := + { collrest #0 > } + { s ptr #2 substring$ 't := + t "S." = + { format.pages.bkcollation + #0 'collrest := } + { ptr #1 + 'ptr := + collrest #1 - 'collrest := + #1 collrest = + { format.pages.book } + { skip$ } + if$ + } + if$ + } + while$ + } + if$ +} FUNCTION {format.vol.year.num.pages} { volume field.or.null year empty$ - { "Es gibt einen Jahrgang, aber kein Jahr in " cite$ * warning$ } + { "there's no year in " cite$ * warning$ } { " (" year * ")" * * } if$ month empty$ - 'skip$ - { ", " month * * } + 'skip$ + { ", " month * * } if$ number empty$ - 'skip$ - { ", Nr. " number * * } - if$ - pages empty$%% Lo, 26/2/97 'skip$ - { ", " format.pages * *}%% + { ", Nr. " number * * } if$ - -%% pages empty$%% das war die Fass. Nov. 96, die auch ging -%% 'skip$ -%% { duplicate$ empty$ -%% { pop$ format.pages }%% da pages leer, wird nur "" auf stack gelegt -%% { ", " format.pages * *} -%% if$ -%% } -%% if$ - + pages empty$ + 'skip$ + { duplicate$ empty$ + { pop$ "" } + { title missing$ + { ", " pages format.bkpages.collat.check * *} + { ", " format.pages * *} + if$ + } + if$ + } + if$ } -%% geaendert 21/2/94 +FUNCTION {format.chapter.inbook} +{ duplicate$ empty$ + { pop$ "empty chapter in " cite$ * warning$ } + { type empty$ + { "\emph{Kapitel\/} " swap$ tie.or.space.connect } + { type " " * swap$ * }%% wenn keine bes. Abschnittsform gen. werden soll, + %% koennte e. kl. Zwischenraum gewaehlt werden, z.B. " \, " + if$ + } + if$ + } + FUNCTION {format.chapter.pages} { chapter empty$ 'format.pages { type empty$ - { "Kapitel " } - { type } + { "Kapitel " } + { url empty$ + { type } + { "Kapitel " } + if$ + } if$ chapter tie.or.space.connect pages empty$ - 'skip$ - { ", " * format.pages * } + 'skip$ + { ", " * format.pages * } if$ } if$ } -%%$$$ geaendert 21/2/94 FUNCTION {format.in.ed.booktitle.din} { booktitle empty$ { "" } { editor empty$ - { volume empty$ - { "{In: }" booktitle emphasize * }%% n. Belieben fettes In: - { "{In: }" booktitle emphasize * %% - " - - " Bd." volume tie.or.space.connect * + { volume empty$ + { "{In: }" booktitle emphasize * } + { "{In: }" booktitle emphasize * + " Bd." volume tie.or.space.connect * } if$ } - { volume empty$ + { volume empty$ { "{In: }" format.ed.incoll * ": " * booktitle emphasize * } - { "{In: }" format.ed.incoll * ": " * booktitle emphasize * - " Bd." volume tie.or.space.connect * + { "{In: }" format.ed.incoll * ": " * booktitle emphasize * + " Bd." volume tie.or.space.connect * } if$ } @@ -735,257 +1163,277 @@ FUNCTION {format.in.ed.booktitle.din} if$ } -%% geaendert 1/3/94 -FUNCTION {format.thesis.type} +FUNCTION {format.thesis.tr.type} { type empty$ 'skip$ - { pop$ - type - } - if$ + { pop$ + type + } + if$ } -%% geaendert 23/2/94 i.Orig. wird zuerst die number, dann der type getestet -FUNCTION {format.tr.number.din} -{ type empty$ - { number empty$ - { " -- Forschungsbericht" } %% bei Minimalangaben besser ohne "."! - { "(" number tie.or.space.connect "). -- Forschungsbericht" * } - if$ - } - { number empty$ - { " -- " type * } %% bei Minimalangaben besser ohne "."! - { "(" number tie.or.space.connect "). -- " * type * } - if$ - } - if$ -} - - FUNCTION {format.article.crossref} { key empty$ { journal empty$ - { "need key or journal for " cite$ * " to crossref " * crossref * - warning$ - "" - } - { "{In: }{\em " journal * "\/}" * }%% + { "need key or journal for " cite$ * " to crossref " * crossref * + warning$ + "" + } + { "{In: }{\emph " journal * "}" * } if$ } - { "{In: }" key * }%% + { "{In: }" key * } if$ - "{\cite{" * crossref * "}" * "}" * ", " * format.pages * -%% " (siehe \cite{" * crossref * "}" * "), " * format.pages * + "\cite{" * crossref * "}" * ", " * format.pages * } -%%geaendert 7/3/94 und noch einmal nach Lueddecke, s.o. FUNCTION {format.crossref.editor} -%vorher,Lue { editor #1 "{vv~}{ll}" format.name$ " (Hrsg.)" * { editor #1 "{ll}" format.name$ " (Hrsg.)" * editor num.names$ duplicate$ #2 > - { pop$ " [u.~a.]" * } -%% { pop$ " et~al." * } + { pop$ ua.etal * }%% --->u. a. { #2 < - 'skip$ - { editor #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" = - { " [u.~a.]" } -%% { " et~al." * } - { " ; " * editor #2 "{vv~}{ll}" format.name$ * " (Hrsg.)" * } - if$ - } + 'skip$ + { editor #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" = + { ua.etal } + { " ; " * editor #2 "{vv~}{ll}" format.name$ * " (Hrsg.)" * } + if$ + } if$ } if$ } +FUNCTION {format.inbk.vol.title} +{ volume empty$ + { " In: " } + { title empty$ + { " In: Bd." volume tie.or.space.connect + " von " * + } + { "In: Bd." volume tie.or.space.connect ": " * title emphasize * + " (" * year * ") in " * + } + if$ + } + if$ + } + FUNCTION {format.book.crossref} -{ volume empty$ - { "empty volume in " cite$ * "'s crossref of " * crossref * warning$ - "{\texttt{siehe}} " -%% "(siehe " - } - { ". -- Bd." volume tie.or.space.connect - " von " * +{ type$ "inbook" = + { format.inbk.vol.title } + { volume empty$ + { "empty volume in " cite$ * "'s crossref of " * crossref * warning$ + " " + } + { ". -- Bd." volume tie.or.space.connect + " von " * + } + if$ } if$ editor empty$ editor field.or.null author field.or.null = or { key empty$ - { series empty$ - { "need editor, key, or series for " cite$ * " to crossref " * - crossref * warning$ - "" * - } - { "" * }%% dadurch kommt nach der Bandzaehl. gleich das label 2/6/99 -%% { "{\emph{" * series * "}} {\texttt{siehe}}" * } - if$ - } - { key * } + { series empty$ + { "need editor, key, or series for " cite$ * " to crossref " * + crossref * warning$ + "" * + } + { "" * } + if$ + } + { key * } if$ } - { "" * }%% nach der Bandzaehlung kommt gleich das label; Lo 2/6/99 -%% { format.crossref.editor * } + { "" * } if$ - "{\cite{" * crossref * "}" * "}" * -%% "{\cite{" * crossref * "}" * "}" * %%"), " * format.pages * + "\cite{" * crossref * "}" * } FUNCTION {format.incoll.inproc.crossref} { editor empty$ - editor field.or.null author field.or.null = - or - { key empty$ - { booktitle empty$ - { "need editor, key, or booktitle for " cite$ * " to crossref " * - crossref * warning$ - "" - } - { "{In: }{\emph " booktitle * "}" * }%% fettes In: n. Belieben - if$ - } - { "{In: }" }%% 26/5/99 -%% { "{In: }" key * } + editor field.or.null author field.or.null = + or + { key empty$ + { booktitle empty$ + { "need editor, key, or booktitle for " cite$ * " to crossref " * + crossref * warning$ + "" + } + { "{In: }{\emph " booktitle * "}" * }%% + if$ + } + { "{In: }" } if$ - } -%% { "{In: }{\em " booktitle * "\/}" * }%% - { "{In: }" }%% Lo, 10/2/99 es sieht der reine Bezug (Referenz) besser aus! + } + { "{In: }" } if$ -%% " (siehe \cite{" * crossref * "}" * "), " * format.pages * - "{\cite{" * crossref * "}" * "}" * ", " * format.pages *%% das fette label, Lo 23/2/99 -%% alte Vers. bis 27/2/97 " (siehe \cite{" * crossref * "}" * ")" * + "\cite{" * crossref * "}" * %% ", " * format.pages * 5.12.2005 } -%%geaendert FUNCTION {article} { output.bibitem format.authors "author" output.check set.colon.after format.title "title" output.check crossref missing$ - { journal article.in.journal output.nonnull % 26/2/97 - new.sentence + { journal article.in.journal output.nonnull + new.sentence format.vol.year.num.pages output + format.url output } { format.article.crossref output.nonnull } if$ - note set.period.dash.check - note output + format.online.lastcheck + doi set.period.dash.check + urn set.period.dash.check + format.doi.urn output issn set.period.dash.check format.isbn.issn output + note set.period.dash.check + note output fin.entry } -%%$$$ geaendert, 20/2/94 FUNCTION {book} { output.bibitem author empty$ { format.editors "author and editor" output.check } - { format.authors format.editors output.nonnull } + { format.authors format.editors output.nonnull } if$ set.colon.after crossref missing$ { format.btitle.vol "title" output.check } { format.btitle "title" output.check } if$ - format.edition "edition" output.check + format.edition output format.address.publisher.year "publisher" output.check new.sentence crossref missing$ - { format.series.number.din output - pages set.period.dash.check%% 19/5/99 wie bei adinat.bst - format.pages.book output - } - { format.book.crossref output.nonnull - pages set.period.dash.check - format.pages.book output + { format.series.number.din output } + { format.book.crossref output.nonnull } + if$ + pages empty$ + { skip$ } + { pages set.period.dash.check + pages format.bkpages.collat.check output } if$ - note set.period.dash.check - note output + format.doi output + format.url output + new.block isbn set.period.dash.check format.isbn.issn output + note set.period.dash.check + note output fin.entry } -%% geaendert 23/2/94 -FUNCTION {inbook} +FUNCTION {booklet} { output.bibitem -%% unselbst. Teile eines Buches werden am Anf. genannt, dann d selbst. Quelle - chapter empty$ - { "Es fehlen die Kapitelangaben in " cite$ * warning$ } - { type empty$ - { "Kap. " }%% d.i. die Standardvorgabe - { type }%% wenn man keine bes. Typform angeben will, koennte ein kl. -%% Zwischenraum gewaehlt werden, z.B. " \, " - if$ - chapter tie.or.space.connect " {In: }" * * %% n. Belieben fettes In: - } - if$ - -%% -------- jetzt kommt der bibliogr. selbst. Teil author empty$ { format.editors "author and editor" output.check } - { format.authors output.nonnull - } + { format.authors format.editors output.nonnull } if$ set.colon.after - format.btitle.vol "title" output.check - crossref missing$ - { format.edition output - format.address.publisher.year "publisher" output.check - new.sentence - format.series.number.din output -%% vorher note ... - part.of.sentence - format.pages "pages" output.check - note set.period.dash.check - note output - } - { format.book.crossref output.nonnull - note set.period.dash.check - note output + format.btitle "title" output.check + format.edition.or.version output + format.url output + format.online.lastcheck + format.howpublished output + series new.sentence.checka + format.series.number.din output + pages empty$ + { skip$ } + { pages set.period.dash.check + pages format.bkpages.collat.check output } if$ - isbn set.period.dash.check + type set.period.dash.check + format.digital.type output + doi set.period.dash.check + urn set.period.dash.check + format.doi.urn output + note set.period.dash.check + note output format.isbn.issn output fin.entry } -%% geaenderte Seitenzahlausgabe, wenn crossref-Feld benutzt wird, 27/2/97 + +FUNCTION {inbook} +{ output.bibitem + chapter format.chapter.inbook output.nonnull + crossref missing$ + { author empty$ + { format.editors "\,{In:\,}" swap$ * "author and editor" output.check } + { format.authors "\,{In:\,}" swap$ * output.nonnull } + if$ + author empty$ editor empty$ AND + { before.all 'output.state := } + { set.colon.after } + if$ + format.btitle.vol "title" output.check + format.edition output + format.address.publisher.year "publisher" output.check + new.sentence + format.series.number.din output + isbn set.period.dash.check + format.isbn.issn output + } + { format.book.crossref output.nonnull } + if$ + part.of.sentence + format.pages output + note set.period.dash.check + note output + fin.entry +} + FUNCTION {incollection} { output.bibitem format.authors "author" output.check set.colon.after format.title "title" output.check + format.version.url output + type empty$ NOT + { type #-1 #4 substring$ "mail" = + type #1 #4 substring$ "Mail" = + OR + 'skip$ + { format.online.lastcheck } + if$ + } + { format.online.lastcheck } + if$ crossref missing$ { format.in.ed.booktitle.din "booktitle" output.check format.edition output format.address.publisher.year "publisher" output.check + format.maillist.url output + format.maillist.lastcheck new.sentence format.series.number.din output - note set.period.dash.check - note output - isbn set.period.dash.check - issn set.period.dash.check - format.isbn.issn output - part.of.sentence - format.chapter.pages "pages" output.check - } - { format.incoll.inproc.crossref output.nonnull - note set.period.dash.check - note output + doi set.period.dash.check + urn set.period.dash.check + format.doi.urn output isbn set.period.dash.check issn set.period.dash.check format.isbn.issn output } - if$ - fin.entry + { format.incoll.inproc.crossref output.nonnull } + if$ + part.of.sentence + format.chapter.pages "pages" output.check + note set.period.dash.check + note output + fin.entry } -%% geaendert 22/2/94, 15/11/96 (Hinweis v. Alin Shindun, Uni Siegen) + FUNCTION {inproceedings} { output.bibitem format.authors "author" output.check @@ -994,101 +1442,112 @@ FUNCTION {inproceedings} crossref missing$ { format.in.ed.booktitle.din "booktitle" output.check address empty$ - { organization new.sentence.checka - organization output + { organization new.sentence.checka + organization output part.of.sentence format.address.publisher.year output - } - { format.address.publisher.year "publisher" output.check } + } + { format.address.publisher.year "publisher" output.check } if$ new.sentence - series empty$ %%neu nach Hinweis v. Alin Shindun, 15/11/96 + series empty$ 'skip$ { format.series.number.din output } if$ - note set.period.dash.check - note output - isbn set.period.dash.check - issn set.period.dash.check - format.isbn.issn output - part.of.sentence - format.pages output - } - { format.incoll.inproc.crossref output.nonnull - note set.period.dash.check - note output isbn set.period.dash.check issn set.period.dash.check format.isbn.issn output } - if$ - fin.entry -} - -FUNCTION {conference} { inproceedings }%% nach Patashnik, wg US-Kompatibilitaet - -%% geaendert, 11/6/99 -FUNCTION {manual} -{ output.bibitem - author empty$ - { organization empty$ - { title empty$ - 'skip$ - {format.btitle "title" output.check } - if$ - } - { organization output.nonnull - set.colon.after - format.btitle "title" output.check - } - if$ - } - { format.authors output.nonnull - set.colon.after - format.btitle "title" output.check - } + { format.incoll.inproc.crossref output.nonnull } if$ - format.edition "edition" output.check - author empty$ - { organization empty$ - { address output - part.of.sentence - } - 'skip$ - if$ - } - { address ": " * organization * output - part.of.sentence - } - if$ - format.date output - pages set.period.dash.check - format.pages.book output + part.of.sentence + format.pages "pages" output.check note set.period.dash.check note output fin.entry } -%% MASTERSTHESIS ersetzt zugleich PHDTHESIS !! KFL, 17/2/94 -%% Ausgabe-Standard ist "Diplomarbeit", fuer andere Abschlussarbeiten -%% bei der Erfassung TYPE="anderer Typ" eingeben. -%% z.B. TYPE={Dissertation}, TYPE={Diss.}, TYPE={Habil.}, TYPE={Magisterarb.} -%% +FUNCTION {conference} { inproceedings }%% nach Patashnik, wg US-Kompatibilitaet + +FUNCTION {manual} +{ output.bibitem + author empty$ + { organization empty$ + { title empty$ + 'skip$ + {format.btitle "title" output.check } + if$ + } + 'skip$ + if$ + } + 'skip$ + if$ + format.authors.organization output.nonnull + set.colon.after + format.btitle "title" output.check + format.edition "edition" output.check + author empty$ organization empty$ AND + { address "address" output.check + part.of.sentence + } + { organization empty$ + { address "address" output.check + part.of.sentence + } + { address ": " * organization * output + part.of.sentence + } + if$ + } + if$ + format.date output + number empty$ + 'skip$ + { "(" number * ") " * output } + if$ + pages empty$ + { skip$ } + { pages set.period.dash.check + pages format.bkpages.collat.check output + } + if$ + format.doi output + format.url output + format.online.lastcheck + note set.period.dash.check + note output + fin.entry +} + +%% Standard ist "Diplomarbeit", anderes mit TYPE="anderer Typ" erfassen! +%% z.B. TYPE={Hausarbeit}, TYPE={Diss.}, TYPE={Habil.}, TYPE={Magisterarb.} FUNCTION {mastersthesis} { output.bibitem format.authors "author" output.check set.colon.after format.btitle "title" output.check address output - part.of.sentence + part.of.sentence school "school" output.check part.of.sentence - "Diplomarbeit" format.thesis.type output.nonnull + "Diplomarbeit" format.thesis.tr.type output.nonnull part.of.sentence format.date "year" output.check -%% pages new.sentence.checka - pages set.period.dash.check - format.pages.book output + format.url output + format.online.lastcheck +%% format.digital.resource.type + doi set.period.dash.check + urn set.period.dash.check + format.doi.urn output +%% pages set.period.dash.check +%% format.pages.book output + pages empty$ + { skip$ } + { pages set.period.dash.check + pages format.bkpages.collat.check output + } + if$ note set.period.dash.check note output fin.entry @@ -1100,75 +1559,174 @@ FUNCTION {phdthesis} %% {mastersthesis}% ist identisch bis auf Standardwert, s. set.colon.after format.btitle "title" output.check address output - part.of.sentence + part.of.sentence school "school" output.check part.of.sentence - "Diss." format.thesis.type output.nonnull % koennte auch `Dissertation' sein + "Diss." format.thesis.tr.type output.nonnull % koennte auch `Dissertation' sein part.of.sentence format.date "year" output.check - pages set.period.dash.check - format.pages.book output + format.url output + format.online.lastcheck +%% format.digital.resource.type + doi set.period.dash.check + urn set.period.dash.check + format.doi.urn output + pages empty$ + { skip$ } + { pages set.period.dash.check + pages format.bkpages.collat.check output + } + if$ +%% pages set.period.dash.check +%% format.pages.book output note set.period.dash.check note output fin.entry } -%% hiermit werden u.a. Normen erfasst + +%% Normen, Vornormen, Schutzrechte (Patente) werden hiermit erfasst; +%% (z.Zt. auch noch Internetressourcen) +%% das type-Feld uebernimmt eine wichtige Steuerfunktion: FUNCTION {misc} { output.bibitem - note empty$ - { title empty$ - { "" } - { format.authors format.editors output.nonnull - format.btitle output - howpublished output - format.date output - } - if$ - } - { note duplicate$ #1 #4 substring$ "Norm" = - { output new.sentence - format.date output - format.title output - } - { pop$ "" - author empty$ - { editor empty$ - { organization empty$ - { 'skip$ } - { format.editors.organization output.nonnull - set.colon.after } - if$ - } - { format.editors format.editors.organization output.nonnull - set.colon.after } - if$ - } - { format.authors format.editors output.nonnull - set.colon.after } - if$ - format.btitle output - howpublished output - format.date output + type missing$ not + { type duplicate$ #1 #4 substring$ "Norm" = + type #1 #4 substring$ "Vorn" = OR + { " " * + format.number * output new.sentence - format.misc.series output%% neu 16/6/99 + format.date output + title empty$ + { skip$ } + { add.period$ new.sentence } + if$ + format.btitle "title" output.check note set.period.dash.check note output } + { duplicate$ #1 #6 substring$ "Schutz" = + { " " * format.number * output + new.sentence + "(" * format.date ")" * output + add.period$ new.sentence + format.authors.organization add.period$ output + note output + } + %% wenn irgendein anderer Typ eingetragen ist + { pop$ pop$ "" + title empty$ + { note empty$ + { url empty$ + { "there's no relevant field in " cite$ warning$ + pop$ "" + } + { format.url output }%%% + if$ + } + { note " " * output.nonnull } + if$ + } + { author empty$ + { editor empty$ + { organization empty$ + { skip$ } + { format.editors.organization output.nonnull + set.colon.after + } + if$ + } + { format.editors format.editors.organization + output.nonnull set.colon.after + } + if$ + } + { format.authors format.editors output.nonnull + set.colon.after + } + if$ + format.btitle output.nonnull + url empty$ + { format.edition output + format.howpublished output} + { format.howpublished output + format.edition.or.date output + format.url output + } + if$ + format.online.lastcheck +%% format.lastchecked.or.type + new.sentence + format.misc.series output +%% note set.period.dash.check + note output + } + if$ + } if$ + } + if$ } - if$ - fin.entry + %% wenn es keinen type gibt + { title empty$ + { note empty$ + { url empty$ + { "there's no relevant field in " cite$ warning$ + pop$ "" + } + { format.url output }%%% das waere e. reine URL + if$ + } + { note " " * output.nonnull + %% format.url format.date output + } + if$ + } + { author empty$ + { editor empty$ + { organization empty$ + { skip$ } + { format.editors.organization output.nonnull + set.colon.after + } + if$ + } + { format.editors format.editors.organization + output.nonnull set.colon.after + } + if$ + } + { format.authors format.editors output.nonnull + set.colon.after + } + if$ + format.btitle output.nonnull + url empty$ + { format.edition output + format.howpublished output} + { format.howpublished output + format.url output + format.edition.or.date output + format.online.lastcheck +%% format.lastchecked.or.type + } + if$ + new.sentence + format.misc.series output + note set.period.dash.check + note output + } + if$ + } + if$ + fin.entry } -FUNCTION {booklet} {misc}%% booklet ist nach dt. Vorgehensweise oft ueberfluessig - -%% geaendert 21/5/99 FUNCTION {proceedings} { output.bibitem editor empty$ { organization empty$ - { "" } + { "empty organization and editor in " cite$ * warning$ } { organization " (Veranst.)" * output } if$ } @@ -1177,59 +1735,78 @@ FUNCTION {proceedings} set.colon.after format.btitle "title" output.check volume empty$ - { "" output.nonnull } + { skip$ } { "{\textnormal{Bd.}}" volume tie.or.space.connect emphasize "volume" output.check } if$ format.address.publisher.year "publisher" output.check new.sentence format.series.number.din output.nonnull - pages set.period.dash.check - format.pages.book output - note set.period.dash.check - note output + pages empty$ + { skip$ } + { pages set.period.dash.check + pages format.bkpages.collat.check output + } + if$ isbn set.period.dash.check issn set.period.dash.check format.isbn.issn output + note set.period.dash.check + note output fin.entry } -%% geaendert 23/2/94 auch fuer Firmenschriften u."a. zu benutzen FUNCTION {techreport} { output.bibitem author empty$ - { format.editors "author and editor" output.check } + { format.editors "author and editor" output.check + format.tr.institution output.nonnull } { format.authors format.editors output.nonnull } if$ set.colon.after format.title "title" output.check - institution new.sentence.checka institution empty$ 'skip$ - { " / " institution * output.nonnull } + { author empty$ editor empty$ AND + 'skip$ + { institution new.sentence.checka + "/ " institution * output.nonnull + } + if$ + } if$ + format.version.url output + format.online.lastcheck format.address.publisher.year output number new.sentence.checka - format.tr.number.din "number" output.check -%% new.sentence - pages set.period.dash.check - format.pages.book output - note "note" output.check + format.tr.series.or.number "number" output.check + "Forschungsbericht" format.thesis.tr.type set.period.dash.check + "Forschungsbericht" format.thesis.tr.type output +%% format.digital.resource.type + pages empty$ + { skip$ } + { pages set.period.dash.check + pages format.bkpages.collat.check output + } + if$ isbn set.period.dash.check issn set.period.dash.check format.isbn.issn output + note set.period.dash.check + note "note" output.check fin.entry } -FUNCTION {unpublished} {misc}%% author, title, note muessen sein! howpublished -%% %% entfaellt natuerlich +FUNCTION {unpublished} {misc}%% AUTHOR, TITLE, NOTE muessen sein! +%% andere Felder sind optional + FUNCTION {default.type} { misc } + MACRO {jan} {"Januar"} MACRO {feb} {"Februar"} MACRO {mar} {"M{\^^b a}rz"} -%% nach Bernd Raichle, Febr. 1999 MACRO {apr} {"April"} @@ -1255,29 +1832,12 @@ MACRO {dez} {"Dezember"} MACRO {dec} {"Dezember"} -%% stillgelegte Beispiele fuer den Gebrauch von Kuerzeln (hier Zs-Titel). +%%$$$ stillgelegte Beispiele fuer den Gebrauch von Kuerzeln (hier Zs-Titel). %%MACRO {acmcs} {"ACM Computing Surveys"} %%MACRO {acta} {"Acta Informatica"} -%%MACRO {cacm} {"Communications of the ACM"} - -%%MACRO {ibmjrd} {"IBM Journal of Research and Development"} - -%%MACRO {ibmsj} {"IBM Systems Journal"} - -%%MACRO {ieeese} {"IEEE Transactions on Software Engineering"} - -%%MACRO {ieeetc} {"IEEE Transactions on Computers"} - -%%MACRO {ieeetcad} -%% {"IEEE Transactions on Computer-Aided Design of Integrated Circuits"} - -%%MACRO {ipl} {"Information Processing Letters"} - -%%MACRO {jacm} {"Journal of the ACM"} - READ FUNCTION {sortify} @@ -1285,8 +1845,6 @@ FUNCTION {sortify} "l" change.case$ } -INTEGERS { len } - FUNCTION {chop.word} { 's := 'len := @@ -1296,8 +1854,6 @@ FUNCTION {chop.word} if$ } -INTEGERS { et.al.char.used } - FUNCTION {initialize.et.al.char.used} { #0 'et.al.char.used := } @@ -1309,57 +1865,49 @@ FUNCTION {format.lab.names} s num.names$ 'numnames := numnames #1 > { numnames #4 > - { #3 'namesleft := } - { numnames 'namesleft := } + { #3 'namesleft := } + { numnames 'namesleft := } if$ #1 'nameptr := "" - { namesleft #0 > } - { nameptr numnames = - { s nameptr "{ff }{vv }{ll}{ jj}" format.name$ "others" = -%% { "\," * %% kein besonderes Zeichen fuer "others" i. label - { "{\etalchar{+}}" * %% ein plus-Zeichen (+) fuer "others"! - #1 'et.al.char.used := - } -%% { s nameptr "{v{}}{l{}}" format.name$ * } - { s nameptr "{l{}}" format.name$ * } - if$ - } -%% { s nameptr "{v{}}{l{}}" format.name$ * } - { s nameptr "{l{}}" format.name$ * } - if$ - nameptr #1 + 'nameptr := - namesleft #1 - 'namesleft := - } + { namesleft #0 > } + { nameptr numnames = + { s nameptr "{ff }{vv }{ll}{ jj}" format.name$ "others" = +%% { "\," * %% kein besonderes Zeichen fuer "others" i. label + { "{\etalchar{+}}" * %% ein plus-Zeichen (+) fuer "others"! + #1 'et.al.char.used := + } + { s nameptr "{l{}}" format.name$ * } + if$ + } + { s nameptr "{l{}}" format.name$ * } + if$ + nameptr #1 + 'nameptr := + namesleft #1 - 'namesleft := + } while$ numnames #4 > %% { "\," * %% s. Bemerkung oben - { "{\etalchar{+}}" * - #1 'et.al.char.used := - } - 'skip$ + { "{\etalchar{+}}" * + #1 'et.al.char.used := + } + 'skip$ if$ } -%% { s #1 "{v{}}{l{}}" format.name$ { s #1 "{l{}}" format.name$ duplicate$ text.length$ #2 < - { pop$ s #1 "{ll}" format.name$ #3 text.prefix$ } %% vgl. Anmerkung! - 'skip$ + { pop$ s #1 "{ll}" format.name$ #3 text.prefix$ } %% vgl. Anmerkung! + 'skip$ if$ } if$ } -%% Anmerkung, Lo 14/12/95: -%% wenn man in der letzten label-Bearbeitung #4 statt #3 setzt, dann werden -%% auch Umlaute oder an 3. Stelle im Namen korrekt in das label genommen. -%% Tip: Aendere diese Zahl nur, wenn in einer Lit.-Liste der Umlautsonderfall -%% stoerend auffaellt. FUNCTION {author.key.label} { author empty$ { key empty$ - { cite$ #1 #3 substring$ } - { key #3 text.prefix$ } + { cite$ #1 #3 substring$ } + { key #3 text.prefix$ } if$ } { author format.lab.names } @@ -1369,12 +1917,12 @@ FUNCTION {author.key.label} FUNCTION {author.editor.key.label} { author empty$ { editor empty$ - { key empty$ - { cite$ #1 #3 substring$ } - { key #3 text.prefix$ } - if$ - } - { editor format.lab.names } + { key empty$ + { cite$ #1 #3 substring$ } + { key #3 text.prefix$ } + if$ + } + { editor format.lab.names } if$ } { author format.lab.names } @@ -1384,30 +1932,27 @@ FUNCTION {author.editor.key.label} FUNCTION {author.key.organization.label} { author empty$ { key empty$ - { organization empty$ - { cite$ #1 #3 substring$ } - { "The " #4 organization chop.word #3 text.prefix$ } - if$ - } - { key #3 text.prefix$ } + { organization empty$ + { cite$ #1 #3 substring$ } + { "The " #4 organization chop.word #3 text.prefix$ } + if$ + } + { key #3 text.prefix$ } if$ } { author format.lab.names } if$ } -%% neu 19/5/99 damit eigene labels fuer Konferenzen erzeugt werden koennen, -%% darf man zusaetzlich auch ein key-Feld eingeben. Das produziert -%% dann vorrangig das label. + FUNCTION {editor.key.organization.label} { editor empty$ { key empty$ - { organization empty$ - { cite$ #1 #3 substring$ } - { "The " #4 organization chop.word organization } %% Lo, 26/1/98 -%% { "The " #4 organization chop.word #3 text.prefix$ } - if$ - } - { key #5 text.prefix$ }%% man kann Laenge des key einstellen + { organization empty$ + { cite$ #1 #3 substring$ } + { "The " #4 organization chop.word organization } + if$ + } + { key #5 text.prefix$ }%% man kann Laenge des key einstellen if$ } { key empty$%% wenn key vh., dann macht er das label! Lo,18/5/99 @@ -1420,16 +1965,17 @@ FUNCTION {editor.key.organization.label} FUNCTION {calc.label} { type$ "book" = + type$ "booklet" = type$ "inbook" = - or + or or 'author.editor.key.label { type$ "proceedings" = - 'editor.key.organization.label - { type$ "manual" = - 'author.key.organization.label - 'author.key.label - if$ - } + 'editor.key.organization.label + { type$ "manual" = + 'author.key.organization.label + 'author.key.label + if$ + } if$ } if$ @@ -1450,19 +1996,13 @@ FUNCTION {sort.format.names} numnames 'namesleft := { namesleft #0 > } { nameptr #1 > - { " " * } - 'skip$ + { " " * } + 'skip$ if$ -% s nameptr "{vv{ } }{ll{ }}{ ff{ }}{ jj{ }}" format.name$ 't := -% -% Zeile geaendert, damit die Namenszusaetze wie von, de usw nach deutscher -% Norm richtig einsortiert werden. 27.10.94 Lueddecke -% s nameptr "{ll{ }}{ ff{ }}{ vv{ }}{ jj{ }}" format.name$ 't := nameptr numnames = t "others" = and - { "[u.~a.]" * } - %% { "et al" * }% Geschmackssache - { t sortify * } + { ua.etal * } + { t sortify * } if$ nameptr #1 + 'nameptr := namesleft #1 - 'namesleft := @@ -1478,7 +2018,7 @@ FUNCTION {sort.format.title} "Die " #4 "Das " #4 "Ein " #4 - "Eine " #5 + "Eine " #5 "The " #4 t chop.word chop.word chop.word @@ -1494,10 +2034,10 @@ FUNCTION {sort.format.title} FUNCTION {author.sort} { author empty$ { key empty$ - { "to sort, need author or key in " cite$ * warning$ - "" - } - { key sortify } + { "to sort, need author or key in " cite$ * warning$ + "" + } + { key sortify } if$ } { author sort.format.names } @@ -1507,14 +2047,14 @@ FUNCTION {author.sort} FUNCTION {author.editor.sort} { author empty$ { editor empty$ - { key empty$ - { "to sort, need author, editor, or key in " cite$ * warning$ - "" - } - { key sortify } - if$ - } - { editor sort.format.names } + { key empty$ + { "to sort, need author, editor, or key in " cite$ * warning$ + "" + } + { key sortify } + if$ + } + { editor sort.format.names } if$ } { author sort.format.names } @@ -1524,14 +2064,14 @@ FUNCTION {author.editor.sort} FUNCTION {author.organization.sort} { author empty$ { organization empty$ - { key empty$ - { "to sort, need author, organization, or key in " cite$ * warning$ - "" - } - { key sortify } - if$ - } - { "The " #4 organization chop.word sortify } + { key empty$ + { "to sort, need author, organization, or key in " cite$ * warning$ + "" + } + { key sortify } + if$ + } + { "The " #4 organization chop.word sortify } if$ } { author sort.format.names } @@ -1541,14 +2081,14 @@ FUNCTION {author.organization.sort} FUNCTION {editor.organization.sort} { editor empty$ { organization empty$ - { key empty$ - { "to sort, need editor, organization, or key in " cite$ * warning$ - "" - } - { key sortify } - if$ - } - { "The " #4 organization chop.word sortify } + { key empty$ + { "to sort, need editor, organization, or key in " cite$ * warning$ + "" + } + { key sortify } + if$ + } + { "The " #4 organization chop.word sortify } if$ } { editor sort.format.names } @@ -1561,16 +2101,17 @@ FUNCTION {presort} " " * type$ "book" = + type$ "booklet" = type$ "inbook" = - or + or or 'author.editor.sort { type$ "proceedings" = - 'editor.organization.sort - { type$ "manual" = - 'author.organization.sort - 'author.sort - if$ - } + 'editor.organization.sort + { type$ "manual" = + 'author.organization.sort + 'author.sort + if$ + } if$ } if$ @@ -1592,10 +2133,6 @@ ITERATE {presort} SORT -STRINGS { longest.label last.sort.label next.extra } - -INTEGERS { longest.label.width last.extra.num } - FUNCTION {initialize.longest.label} { "" 'longest.label := #0 int.to.chr$ 'last.sort.label := @@ -1637,7 +2174,7 @@ ITERATE {forward.pass} REVERSE {reverse.pass} -FUNCTION {begin.bib}%%lt. Original wiederhergestellt 4/1/96 +FUNCTION {begin.bib} { et.al.char.used { "\newcommand{\etalchar}[1]{$^{#1}$}" write$ newline$ } 'skip$ @@ -1647,6 +2184,18 @@ FUNCTION {begin.bib}%%lt. Original wiederhergestellt 4/1/96 { preamble$ write$ newline$ } if$ "\begin{thebibliography}{" longest.label * "}" * write$ newline$ + newline$ + "% this bibliography is generated by alphadin.bst [8.2] from 2005-12-21" + write$ newline$ + newline$ + "\providecommand{\url}[1]{\texttt{#1}}" + write$ newline$ + "\expandafter\ifx\csname urlstyle\endcsname\relax" + write$ newline$ + " \providecommand{\doi}[1]{doi: #1}\else" + write$ newline$ + " \providecommand{\doi}{doi: \begingroup \urlstyle{rm}\Url}\fi" + write$ newline$ } EXECUTE {begin.bib} @@ -1660,6 +2209,4 @@ FUNCTION {end.bib} "\end{thebibliography}" write$ newline$ } -EXECUTE {end.bib} - -%% Ende von ALPHADIN.BST KFL, 23/11/99 +EXECUTE {end.bib} \ No newline at end of file diff --git a/report/appandix.tex b/report/appandix.tex new file mode 100644 index 0000000..c46607e --- /dev/null +++ b/report/appandix.tex @@ -0,0 +1,6 @@ +\appendix + +\subsection{Initsystem} +\label{sec:initsysteme} + +Prozess, der in einem Betriebsystem alle nachfolgenden Prozesse verwaltet und startet. diff --git a/report/comparison.tex b/report/comparison.tex new file mode 100644 index 0000000..49ca7b2 --- /dev/null +++ b/report/comparison.tex @@ -0,0 +1,499 @@ +\subsection{Funktionsweise von Chef} +\label{ssub:funktionsweise_von_chef} + +\href{http://www.getchef.com/chef/}{Chef} ist ein Framework, welches eine +automatisierte Serverkonfiguration und -verwaltung ermöglicht. Chef übernimmt +dabei Aufgaben der Provisionierung (Installation der grundlegenden Dienste, +Ressourcenverwaltung, Einrichtung und Konfiguration von Middleware) bis hin zum +Deployment (Verteilung der eigentlichen Business-Anwendung). +Der Endanwender beschreibt hierbei die Systemressourcen und ihre Zustände in der +Programmiersprache \href{https://www.ruby-lang.org/}{Ruby}. Diese Definitionen +werden von dem Programm \texttt{Chef-Client} eingelesen und in notwendige Aktionen +übersetzt, welche ausgeführt werden müssen, um den beschriebenen Zustand +umzusetzen. + +Die Gesamtheit aller Definitionen/Einstellungen nennt man das \texttt{Chef-Repo}. +Ein solches untergliedert sich in mehrere \texttt{Cookbooks}\label{cookbook}. Ein +Cookbook ist die Grundverwaltungseinheit in Chef. Es erfüllt einen bestimmten +Teilaspekt des Systems (z.B. die Einrichtung eines Webservers +\href{https://github.com/opscode-cookbooks/apache2}{Apache}). Cookbooks können +versioniert werden. Es können Abhängigkeiten zwischen mehreren Cookbooks +angegeben werden. + +Physikalische oder virtuelle Maschinen werden als \texttt{Nodes} bezeichnet. +Der Node werden \texttt{Attribute}, \texttt{Rollen} und Cookbooks zugewiesen. +Rollen und Cookbooks werden dazu in die sogenannte \texttt{Run-List} eingefügt. +Diese gibt die Reihenfolge an, in welcher Rollen und Cookbooks angewendet +werden. Rollen bieten eine Möglichkeit, Nodes zu gruppieren, welche die gleichen +Aufgaben in einer Organisation erfüllen (z.B. Webserver). + +Es gibt mehrere Möglichkeiten \texttt{Chef} zu betreiben: + +\begin{description} + \item[Chef-Solo] Chef-Solo ist die einfachste Ausführungsform. Alle nötigen + Daten werden aus einem lokalen Verzeichnis geladen. Im Gegensatz zu + \texttt{Chef-Server} und \texttt{Enterprise-Chef} wird bei Chef-Solo das + Programm \texttt{chef-solo} an Stelle von \texttt{chef-client} ausgeführt. Diese + Form wurde für die Umsetzung der Aufgabenstellung in + Abschnitt~\ref{sub:einrichtung-der-netzwerkdienste} gewählt. + \item[Chef-Server] Hierbei authentifiziert sich \texttt{Chef-Client} über eine + \texttt{REST-Api} zu einem \texttt{Chef-Server} mittels eines privaten + RSA-Keys. Der Server verwaltet zentral das Chef-Repo. Der Chef-Client + bekommt von diesem alle nötigen Informationen für die zu provisionierende + \texttt{Node}. Chef-Server bietet eine webbasierte GUI für die + Administration an. Die Attribute aller Nodes sind über die eingebaute + Suchmaschine \href{https://lucene.apache.org/solr/}{\texttt{Solr}} + durchsuchbar. + \item[Enterprise-Chef/Hosted-Enterprise-Chef] Enterprise-Chef bietet + zusätzlich zu den Funktionen der Opensource-Version Chef-Server eine + rollenbasierte Benutzerverwaltung, bessere Überwachung, eine verbesserte + Weboberfläche sowie Push-Deployment an. Während bei Hosted-Enterprise-Chef + die Firma Chef die Infrastruktur des Chef-Server betreibt und die Skalierung + des Dienstes übernimmt, befindet sich im Falle von Enterprise-Chef der + Server in der eigenen Organisation~\cite{chefenterprise}. +\end{description} + +\subsubsection{Aufbau eines Cookbooks} +\label{aufbau_eines_cookbook} + +\begin{figure}[h] + \centering + \caption{Ordnerstruktur eines Cookbooks am Beispiel des \href{https://github.com/opscode-cookbooks/apt}{apt}-Cookbooks dargestellt.} + \begin{tikzpicture} + \treeroot{apt-2.3.4} + \altentry{attributes}{1} + \altentry{default.rb}{2} + \altentry{files}{1} + \altentry{default}{2} + \altentry{apt-proxy-v2.conf}{3} + \altentry{libraries}{1} + \altentry{helpers.rb}{2} + \altentry{network.rb}{2} + \altentry{providers}{1} + \altentry{preference.rb}{2} + \altentry{repository.rb}{2} + \altentry{recipes}{1} + \altentry{cacher-client.rb}{2} + \altentry{cacher-ng.rb}{2} + \altentry{default.rb}{2} + \altentry{resources}{1} + \altentry{preference.rb}{2} + \altentry{repository.rb}{2} + \altentry{templates}{1} + \altentry{debian-6.0}{2} + \altentry{default}{2} + \altentry{01proxy.erb}{3} + \altentry{acng.conf.erb}{3} + \altentry{ubuntu-10.04}{2} + \altentry{acng.conf.erb}{3} + \altentry{CHANGELOG}{1} + \altentry{metadata.json}{1} + \altentry{metadata.rb}{1} + \altentry{README.md}{1} + \end{tikzpicture} +\end{figure} + +Die Verzeichnisnamen und die Datei \texttt{metadata.rb} sind fest vorgeben. +Jedes Verzeichnis hat seine eigene Funktion. Dies hat den Vorteil, das man sich +schnell in neuen Cookbooks zurecht findet. + +\begin{description} + \item[attributes] Attribute sind einfache Schlüssel-Wert-Beziehungen und + setzen Standardwerte für das Cookbook. Die Schlüssel sind hierarchisch + organisiert. In der Regel ist die höchste Ebene der Name des Cookbooks (z.B. + \texttt{normal.mysql.client.packages}). Werte können Strings, Zahlen oder + Arrays sein. Die gesetzten Attribute können in Rollen, Nodes oder von + anderen Cookbooks überschrieben werden. Hierfür werden die Attribute mit den + verschiedenen Prioritäten \texttt{default}, \texttt{force\_default}, + \texttt{normal} und \texttt{override} (aufsteigender Wertigkeit) gesetzt. + Attribute mit einer höheren Priorität überschreiben den Wert von Attributen + mit einer niedrigeren Priorität. + \item[files] In diesem Verzeichnis können statische Dateien eingefügt werden, + welche auf dem Zielsystem in das entsprechende Verzeichnis kopiert werden + können. + \item[libraries] In diesem Pfad können Hilfsfunktionen und + Spracherweiterungen definiert werden. + \item[resources] Ressourcen beschreiben die Bestandteile eines Systems. Eine + Ressource kann z.B. eine Datei, ein Prozess oder ein Paket sein. Man + beschreibt, welchen Zustand (Action in Chef genannt) diese Ressource haben + soll und Chef versucht, diesen Zustand herzustellen. Chef liefert bereits + viele wichtige Ressourcen mit. In Cookbooks können darüber hinaus eigene + Ressourcen definiert werden. + \item[providers] Während Ressourcen nur die Schnittstelle mit allen Attribute + beschreiben, die gesetzt werden können, ist der Provider eine konkrete + Implementierung. Deswegen muss für jede Ressource mindestens ein Provider + existieren. Es kann mehrere Provider für eine Ressource geben, um zum + Beispiel mehrere Plattformenvarianten oder Betriebssysteme abdecken zu + können (z.B. bei Paketmanagern oder Initsystemen - \ref{sec:initsysteme}). In + eigenen Cookbooks erstellte Ressourcen/Provider nennt man LWRP + (englische Abkürzung für \texttt{Lightweight Resources and Providers}). + \item[recipes] In Recipes werden Ressourcen instantiiert, welche nötig sind, + um das gewünschte Ziel zu erreichen. Dabei können Abhängigkeiten zwischen + Recipes angegeben werden. + \item[definitions] Ressourcen, welche häufiger in verschiedenen Recipes in + ähnlicher Form benötigt werden, können in eine \texttt{Definition} + ausgelagert werden. Ein Beispiel ist das Generieren eines SSH-Schlüssels + für verschiedene Nutzer auf dem System. Für komplexere Konstrukte sollten + jedoch LWRPs (siehe oben) bevorzugt werden. + \item[templates] Häufig werden dynamisch generierte Dateien benötigt, um zum + Beispiel Konfigurationsdateien zu erzeugen. In Chef wird für diesen Zweck + die Templatesprache eRuby (Embedded Ruby) verwendet. In ERB-Templates wird + Rubyquellcode ausgeführt, der sich zwischen den Tags \texttt{<\%} und \texttt{\%>} + befindet. Dies erlaubt es einerseits den Inhalt von Variablen oder den + Rückgabewert von Methoden einzufügen, andererseits können in Templates + Kontrollstrukturen wie If-Statements und Schleifen verwendet werden. + \item[metadata.rb] In der Datei \texttt{metadata.rb} kann der Name des Cookbook, + die eigene Version, eine Beschreibung sowie Abhängigkeiten zu anderen + Cookbooks angegeben werden. +\end{description} + +\begin{lstlisting}[caption={Beispiel ERB-Template:},label={lst:erb-templates}] + Diese Zeile wird beim Rendern ohne Aenderung uebernommen + <%# Ein Kommentar%> + + Diese Node heisst: <%= @node.name %> + + <% if node[:platform] == "ubuntu" -%> <%# Bedingte Anweisung %> + Diese Zeile erscheint auf Ubuntu-basierten Nodes. + <% else %> + Diese Zeile erscheint auf nicht Ubuntu-basierten Nodes. + <% end -%> + + <%# Listet in einer Schleife alle Blockdevices des Node auf %> + <% @node.block_device.each do |block_device, attributes| %> + <%= block_device %>: <%= attributes.join(", ") %> + <% end %> +\end{lstlisting} + +\subsubsection{Ablauf einer Provisionierung} +\label{ablauf_einer_provisionierung} +Der genaue Ablauf wurde der Onlinedokumentation (\cite{chefrun}) von Chef +entnommen. Wie schon zu Beginn erwähnt, wird die Provisionierung von einem +Programm namens \texttt{Chef-Client} durchgeführt. + +Je nach gewählter Umgebung kann dieser unterschiedlich gestartet werden: + +\begin{itemize} + \item periodisch vom Scheduler \texttt{Cron} + \item permanent als Systemdienst (z.B. bei Enterprise Chef) + \item manuell (z.B. bei Vagrant - siehe~\ref{sub:einrichtung-der-netzwerkdienste}) +\end{itemize} + +Als erstes lädt dieser Prozess seine Konfiguration aus der Datei +\texttt{client.rb}. In dieser stehen beispielsweise die URL des Chef-Server und +der Name des Node. Letzteres ist wichtig, um die Node in Chef einordnen zu +können und die richtigen Einstellungen zuzuweisen. Alternativ kann der Name auch +von der Bibliothek \href{http://docs.opscode.com/ohai.html}{Ohai} gesetzt +werden, in dem auf den Hostnamen oder der FQDN (Fully Qualified Domain Name) +zurückgegriffen wird. Ohai sammelt systemrelevante Daten wie Details über +Hardwarekomponenten (Anzahl der CPUs, Größe und Art des RAMs, Netzwerkanbindung, +Festplatten/SSDs, \dots), Informationen über die Plattform (Art des +Betriebssystems und sowie dessen Version, installierte Anwendungssoftware) und +die laufenden Prozesse. Diese Informationen sind durch eigene Ohai-Plugins +erweiterbar und können im Provisionierungsprozess genutzt werden, um weitere +Entscheidungen zu treffen. Sie sind darüber hinaus auch auf dem Server +gespeichert und für andere Clients abrufbar. + +Nach dem alle Einstellungen eingelesen sind, verbindet sich der Chef-Client mit +dem Chef-Server. Die Authentifizierung erfolgt über dem vorher auf dem Node +abgelegten RSA-Schlüssel. Für Administratoren gibt es einen Validator-Key. Mit +diesem kann ein Node auf dem Server registriert werden und so ein +Client-Schlüssel generiert werden. + +Anschließend werden zuvor gesetzte Attribute und die Run-List vom Server +übertragen. Im 1. Durchlauf oder bei Verwendung von Chef-Solo sind diese Daten +nicht vorhanden. Stattdessen kann eine Datei im JSON-Format angegeben werden, +um die Attribute und die Run-List für die Node zu spezifizieren. Außerdem ist +es möglich eine Run-List auf dem Chef-Server einzustellen, welche ausgeführt +wird, wenn die Node keine eigene Run-List besitzt. + +Durch Auswertung der eingebunden Rollen und Recipes werden die benötigen +Cookbooks ermittelt. Der Client fordert eine Liste aller darin enthaltenen +Dateien und deren Checksumme an. Alle geänderten oder neuen Dateien werden +heruntergeladen und lokal gespeichert. + +Nun werden die Attribute zurückgesetzt und aus den Cookbooks, Rollen und dem +Node neu generiert und entsprechend ihrer Priorität gesetzt. Die Ressourcen aus +den Cookbooks werden geladen und in der Ressource-Collection zusammengefasst. +Nachdem alle Definitionen und Bibliotheken geladen wurden, werden schließlich die +Recipes verarbeitet. Die darin erstellten Ressourcen beschreiben das System. Für +jede Ressource wird der Zustand festgelegt. + +Im nächsten Schritt folgt das sogenannte \texttt{Converging} (englisch für +Angleichen). Es werden alle Ressourcen Schritt für Schritt abgearbeitet. Dabei +wird für jede Ressource der für die Plattform zugehörige Provider ausgewählt. +Dieser überprüft den aktuellen Zustand der Ressource und verändert falls +notwendig das System, um den Sollzustand zu erreichen. Zum Schluss überträgt +Chef-Client die aktualisierten Attribute auf den Server, von welchem sie in +\texttt{Solr} indexiert werden. + +Es besteht die Möglichkeit, Handler vor oder nach der Provisionierung auszuführen. +Diese können im Fehlerfall Benachrichtigungen an das Monitoringssystem oder per +Email verschicken. In letzten Abschnitt (\ref{minitest_handler}) wird dieser +Mechanismus genutzt, um Tests auszuführen. + +\subsubsection{Vergleich mit puppet} +\label{vergleich_mit_puppet} + +\paragraph{Historischer Kontext} +Ein ebenfalls weit verbreitetes Konfigurationsmanagementsystem ist Puppet. Es ist +das Ältere der beiden Projekte. Während das erste Puppet-Release bereits im +Jahre 2005 von den Puppet Labs veröffentlicht wurde, erschien Chef erst 4 Jahre später +im Jahr 2009. Chef wurde stark von Puppet beeinflusst. Der Erfinder von Chef, +Adam Jacob, war selbst langjähriger Puppetnutzer, bevor er Chef schrieb. Seine +damalige Firma betreute als Unternehmensberater mehrere Firmen bei der +Provisionierung der Infrastruktur bis hin zum Deployment der Anwendung. Dabei +kam Puppet zum Einsatz. Mit steigender Anzahl der Kunden, wuchs nach Aussagen +von Adam Jacob der Aufwand bei der Verwaltung der Puppet-Konfiguration. Diese +mussten häufig für jeden Kunden stark angepasst oder neu geschrieben werden. Aus +diesem Grund begann er an ein neues Deploymentsystem zu schreiben. Damals trug +es noch den Namen \texttt{Marionette}. Dabei verwendete er, wie schon bei +Puppet, die Programmiersprache Ruby zur Implementierung des Clients. Ein +wichtiges Designziel seines neuen System war es, bessere +Abstraktionsmöglichkeiten zu schaffen, um damit die Wiederverwendbarkeit zu +erhöhen (Quelle: \cite{chefhistory}). Anzumerken ist, dass seit der damals +veröffentlichten Puppetversion +(\href{https://github.com/puppetlabs/puppet/commit/ce964ecb6d6a38cb7fb9f0b13a7e6b2eb4c381c3}{0.24.5}) +neue Funktionen und Spracherweiterungen zu Puppet hinzugefügt wurden, um dieses +Problem zu adressieren. (\cite{puppetlanguagechangelog}) + +\paragraph{Sprache} +Während bei Chef die Konfiguration in Ruby geschrieben wird, besitzt Puppet eine +eigene Konfigurationssprache. Puppet's Sprache ist im Gegensatz zu allgemeinen +verwendeten Sprachen (engl. General-Purpose-Languages, kurz GPL) wie Ruby, Java +oder C/C++ eine domänspezifische Sprache (engl. Domain-Specific-Language - DSL). +Eine DSL ist eine speziell für den Anwendungszweck geschriebene und optimierte +Sprache. Sie enthält häufig Elemente und Ausdrücke, welche es erlauben, Probleme +der Anwendungsdomäne effizient zu lösen. Es wird häufig auf umfangreiche +Standardbibliotheken und Sprachkonstrukte verzichtet, die in GPLs üblich sind. +Puppet's Sprache wurde an das Konfigurationsformat der Überwachungssoftware +Nagios angelehnt (\cite{puppetlanguage}). Sie ist deklarativ gehalten und soll +möglichst einfach erlernbar sein (auch für Administratoren ohne programmiertechnischen +Hintergrund). Der Schwerpunkt liegt auf der Beschreibung von +\texttt{Ressourcen}. Die Sprache besitzt Kontrollstrukturen wie Case- und +If-Statements. Es gibt Datentypen wie \texttt{Strings}, \texttt{Booleans}, +\texttt{Arrays}, \texttt{Reguläre Ausdrücke} und \texttt{Hashes}. Diese können +in Variablen gespeichert werden. Die +\href{https://forge.puppetlabs.com/puppetlabs/stdlib}{Standardbibliothek} von +Puppet stellt Funktionen bereit, um auf diesen Datentypen einfache Operationen +auszuführen. Allerdings ist es nicht möglich, Schleifen auszuführen. (Diese +\href{http://docs.puppetlabs.com/puppet/latest/reference/experiments_lambdas.html}{Funktion} +ist momentan als \texttt{experimentell} markiert). Funktionen können nicht +direkt in Puppet's Sprache definiert werden. Stattdessen werden diese als +Erweiterung des Parsers in Ruby implementiert, was wiederum den Nachteil hat, +dass dafür eine weitere Sprachen erlernt werden muss. Manche Unternehmen und +Organisationen greifen bevorzugt auf Puppet zurück, weil es einfacher ist, neue +Mitarbeiter ohne Rubykenntnisse in diesem Framework zu schulen. Andere wiederum +bevorzugen die Flexibilität von Ruby. Facebook gab dies als einen der Grund an +für einen Umstieg im Jahre 2013 von \texttt{CFEngine2} auf \texttt{Chef 11} +\cite{facebooklikeschef}. + +\paragraph{Communities} +Das strukturelle Gegenstück zu \texttt{Cookbooks} in Chef ist das +\texttt{Modul} in Puppet. Diese werden in der Nutzergemeinschaft entwickelt. Da +Puppet älter ist, ist anzunehmen, dass hierfür mehr Module zur Verfügung +stehen, als Cookbooks für Chef. Die primäre Distributionsquelle ist +\href{https://forge.puppetlabs.com/}{Puppet-Forge}, in dem \textbf{2206} +\href{https://forge.puppetlabs.com/modules?supported=yes}{Modul} zur Verfügung +stehen (Stand: 31.03.2014). Für Chef gibt es eine ähnliche +\href{http://community.opscode.com/}{Community-Seite} mit \textbf{1368} Modulen, +(Stand: 31.03.2014 - ermittelt über die +\href{https://cookbooks.opscode.com/api/v1/cookbooks?start}{API}). Zu einer +weiteren wichtigen Quelle hat sich die Plattform +\href{https://github.com}{Github} für beide Projekte entwickelt. Für einen +Vergleich wurde die Anzahl der Suchtreffer für Projekte, die die Begriffe +``Chef'' und ``Puppet'' in der Suchmaschine auf Github herangezogen. Github +filtert Forks (Abspaltungen) von Projekten aus den Suchergebnissen heraus und +schlüsselt die Ergebnisse nach Programmiersprache auf. Es wurden alle Sprachen +in beiden Projekte mit weniger als 100 Suchtreffer aus Übersichtlichkeitsgründen +nicht in das Diagramm übernommen (siehe Tabelle~\ref{tab:rohdaten}). Eine +Stichproben der Ergebnisse, dass die Suchtreffer sich überwiegend mit den +eigentlichen Projekten Chef und Puppet beschäftigen. Anzumerken ist, dass +Zielgruppe von Puppet überwiegend Systemadminstratoren aus besteht, während Chef +auch von vielen Entwicklern genutzt wird. Letztere verwenden bevorzugt Github. + +\begin{figure}[h] +\pgfplotstableread{ +Puppet Ruby Shell Python Javascript Perl Andere +0 9902 321 148 124 42 260 +7315 3108 751 207 157 137 211 +}\dataset +\definecolor{bblue}{HTML}{4F81BD} +\definecolor{rred}{HTML}{C0504D} +\definecolor{ggreen}{HTML}{9BBB59} +\definecolor{ppurple}{HTML}{9F4C7C} +\begin{tikzpicture} +\begin{axis}[ybar stacked, + width=12cm, + enlarge x limits=0.5, + height=10cm, + ymin=0, + ymax=13500, + scaled x ticks = false, + scaled y ticks = false, + ylabel={Anzahl der Suchtreffer}, + xtick=data, + xticklabels = { + \strut Chef (Gesamt: 10797), + \strut Puppet (Gesamt: 11749) + }, + major x tick style = {opacity=0}, + every node near coord/.append style={ + anchor=west, + rotate=90 + }, + legend entries={Puppet, Ruby, Shell, Python, Javascript, Perl, Andere}, + legend columns=13, + ] + + \addplot[draw=black,fill=rred] table[x index=0,y index=0] \dataset; + \addplot[draw=black,fill=ggreen] table[x index=0,y index=1] \dataset; + \addplot[draw=black,fill=bblue] table[x index=0,y index=2] \dataset; + \addplot[draw=black,fill=ppurple] table[x index=0,y index=3] \dataset; + \addplot[draw=black,fill=magenta] table[x index=0,y index=4] \dataset; + \addplot[draw=black,fill=yellow] table[x index=0,y index=5] \dataset; + \addplot[draw=black,fill=black] table[x index=0,y index=6] \dataset; +\end{axis} +\end{tikzpicture} +\caption{Anzahl der Suchtreffer auf Github aufgeschlüsselt nach +Programmiersprache für die Begriffe ``Chef'' und ``Puppet''.} +\label{tab:rohdaten} +\end{figure} + +\begin{table}[h] +\caption{Ausgangsdaten für das Diagramm} +\begin{tabular}{l|c|c|c|c|c|c|c|c|c|c|c|c} + Sprache & \textbf{Ruby} & \textbf{Puppet} & \textbf{Shell} & \textbf{Python} & \textbf{Javascript} & \textbf{Perl} & PHP & Java & VimL & CSS & C & C++ \\\hline + \textbf{Chef} & 9,902& - & 321 & 148 & 124 & 42 & 56 & 88 & - & 31 & 48& 37 \\\hline + \textbf{Puppet} & 3,108& 7,315 & 751 & 207 & 157 & 137 & 82 & 42 & 64 & 23 & - & - \\ +\end{tabular} +\end{table} + +\vspace{0.5cm} + +Eine weitere wichtige Statistik für Opensource-Projekte ist die Anzahl der +Abonnenten auf den jeweiligen Mailinglisten. Engagierte und aktive +Nutzer/Entwickler abonnieren häufig diese, wodurch sich die Größe der Community +qualitativ vergleichen lassen. + +\begin{description} + \item[chef@lists.opscode.com] Community-Mailingliste, 1620 Abonnenten, Quelle:~\cite{chefcommunitylist}, Stand: 31.03.2014 + \item[chef-dev@lists.opscode.com] Entwickler-Mailingliste, 652 Abonnenten, Quelle:~\cite{chefdeveloperlist}, Stand: 31.03.2014 + \item[puppet-users@googlegroups.com] Community-Mailingliste, \textasciitilde{}7000 Abonnenten, Quelle:~\cite{puppetcommunitylist}, Stand: 01.04.2014 +\end{description} + +Die Anzahl der verfügbaren Module, veröffentlichte Githubprojekte und der +Abonnenten auf den Mailinglisten weisen darauf hin, dass Puppet nach wie vor +eine größere Community hat. + +\paragraph{Funktionsweise} +Anstelle von Recipes werden in Puppet Manifeste geschrieben. Das sind Dateien, +die auf den Suffix .pp enden und sich in dem Ordner \texttt{manifests} im Modul +befinden. Jedes Manifest definiert eine Klasse, eingeleitet durch das +Schlüsselwort \texttt{class}. Der Namen dieser Klasse wird aus dem Modulnamen +und dem Manifest-Namen gebildet. Wenn das Modul \texttt{foo} das Manifest +\texttt{bar} enthält, ist der Name der Klasse \texttt{foo::bar}. Eine Ausnahme +bildet das Manifest \texttt{init.pp}, bei dem die Klasse nur \texttt{bar} lauten +würde. Diese Benennungskonvention wurde in Chef übernommen, um Recipes in +Cookbooks zu referenzieren. Allerdings werden in Recipes keine separaten Objekt +definiert und der ganze Inhalt der Datei bildet das Recipe. + +Eine Klasse in Puppet kann über Parameter konfiguriert werden. Parameter werden +im Kopfteil der Klasse deklariert und können Standardwerte besitzen. Chef +besitzt mit \texttt{Attributen} ein vergleichbares Konzept. Allerdings werden +Attribute getrennt von den Recipes definiert und sie werden dem Node-Objekte +zugewiesen. Die Attribute stehen somit allen Recipes zu Verfügung und können an +verschiedenen Stellen überschrieben werden. In Puppet 3 wurde diese Trennung +von Code und organsationsspezifischen Daten durch die Erweiterung \texttt{Hiera} +ebenfalls eingeführt. Klassenparameter werden automatisch in der +\texttt{HieraDB} gesucht und gegebenenfalls überschrieben. In älteren Versionen +von \texttt{Puppet} wurden Einstellungen für die Nodes in der zentralen +\texttt{site.pp}-Manifest verwaltet. Hiera ersetzt die \texttt{site.pp} weitest +gehend. Durch die Funktion \texttt{hiera\_include} können Klassen im +Hiera-Backend gesetzt werden (ähnlich der Run-List in Chef). + +Ressourcen heißen in Puppet \texttt{Types}. Puppet liefert wie Chef bereits eine Reihe +von Types mit. Diese werden Core-Types genannt. Wie auch in Chef können Types in +Puppet mehrere plattformspezifische Provider besitzen. Es ist möglich, eigene +Types zu definieren, auch Custom-Types genannt (Ähnlich LRWP in Chef). Die +Implementierung der Types/Provider erfolgt in Ruby im Verzeichnis +\texttt{lib/puppet}. Die Zustände einer Ressource können in Puppet über das Setzen +des Parameters \texttt{ensure} festgelegt werden (vergleichbar mit \texttt{action} +in Chef). + +Ein weiteres häufig genutztes Entwurfsmuster, um Ressourcen zu gruppieren, ist +der \texttt{Defined-Type}. Dieser ist das Äquivalent zur aus Chef bekannten +\texttt{Definition}. Ein Defined-Type kann im Gegensatz zum Custom-Type auch +direkt in der Puppet-Sprache mit dem Schlüsselwort \texttt{define} erstellt +werden. + +Vor der eigentlichen Provisionierung werden Informationen über das System zu +gesammelt. Dabei wird auf die Bibliothek +\href{http://puppetlabs.com/facter}{Facter} zurückgegriffen. In frühen Versionen +von Chef wurde die gleiche Bibliothek verwendet, bevor später +\href{http://docs.opscode.com/ohai.html}{Ohai} integriert wurde. + +Puppet nutzt die gleiche Template-Syntax wie Chef, welche in +Quellcodelisting~\ref{lst:erb-templates} vorgestellt wurde, um Dateien auf dem System +zu generieren. Der einzige Unterschied bei Chef ist die Funktion für +verschiedene Plattformen und -versionen verschiedene Template-Varianten der +gleichen Datei im Cookbook vor halten zu können. Die Varianten werden durch Unterordner +im Verzeichnis \texttt{templates/} unterschieden (z.B. +\texttt{templates/windows} oder \texttt{templates/ubuntu-12.04}). Falls kein der +Plattform entsprechende Ordner existiert sucht Chef im Verzeichnis +\texttt{templates/default}. + +Ein wesentlicher Unterschied zwischen Puppet und Chef ist die Reihenfolge der +Ausführung von Ressourcen. Chef überprüft die Ressourcen in der Reihenfolge, in +der sie in der Run-List und in den Recipes geladen werden. Puppet sortiert +Ressourcen derartig um, dass möglichst wenig Veränderungen am System vorgenommen +werden müssen um den gewünschten Zustand zu erreichen. Zum Beispiel, wenn an +mehreren Stellen eine Konfiguration für einen Dienst verändert wird, sollte +dieser nur einmal neu gestartet werden müssen. Bei Puppet spricht man von +modellbasiertem Konfigurationsmanagement, während Chef ein +\href{http://www.getchef.com/solutions/configuration-management/}{codebasiertes +Konfigurationsmanagement} ist. Da manche Ressourcen voneinander abhängen, kann +durch die Angabe der Parameter \texttt{before} und \texttt{require} die +Reihenfolge festgelegt werden. Über die Parameter \texttt{notify} und +\texttt{subscribe} können darüber hinaus Ressourcen aktualisiert werden, wenn +sich eine Abhängigkeit geändert hat (z.B. kann ein Dienst neu gestartet werden, +wenn sich die dazu gehörige Konfiguration verändert hat). In Chef kann Letzteres +über die Parameter \texttt{notifies} und \texttt{subscribes} angegeben werden. + +\paragraph{Architektur} Wie auch Chef bietet Puppet verschiedene Betriebsmodi. +Im einfachsten Fall wird mit dem Befehl \texttt{puppet apply} ein lokales +Manifest geladen werden (vergleichbar mit Chef-Solo). Das Äquivalent zum +Chef-Server in Chef ist bei Puppet der Puppet-Master, zu welchem sich der Client +\texttt{Puppetd} verbindet und mittels SSL-Zertifikaten authentifiziert. In der +Standarteinstellung setzt Puppetmaster auf den verhältnismäßig einfachen +Webserver \texttt{WEBrick} Dieser skaliert allerdings nicht auf mehrere +CPU-Kerne, da nur ein Prozess und Thread gestartet wird. Für Installationen mit +mehr als 10 Knoten werden Passenger oder Mongrel als Applikationsserver +empfohlen, wobei Nginx als Load-Balancer fungiert. Ein beliebter Ansatz zum +Skalieren größerer Cluster ist das Verwalten der Manifeste in einem +Git-Repository, wobei ein Cron-Job periodisch die Manifeste vom Git-Server lädt +und Puppet ausführt. Während Chef-Server bis zur Version 10 wie Puppetmaster in +Ruby geschrieben war, wurde der API-Teil von Chef-Server in Version 11 in der +Programmiersprache Erlang neu geschrieben. Die Zahl der Nodes, die von einem +Server bedient werden, soll sich dabei vervierfacht haben und kann somit bis zu +10.000 Nodes bedienen (Quelle: \cite{chefscale}). Für Puppet wurden keine +Statistiken gefunden, die eine Aussage darüber treffen, wie viele Nodes pro +Server betreut werden können. Allerdings ist anzunehmen, dass die Anzahl der +Server, bedingt durch die genutzte Architektur, kleiner ist als bei Chef. + +Zu den, von offiziell von Chef unterstützten, Plattformen gehören Windows, Mac OS X, +verschiedene Linuxderivate (Debian, Ubuntu, Redhat, \ldots) und Solaris. Puppet +bietet breiteren Support und unterstützt zusätzlich Free- und OpenBSD sowie +HP-UX und AIX. + +\paragraph{Résumé} +Zusammenfassend lässt sich feststellen, dass Chef und Puppet den gleichen +Funktionsumfang bieten. Die Grundkonzepte sind ähnlich, so ein Anwender des +einen Systems mit wenig Aufwand auch das andere System lernen kann. Die beiden +Firmen, Puppet Labs und Chef, entwickeln beide ihr Produkt stetig weiter und +bieten kommerziellen Support. Während Puppet auf den klassischen +Systemadministrator abzielt, Chef spricht den Trend der +\href{http://www.getchef.com/solutions/devops/}{DevOps}-Kultur an, bei welcher +Administration und Entwicklung stärker ineinander über gehen. + +% vim: set spell spelllang=de_de diff --git a/report/mymacros.sty b/report/mymacros.sty new file mode 100644 index 0000000..bdd1147 --- /dev/null +++ b/report/mymacros.sty @@ -0,0 +1,22 @@ +\newcommand{\treeroot}[1]{% Title + \node[above] at (0,0) {#1};% + \setcounter{treeline}{0} +} + + +\newcommand{\treeentry}[2]{% Title, Level + \draw[->] (#2-1,-\value{treeline}/2) -- (#2-1,-\value{treeline}/2-0.5) -- + (#2+0.5,-\value{treeline}/2-0.5) node[right] {#1}; + \stepcounter{treeline} +} + +\newcommand{\altentry}[2]{% Title, Level + \draw[->] (#2-1,-\value{treeline}/2) -- (#2-1,-\value{treeline}/2-0.5) -- + (#2+0.5,-\value{treeline}/2-0.5) node[right] {#1}; + \foreach \x in {1,...,#2} + { \draw (\x-1,-\value{treeline}/2) -- (\x-1,-\value{treeline}/2-0.5); + } + \stepcounter{treeline} +} + +\newcommand{\shellcmd}[1]{\nopagebreak\hspace{1cm}\texttt{\footnotesize\$ #1}} diff --git a/report/plaindin.bst b/report/plaindin.bst index e8c199e..592f15b 100644 --- a/report/plaindin.bst +++ b/report/plaindin.bst @@ -1,100 +1,118 @@ -%% PLAINDIN.BST Ausgabe [8] vom 10/10/00 -%% (C) Klaus F. Lorenzen, Hamburg email: lorenzen.marxen@t-online.de -%% ersetzt PLAINDIN.BST Ausgabe [7] 19/6/99 -%% ersetzt DINPLAIN.BST von 28/3/94 +%% PLAINDIN.BST Ausgabe [8.2] 2006-01-02 +%% mit doi-, urn-, url-Funktionen fuer Internetressourcen +%% ersetzt PLAINDIN.BST Ausgabe [8.1b3] 22.2.2005 +%% +%% +%% K.F.Lorenzen (Copyright 1994-2006) email: lorenzen.marxen@t-online.de %% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -%% PLAINDIN.BST wurde entwickelt aus BibTeX standard bibliography style -%% `plain'.Mit PLAINDIN.BST werden Literaturverzeichnisse gemaess der deutschen +%% PLAINDIN.BST wurde entwickelt aus Oren Patashnik's BibTeX standard +%% bibliography style `plain'. Dadurch ist es moeglich, eine vorgegebene +%% Literaturdatenbank ohne Aenderungen beliebig nach Us- oder deutscher +%% Zitierkonvention zu verarbeiten. +%% Mit PLAINDIN.BST werden Literaturverzeichnisse gemaess der deutschen %% Zitiernorm DIN 1505 Teil 2 formatiert. -%% Analog zu den 4 US standard styles wird ein vollstaendiger Satz von +%% Analog zu den 4 US standard styles wird ein vollstaendiger Satz von %% 4 DIN-gerechten bst-style Dateien veroeffentlicht (alphadin.bst, %% plaindin.bst, unsrtdin.bst, abbrvdin.bst). Die gueltige Version %% ist am schnellsten aus dem WWW ueber folgende URL zu beziehen -%% http://www.fh-hamburg.de/pers/Lorenzen/bibtex/ -%% Stand: 10/10/00 +%% http://www.haw-hamburg.de/pers/Lorenzen/bibtex/ +%% Stand: 2006-01-02 %% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ %% WAS IST PLAINDIN.BST ? %% Dieser style produziert Literaturzitate in Literaturverzeichnissen %% gemaess der deutschen Norm DIN 1505, Teil 2 vom Jan. 1984. %% Die Literaturzitate werden alphabetisch nach Verfassern sortiert -%% und fortlaufend in eckigen Klammern gezaehlt. -%% Es gibt Unterschiede zwischen der US- und der deutschen Zitierkonvention, -%% was die bibliographischen Typen und die verschiedenen Trennzeichen zwischen -%% den Feldern angeht. Daher ist auch keine 100%ige Abbildung der beiden -%% Regelwerke aufeinander moeglich. Dies ist aber immer durch eine achtsame -%% Erfassung zu beherrschen! Die vorliegenden DIN-styles versuchen einige -%% bibliographische Beschraenkungen der Originalstyles zu ueberwinden. -%% Es laesst sich in fast allen Faellen problemlos ein Original-bib-file -%% (d.i. die Datenbank, die die bibliographischen Informationen enthaelt) -%% wahlweise nach US-Norm oder deutscher DIN-Norm verarbeiten. -%% [Beispiel: Produzieren Sie mit der XAMPL.bib-Datenbank aus dem Original- -%% paket 2 verschiedene Literaturverzeichnisse.] Zu Gunsten -%% der Allgemeingueltigkeit von bib-files ist bei den Publikationstypen -%% (entry-types) und den bibliographischen Kategorien (fields) in Zweifels- -%% faellen immer (ja, mit endlichen Ausnahmen) die originale US-Bedeutung -%% beibehalten worden. Bei der Erfassung von Literaturquellen in bib-files -%% gelten folglich die in der TEX-Literatur veroeffentlichten Regeln. -%% Kommt es dennoch zu kleineren "Schoenheitsfehlern" im fertig gesetzten -%% output, so koennen diese so gut wie immer durch eine leicht veraenderte -%% Erfassung im bib-inputfile beseitigt werden. Last but not least koennen +%% und fortlaufend in eckigen Klammern gezaehlt. Die vorliegenden DIN-styles +%% gehen ueber die bibliographischen Beschraenkungen der Originalstyles hinaus. +% +%% Es werden nun auch Elektronische Online / Offline Ressourcen wie Internet- +%% quellen, CD-ROM usw. verarbeitet. Dazu kommen besondere Publikationsformen +%% wie Patente, Normen, Karten, Fernsehaufzeichnungen, Gesetzesstellen, Spiele. +% +%% Zur Gewaehrleistung der Allgemeingueltigkeit von bib-files gelten in den +%% DIN-styles die in der Tex-Literatur veroeffentlichten originalen +%% Definitionen und Regeln fuer die Publikationstypen (entry-types) und die +%% bibliographischen Felder (fields). +%% Treten kleinere "Schoenheitsfehler" im fertig gesetzten output auf, +%% lassen sich diese so gut wie immer durch eine veraenderte +%% Erfassung im bib-inputfile beseitigen. Oren Patashnik empfiehlt, die +%% Definition der Felder weit auszulegen. Last but not least koennen %% Sie im output-file < *.bbl > noch letzte Hand zur Korrektur ansetzen. % -%% UMGANG MIT FEHLERMELDUNGEN -%% Noch nicht alle ueberfluessigen Fehlermeldungen des Original-style sind -%% ausgemerzt. Die meisten Warnmeldungen beruhen auf -%% den andersartigen bibliographischen Regeln nach DIN 1505 und dem damit -%% verbundenen Ermessensspielraum, sind also in Wahrheit keine "Fehler". -%% Dennoch sollten Sie diese Warnungen beachten, um heraus zu finden, ob -%% evtl. eine unzulaessige Kombination von Publikationstyp (=entry-type) und -%% "fields" vorgenommen worden ist. Das fuehrt mitunter zu Wasserfallartigen -%% Fehlermeldungen: meistens duerfen Sie das einfach ignorieren. +%% WARN- UND FEHLERMELDUNGEN +%% Ursache von Warnmeldungen sind meistens fehlende Felder oder +%% Erfassungs-"Fehler". Letztere haengen teilweise mit den gegenueber US- +%% Gepflogenheiten andersartigen bibliographischen Regeln nach DIN 1505 +%% zusammen. Sie sind also in Wahrheit keine "Fehler" und duerfen fast immer +%% ignoriert werden. Dennoch pruefen Sie diese Warnungen, um heraus zu finden, +%% ob Publikationstyp (=entry-type) und "fields" eventuell unzulaessig +%% kombiniert worden sind. +%% Echte Fehler ("errors") treten nur noch in Verbindung mit falscher +%% Erfassung auf (nach meinen Tests!). Pruefen Sie die Syntax, den entry-type +%% und die fields. +%% Zu guter letzt: Qualitaetsmasstab ist einzig der DIN-konforme output! %% %% DANKSAGUNG -%% Hartmut Lueddecke, FH Hamburg habe ich fuer viele Verbesserungsvorschlaege -%% und stete Unterstuetzung zu danken. Vielen an dieser Stelle ungenannt -%% bleibenden Anwendern gilt mein Dank, die in den vergangenen Jahren durch -%% ihre Aufmerksamkeit dazu beigetragen haben, Fehler auszumerzen und -%% Verbesserungen vorzunehmen. +%% Hartmut Lueddecke, HAW Hamburg, hat viele Verbesserungsvorschlaege +%% in die frueheren Versionen eingebracht. Ihm danke ich herzlich. +%% Patrick W. Daly, dem Entwickler des Natbib-Stils, verdanke ich viele +%% Anregungen und den steten Ansporn, die DIN-Stile zu verbessern. +%% Viele an dieser Stelle ungenannt bleibende Anwender haben mich in +%% den vergangenen Jahren auf Fehler oder Verbesserungsmoeglichkeiten +%% aufmerksam gemacht und so diesen Stil mitentwickelt. Ihnen gilt mein +%% besonderer Dank. Ihr Feedback ist immer willkommen und eine Ermunterung. +%% +%% Klaus F. Lorenzen +%% +%% +%% +%% HINWEIS: Neben den vier bibliographischen DIN 1505 Standard-Stilen +%% nach den Original-styles von Oren Patashnik +%% gibt es zusaetzlich vier DIN 1505 Modifikationen der style +%% Emulationen des NATBIB-Pakets von Patrick W.Daly. +%% In den NATBIB-Modifikationen werden jetzt alle von P.W. Daly +%% implementierten Zitierweisen des Autor-Jahr-Stils unterstuetzt. +%% Damit erhaelt der Anwender eine weit ueber die urspruenglichen +%% Standardstyles hinausreichende Flexibilitaet beim Zitieren. +%% Naeheres unter URL http://www.haw-hamburg.de/pers/Lorenzen/bibtex/ %% -%% HINWEIS: es gibt eine Kombination von ALPHADIN.BST mit dem NATBIB-Stil -%% von Patrick W.Daly), womit Literaturverzeichnisse komplett nach -%% DIN 1505 Teil 2 UND Teil 3 formatiert werden koennen. Naeheres -%% per URL http://www.fh-hamburg.de/pers/Lorenzen/bibtex/ %% %% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -%% Eine ausfuehrliches Internet-Tutorial mit Beispielen ist in Vorbereitung. -%% Fuer den Anfang ist diese Datei schon etwas kommentiert! -%% Kritik, Vorschlaege usw. bitte an : -%% FH Hamburg, Klaus F. Lorenzen, Grindelhof 30, 20146 Hamburg -%% e-mail: lorenzen.marxen@t-online.de -%% 16/6/99 -%% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -% version 0.99c for BibTeX versions 0.99c or later, LaTeX2e -% Copyright (C) 1985, all rights reserved. -% Copying of this file is authorized only if either -% (1) you make absolutely no changes to your copy, including name, or -% (2) if you do make changes, you name it something other than -% bstdin.doc, plaindin.bst, unsrtdin.bst, alphadin.bst, and abbrvdin.bst. -% This restriction helps ensure that all standard styles are identical. -%% ==> The file btxbst.doc has the original documentation for style 'alpha'. -%% KFL, 15/1/96 +% version 0.99c for BibTeX versions 0.99c or later, LaTeX2e +% Copyright (C) 1985, all rights reserved. +% Copying of this file is authorized only if either +% (1) you make absolutely no changes to your copy, including name, or +% (2) if you do make changes, you name it something other than +% plaindin.bst, unsrtdin.bst, alphadin.bst, and abbrvdin.bst. +% This restriction helps ensure that all standard styles are identical. +% The file btxbst.doc has the original documentation for style 'alpha'. %% - +%% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +%% +%% NEUE FELDER +%% Zur Erfassung der neuen digitalen Online-Medien z.B. Internetquellen, E-journals, E-books, +%% E-mail u.a. gibt es die zusaetzlichen Felder: doi, url, urn, lastchecked +%% Internetquellen werden vorzugsweise mit dem BOOKLET-Typ erfasst. +%% Normen, Patente, Schutzrechte sind mit dem MISC-Typ zu erfassen. +% +% ENTRY { address %% Verlagsort author %% persoenlicher Urheber eines Werkes - booktitle %% a) Gesamttitel eines mehrbaendigen Werkes + booktitle %% a) Gesamttitel eines mehrbaendigen Werkes % %% b) Titel des Sammelwerks, das einzelne selbstaendige % %% Beitraege mit eigenem Titel enthaelt (->incollection) chapter %% Kapitel in einem Buch (Monographie) - edition %% Auflagevermerk + doi %%% Digital Object Identifier + edition %% Auflagevermerk; bei selbst. elektron. Dok. == Version editor %% Persoenl.Herausgeber oder Koerperschaftlicher Herausgeber - howpublished %% beliebiger Verlegervermerk: von wem, wo + howpublished %% beliebiger Verlegervermerk: von wem, wo institution %% Institution, die e.Verlagsfreie Veroeffentlichung betreibt isbn %% Standardnr fuer Buecher issn %% - " - : Zeitschriften u. Serien journal %% Titel einer Zeitschrift key %% Zusaetzlich vergebener Sortierschluessel, mitunter notwend. + lastchecked %% Online Abruf einer Internetquelle ( GRAY ); 22.1.2004 month %% naehere Bestimmung des Erscheinungsjahres (-> macro 's) note %% freies Eingabefeld fuer zusaetzliche Informationen number %% Mehrfachbedeutung in Abhaengigkeit vom Eingabetyp @@ -106,6 +124,8 @@ ENTRY series %% Titel e.Reihe, in der ein best. Buchtitel erschienen ist title %% Titel einer (namentlich gekennzeichneten) Veroeffentlichung type %% Zusatzfeld z.Kennzeichnung e.besonderen Publikationstyps + url %%% Internet-Adresse URL ( Uniform Resource Locator ) + urn %% Persistent Identifier URN ( Uniform Resource Name ) volume %% a) Zaehlung bei einem mehrbaendigen Werk (-> book) % %% b) Jahrgang einer Zeitschrift (-> article year %% Erscheinungsjahr @@ -113,13 +133,58 @@ ENTRY {} { label extra.label sort.label } +%% Variablen-Vereinbarungen + INTEGERS { output.state before.all mid.sentence after.sentence after.block } -%% die folg. BOOLE'sche VAR steuern d. Ausg. ": " nach Urheber-Feldern -%% und ". - " vor ISBN oder Anmerkungen (NOTE) - INTEGERS { colon.after period.dash } +INTEGERS { after.firstblock } + +%% fuer die Namensbehandlung + +INTEGERS { zahl lang } + +INTEGERS { nameptr namesleft numnames } + +INTEGERS { ptr collation collrest } + +%% fuer die Sortierung bei der label-Produktion +INTEGERS { len } + +INTEGERS { number.label longest.label.width } +%%---------------------------------------------------------------------- + +STRINGS { h s t u v w } + +%% bei der Behandlung der Namen-Funktionsbezeichnung (Hrsg., Redakt., usw) +STRINGS { fkt } + +%% fuer die label-Produktion +STRINGS { longest.label } + +%%%---------------------------------------------------------------------------- +% Einige Standardvorgaben, die vom Benutzer veraendert werden koennen. +%%%---------------------------------------------------------------------------- + +% Abkuerzung ("... und andere") bei Mehrverfasserquellen: + +FUNCTION { ua.etal } { " u.\,a." } %% evtl. auch in eckigen Klammern " [u.\,a.]" + +%% oder lateinisch: FUNCTION { ua.etal } { " et~al." } + +FUNCTION { und } { " u. " } + +%% oder ausgeschrieben: FUNCTION { und } { " und " } +% +% Einige elektronische Medien erhalten nach DIN 1505 eine "Ergaenzende Angabe" +% zusaetzlich zum materiellen Typ, z.B. CD ROM oder DVD u.a.: + +FUNCTION { eress } { "Elektronische Ressource" } + +%%%----------------------------------------------------------------------------------- + + FUNCTION {init.state.consts} { #0 'before.all := #1 'mid.sentence := @@ -127,12 +192,8 @@ FUNCTION {init.state.consts} #3 'after.block := #4 'colon.after := #5 'period.dash := + #6 'after.firstblock := } -INTEGERS { zahl lang } - -STRINGS { h s t u v } - -%% neue DIN-Funktion, 16/2/94 FUNCTION {output.nonnull} { 's := @@ -142,7 +203,7 @@ FUNCTION {output.nonnull} "\newblock " write$ } { output.state before.all = - { write$ } + { write$ } { output.state colon.after = { ": " * write$ newline$ @@ -155,22 +216,33 @@ FUNCTION {output.nonnull} } { output.state mid.sentence = { ", " * write$ } - { write$ - newline$ - "\newblock " write$ + { output.state after.sentence = + { " " * write$ } + { output.state after.firstblock = + { add.period$ write$ + newline$ + "\newblock " write$ + } + { write$ + newline$ + "\newblock " write$ + } + if$ + } + if$ } if$ } - if$ + if$ } - if$ - } + if$ + } if$ - after.block 'output.state := - } - if$ - s -} + after.block 'output.state := + } + if$ + s + } FUNCTION {output} { duplicate$ empty$ @@ -187,64 +259,13 @@ FUNCTION {output.check} if$ } -FUNCTION {output.bibitem} -{ newline$ - "\bibitem[" write$ - label write$ - "]{" write$ - cite$ write$ - "}" write$ - newline$ - "" - before.all 'output.state := -} - -FUNCTION {fin.entry} %%$$$ nach DIN neu 16/2/94 -{ write$ - newline$ -} - -FUNCTION {set.period.dash} %% Wenn ein ". - " die Satzteile trennen soll.! +FUNCTION {new.block} { output.state before.all = 'skip$ - { period.dash 'output.state := } + { after.block 'output.state := } if$ } -%% neu 16/2/94 -%% prueft, ob PAGES, ISBN- oder NOTE-Feld vh. ist und setzt dann ". - " davor. - -FUNCTION {set.period.dash.check} -{ empty$ - 'skip$ - 'set.period.dash - if$ -} - -FUNCTION {set.colon.after} %%$$$ Wenn ein ": " d. Satzteile trennen soll! -{ output.state before.all = - 'skip$ - { colon.after 'output.state := } - if$ -} - -%% neu / alt 17/2/94 Wenn ein " " die Satzteile trennen soll.! -FUNCTION {new.sentence} -{ output.state before.all = - 'skip$ - { after.sentence 'output.state := } - if$ -} - -%% neu 17/2/94 Wenn ein ", " die Satzteile trennen soll.! -FUNCTION { part.of.sentence } -{ output.state before.all = - 'skip$ - { mid.sentence 'output.state := } - if$ -} - - FUNCTION {not} { { #0 } { #1 } @@ -263,6 +284,61 @@ FUNCTION {or} if$ } + +FUNCTION {output.bibitem} +{ newline$ + "\bibitem[" write$ + label write$% + "]{" write$ + cite$ write$ + "}" write$ + newline$ + "" + before.all 'output.state := +} + +FUNCTION {fin.entry} +{ write$ + newline$ +} + +FUNCTION {set.period.dash} %% Wenn ein ". - " die Satzteile trennen soll.! +{ output.state before.all = + 'skip$ + { period.dash 'output.state := } + if$ +} + +FUNCTION {set.period.dash.check} +{ empty$ + 'skip$ + 'set.period.dash + if$ +} + +FUNCTION {set.colon.after} %%$$$ Wenn ein ": " d. Satzteile trennen soll! +{ output.state before.all = + 'skip$ + { colon.after 'output.state := } + if$ +} + +%% Wenn ein " " die Satzteile trennen soll.! +FUNCTION {new.sentence} +{ output.state before.all = + 'skip$ + { after.sentence 'output.state := } + if$ +} + +%% Wenn ein ", " die Satzteile trennen soll.! +FUNCTION { part.of.sentence } +{ output.state before.all = + 'skip$ + { mid.sentence 'output.state := } + if$ +} + FUNCTION {new.sentence.checka} { empty$ 'skip$ @@ -277,10 +353,6 @@ FUNCTION {field.or.null} if$ } -INTEGERS { nameptr namesleft numnames } - -STRINGS { fkt } - FUNCTION {emphasize} { duplicate$ empty$ { pop$ "" } @@ -288,7 +360,6 @@ FUNCTION {emphasize} if$ } -%% neu, setzt Autor/Hrsg. in Kapitaelchen 9/3/94 FUNCTION { capitalize } { duplicate$ empty$ { pop$ "" } @@ -296,27 +367,75 @@ FUNCTION { capitalize } if$ } -%%$$$ DIN-Quellenangabe : spezieller unselbst. Teil ist erschienen "In: " -%% dem bibliogr. selbst. Werk, z.B. Zeitschrift, Buch - -%% 1/4/96 FUNCTION {article.in.journal} { duplicate$ empty$ { pop$ "" } - { author missing$ - { title missing$ - { emphasize " " * * }%% wenn ein Zs-Heft als ganzes zitiert wird - { emphasize "{In: }" swap$ " " * * } + { author missing$ title missing$ and + { emphasize } + { emphasize "{In: }" swap$ * } if$ - } - { emphasize "{In: }" swap$ " " * * } - if$ } if$ } -%% nach Vorschlag von H.Lueddecke, um Adelspraedikate beim Sortieren -%% nach den(m) Vornamen aufzufuehren. Lo, 2/11/94 +FUNCTION {format.doi} +{ doi empty$ + { "" } + { new.block "\url{http://dx.doi.org/" doi * "}" * + %% { new.block "\url{http://dx.medra.org/" doi * "}" * + } + if$ +} + +FUNCTION {format.url} +{ urn missing$ + { doi missing$ + { url empty$ + { "" } + { type empty$ NOT + { type #-1 #4 substring$ "mail" = + type #1 #4 substring$ "Mail" = + OR + { type$ "incollection" = + { "" } + { "\,Absenderadresse: \url{" url * "}" * } + if$ + } + { "\url{" url * "}" * }%% evtl. "URL" oder "<...>" + if$ + } + { "\url{" url * "}" * } %% evtl. "URL" oder "<...>" + if$ + } + if$ + } + { format.doi } + if$ + } + { "\url{http://nbn-resolving.de/urn/resolver.pl?urn=" urn * "}" * + } + if$ +} + +FUNCTION {format.maillist.url} + { url empty$ + { "" } + { type empty$ + { "" } + { type #-1 #4 substring$ "mail" = + type #1 #4 substring$ "Mail" = + OR + { "\url{" url * "}" * } + { "" } + if$ + } + if$ + } + if$ + } + +%% Adelspraedikate beim Sortieren nach den(m) Vornamen auffuehren +%% Abweichend v. DIN !!! FUNCTION {format.names} { 's := "" 'u := @@ -325,21 +444,21 @@ FUNCTION {format.names} numnames 'namesleft := { namesleft #0 > } { - %vorher, Lue s nameptr "{vv~}{ll}" format.name$ 't := s nameptr "{ll}" format.name$ 't := t capitalize 't := - %vorher,Lue s nameptr "{, ff}" format.name$ 'u := - s nameptr "{, ff}{ vv}" format.name$ 'u := - u text.length$ 'lang := + s nameptr "{ jj}" format.name$ 'w := + s nameptr "{, ff}{ vv}{ jj}" format.name$ 'u := + u text.length$ 'lang := #1 'zahl := "" 'v := { zahl lang < } - { u zahl #1 substring$ "~" = + { u zahl #1 substring$ "~" = { v "" = { u #1 zahl #1 - substring$ 'v := } 'skip$ if$ - v u zahl #2 substring$ * "." * 'v := } + v u zahl #2 substring$ * "." * w * 'v := + } 'skip$ if$ zahl #1 + 'zahl := } @@ -348,9 +467,7 @@ FUNCTION {format.names} { u 'v := } 'skip$ if$ -%% der string fkt enthaelt " (Hrsg.)", wenn Editorfeld nicht leer ist - t v * fkt * 't := %% Komma nach Nachnamen wird oben erledigt! - %% t enthaelt nun d. formatierten Nnamen, Vnamen + t v * fkt * 't := nameptr #1 > { namesleft #1 > { " ; " * t * } @@ -358,20 +475,15 @@ FUNCTION {format.names} { " " * } 'skip$ if$ -%% %% n. schindle's hinweis 12/1/96 erweitert t "\textsc{others}" = t "\textsc{others} (Hrsg.)" = or - { " [u.~a.]" * }%% 13/2/94 -%%%% { "et~al." * } %% Geschmackssache, waehle eins von beiden - { " ; " * t * } + { ua.etal * } + { " ; " * t * } if$ } if$ %% Ende der namesleft-Pruefung } - 't - %% hierdurch wird bei jed. Schleifendurchgang das sich komplet- - %% tierende Zwischen-Namensergebnis wieder auf den stack gelegt - - if$ %% Ende der nameptr-Pruefung + 't + if$ %% Ende der nameptr-Pruefung nameptr #1 + 'nameptr := namesleft #1 - 'namesleft := @@ -380,8 +492,6 @@ FUNCTION {format.names} "" 'fkt := %% fkt wird zurueckgesetzt } -%%$$$ geaendert 14/2/94 - FUNCTION {format.authors} { author empty$ { "" } @@ -389,50 +499,88 @@ FUNCTION {format.authors} if$ } -%%$$$ geaend. 20/2/94 Anpassung an DIN, wonach Autor + Hrsg. zusammen vorkom- -%% men duerfen.!! - FUNCTION {format.editors} { editor empty$ { author empty$ - { "Weder Verfasser noch Hrsg. in " cite$ * warning$ } - 'skip$ + { "empty author and editor in " cite$ * warning$ "" } + 'skip$ if$ - } - { author empty$ - { " (Hrsg.)" 'fkt := - editor format.names + } + { author empty$ + { " (Hrsg.)" 'fkt := + editor format.names } - { " (Hrsg.)" 'fkt := + { " (Hrsg.)" 'fkt := " ; " * editor format.names * } if$ - } - if$ - } + } + if$ + } + +FUNCTION { format.authors.organization } +{ type$ "misc" = + { organization empty$ + { author empty$ + { "" } + { author format.names " (Erfinder)" * } + if$ + } + { author empty$ + { organization } + { author format.names " (Erfinder); " * + organization * " (Anmelder)" * + } + if$ + } + if$ + } + { type$ "manual" = + { organization empty$ + { format.authors } + { author empty$ + { organization capitalize " (Hrsg.)" * } + { author format.names } + if$ + } + if$ + } + 'skip$ + if$ + } + if$ +} + -%% Lo, 12/5/99 neue Funktion fuer proceedings, misc usw. FUNCTION { format.editors.organization } { organization empty$ 'skip$ { type$ "misc" = { organization } - { " ; " * organization " (Veranst.)" *} + { * " ; " * organization " (Veranst.)" *} if$ } if$ } -%%$$$ Sonderfall: Herausgeber bei Typ incollection, 21/2/94 +FUNCTION { format.tr.institution } +{ institution empty$ + 'skip$ + { institution capitalize } + if$ +} + FUNCTION {format.ed.incoll} { editor empty$ { "" } - { " (Hrsg.)" 'fkt := - editor format.names + { " (Hrsg.)" 'fkt := + editor format.names + format.editors.organization } if$ -} +} + FUNCTION {format.title} { title empty$ @@ -441,70 +589,152 @@ FUNCTION {format.title} if$ } +FUNCTION {format.number} +{ number empty$ + { "" } + { number " " * } %% Text so wie er im Feld number steht plus " " + if$ +} + +FUNCTION {format.digital.type}%% nur in booklet +{ type empty$ + { "" } + { type #-1 #4 substring$ "mail" = + type #1 #4 substring$ "Mail" = + OR + { "" } + { type } %% Typ einer digitalen Ressource in Form einer + %% "Ergaenzenden Angabe", so wie er dasteht; + %% Alternativ kann dieser Text auch in NOTE erfasst werden. + if$ + } + if$ +} + FUNCTION {n.dashify} { 't := "" { t empty$ not } { t #1 #1 substring$ "-" = - { t #1 #2 substring$ "--" = not - { "--" * - t #2 global.max$ substring$ 't := - } - { { t #1 #1 substring$ "-" = } - { "-" * - t #2 global.max$ substring$ 't := - } - while$ - } - if$ - } - { t #1 #1 substring$ * - t #2 global.max$ substring$ 't := - } + { t #1 #2 substring$ "--" = not + { "--" * + t #2 global.max$ substring$ 't := + } + { { t #1 #1 substring$ "-" = } + { "-" * + t #2 global.max$ substring$ 't := + } + while$ + } + if$ + } + { t #1 #1 substring$ * + t #2 global.max$ substring$ 't := + } if$ } while$ } -%% geaendert 24/2/94 +%% Auflagenvermerke gibt man komplett, einschliesslich Abkuerzungen in +%% das Feld edition ein: ---> EDITION= { 3., erw. und verb. Aufl. } +%% oder fremdsprachlich: EDITION= { 2nd edition } + +FUNCTION {format.edition} +{ edition empty$ + { "" } + { edition } + if$ +} + FUNCTION {format.date} -{ year empty$ - { month empty$ - { "" } - { "there's a month but no year in " cite$ * warning$ - month - } +{ year duplicate$ empty$ + { "empty year in " cite$ * warning$ + pop$ "" } + 'skip$ + if$ + month empty$ + 'skip$ + { type$ "book" = + type$ "inbook" = + OR + 'skip$ + { month " " * swap$ * } if$ - } - { month empty$ %% b. Buechern nur Jahr, ohne Monat ausgeb. im Impressum - 'year - { month " " * year * } + } + if$ +} + +FUNCTION {format.edition.or.date} +{ edition empty$ year empty$ and + { "" } + { edition empty$ + { type empty$ NOT + { type #-1 #4 substring$ "mail" = + type #1 #4 substring$ "Mail" = + OR + { " gesendet: " "-- " type * swap$ * + format.date * + } + { "\,Version:\," + format.date * + } + if$ + } + { "\,Version:\," + format.date * + } + if$ + } + { year empty$ + { "\,Version:\," edition * } + { "\,Version:\," edition * ", " * + format.date * + } + if$ + } if$ } if$ } -%% -%%$$$ neue Fkt., 16/2/94 u. 14/3/94 das sog. Impressum +FUNCTION {format.version.url} +{ url empty$ doi empty$ urn empty$ and and + { type$ "techreport" = + { format.edition } + { "" } + if$ + } + { format.edition.or.date output format.url } + if$ +} + +FUNCTION {format.edition.or.version} +{ url empty$ doi empty$ urn empty$ and and + { format.edition } + { format.edition.or.date } + if$ +} + FUNCTION {format.address.publisher.year} { publisher empty$ { address empty$ - { year empty$ + { year empty$ { "" } - { year } + { year } if$ } - { "Es gibt einen Verlagsort, aber keinen Verlag in " cite$ * warning$ - address ", " * format.date * + { "there's an address but no publisher in " cite$ * warning$ + address ", " * format.date * } if$ } { address empty$ { year empty$ - { "Es gibt nur eine Verlagsangabe in " cite$ * warning$ - publisher - } - { publisher ", " * format.date * } + { "neither address nor publication date in " cite$ * warning$ + publisher + } + { publisher ", " * format.date * } if$ } { year empty$ @@ -513,15 +743,133 @@ FUNCTION {format.address.publisher.year} if$ } if$ + } + if$ +} + +FUNCTION {format.address.publisher.year.alt} +{ publisher empty$ + { address empty$ + { year empty$ + { "" } + { url empty$ + { year } + { "" } + if$ + } + if$ + } + { "there's an address but no publisher in " cite$ * warning$ + address ", " * format.date * + } + if$ } + { url empty$%%%% wenn es URL gibt wird nur die service-provider Adresse +%%% ausgegeben, die im publisher-Feld steht + { address empty$ + { year empty$ + { "neither address nor publication date in " cite$ * warning$ + publisher + } + { publisher ", " * format.date * } + if$ + } + { year empty$ + { address " : " * publisher * } + { address " : " * publisher * ", " * format.date * } + if$ + } + if$ + } + { publisher } + if$ + } + if$ +} + +FUNCTION {format.howpublished} +{ url missing$ urn missing$ doi missing$ AND AND + { howpublished empty$ + { address empty$ + { type empty$ + { "" } + { type #-1 #4 substring$ "mail" = + { "(gesendet: " new.sentence + format.date * ")" * + } + { "" } + if$ + } + if$ + format.date * + } + { address ", " * format.date * } + if$ + } + { address empty$ + { howpublished ", " * format.date * } + { address " : " * howpublished * ", " * format.date * } + if$ + } + if$ + } + { howpublished empty$ + { "" } + { howpublished } + if$ + } if$ } +FUNCTION {format.lastchecked.or.type}%% nur in misc-Funktion +{ lastchecked empty$ + { url empty$ doi empty$ urn empty$ and and + { type empty$ + { skip$ } + { type set.period.dash.check + type output + } + if$ + } + { type empty$ + { skip$ } + { type #-1 #4 substring$ "mail" = + type #1 #4 substring$ "Mail" = + OR + { skip$ } + { type set.period.dash.check + type output } + if$ + } + if$ + } + if$ + } + { url empty$ doi empty$ urn empty$ and and + { "there's a lastchecked date but no url, urn or doi in " + cite$ * warning$ + } + { type empty$ + { "there's a URL and a lastchecked date but no type in " + cite$ * warning$ + } + { type set.period.dash.check + type output + part.of.sentence + lastchecked "Abruf: " swap$ * output + } + if$ + } + if$ + } + if$ +} + + FUNCTION {format.btitle} { title emphasize } - FUNCTION {tie.or.space.connect} { duplicate$ text.length$ #3 < { "~" } @@ -530,15 +878,6 @@ FUNCTION {tie.or.space.connect} swap$ * * } -FUNCTION {either.or.check} -{ empty$ - 'pop$ - { "can't use both " swap$ * " fields in " * cite$ * warning$ } - if$ -} - -%% neu 8/3/94 in dieser Funkt. steckt im volume empty-Teil noch ein bug, der -%% aber ignoriert werden kann; das Ergebnis ist ok. FUNCTION {format.btitle.vol} { number empty$ { series empty$ @@ -550,9 +889,9 @@ FUNCTION {format.btitle.vol} { volume empty$ { title emphasize }%% ein Buch, das zusaetzl. SERIES=Reihentitel besitzt %% jetzt kommt d. Fall des mehrbaendigen Werkes mit Gesamttitel=SERIES - %% Zaehlung=VOLUME und Bandtitel=TITLE; - { series emphasize ". Bd." * volume tie.or.space.connect - ": " * "{\emph{" * title * "}}" * } + %% Zaehlung=VOLUME und Bandtitel=TITLE; + { series emphasize ". Bd." * volume tie.or.space.connect + ": " * "{\emph{" * title * "}}" * } if$ } if$%% series-test @@ -561,32 +900,18 @@ FUNCTION {format.btitle.vol} if$%% Ende number-test } -%%$$$ neu 16/2/94 -%% Serien- / Reihentitel werden im Feld series gespeichert. Weist die -%% Serie eine Zaehlung der Einzeltitel auf, gibt man entweder nach DIN alles -%% in das Feld series so ein: ---> TITEL DER SERIE NR. (der Vorlage) <--- -%% z. B. SERIES= { Mensch und Computer 12 }. -%% [ Die Nummer der Vorlage darf auch durch " ; " abgesetzt werden. ] -%% oder: -%% man gibt die Zaehlung in das Feld NUMBER ein, z.B. NUMBER = {12}. -%% Achtung!! -%% Bei mehrbaendigen Werken steht d. Gesamttitel im Feld SERIES und die -%% Bandzaehlung im Feld VOLUME; NUMBER darf dann nicht besetzt sein! -%% Anderenfalls liegt ein Erfassungsfehler vor, da sich Reihe u. mehrbd. -%% Werk gegenseitig ausschliessen. - FUNCTION {format.series.number.din} { volume empty$ { number empty$ - { series empty$ - { "" }%% Ausstieg mit Nullstring - { "(" series * ")" * } %% d. Seriennr koennte auch gleich hier - %% im SERIES-Feld miterfasst werden - if$ - } { series empty$ - { "(" number tie.or.space.connect ")" * - "there's a number but no series in " cite$ * warning$ + { "" } + { "(" series * ")" * } %% d. Seriennr koennte auch gleich hier + %% im SERIES-Feld miterfasst werden + if$ + } + { series empty$ + { "(" number * ")" * + "there's a number but no series in " cite$ * warning$ } { "(" series * number tie.or.space.connect ")" * } if$ @@ -596,7 +921,8 @@ FUNCTION {format.series.number.din} { series empty$ { "" } { type$ "proceedings" = %% Sonderfall, es darf VOLUME und NUMBER ex. ! - { number empty$ + type$ "inproceedings" = OR + { number empty$ { "(" series * ")" * } { "(" series * number tie.or.space.connect ")" * } if$ @@ -604,14 +930,26 @@ FUNCTION {format.series.number.din} { "" }%% Ausstieg mit Nullstring, s. Kommentar if$ }%% bei gezaehlten Reihen MUSS die Reihennr. im Feld NUMBER stehen! - if$ %% wenn also d. Feld VOLUME nicht leer ist, dann liegt ausser bei + if$ %% wenn also d. Feld VOLUME nicht leer ist, dann liegt ausser bei %% Typ PROCEEDINGS falsche } %% Erfassung vor und es erfolgt d. Ausstieg mit d. Nullstring! - if$ + if$ } -%% seltener Fall bei MISC: Ausgabe einer Serie; die Nummer der Serie muss -%% in SERIES miterfasst werden 16/6/99 +FUNCTION {format.tr.series.or.number} +{ number empty$ + { series empty$ + { "" } + { "(" series * ")" * } + if$ + } + { series empty$ + { "(" number * ")" * } + { "(" series * number tie.or.space.connect ")" * } + if$ + } + if$ + } FUNCTION {format.misc.series} { series empty$ @@ -620,20 +958,17 @@ FUNCTION {format.misc.series} if$ } - -%%$$$ 16/2/94 -%% Auflagenvermerke gibt man komplett, einschliesslich Abkuerzungen in -%% das Feld edition ein: ---> EDITION= { 3., erw. und verb. Aufl. } -%% oder fremdsprachlich: EDITION= { 2nd edition } - -FUNCTION {format.edition} -{ edition empty$ - { "" } - { edition } +FUNCTION { format.doi.urn } +{ urn empty$ + { doi empty$ + { "" } + { "DOI" doi n.dashify tie.or.space.connect } + if$ + } + { "URN" urn n.dashify tie.or.space.connect } if$ } -%%$$$ neu, 18/3/94 FUNCTION { format.isbn.issn } { isbn empty$ { issn empty$ @@ -645,88 +980,138 @@ FUNCTION { format.isbn.issn } if$ } -%%$$$ geaendert, 21/2/94 gibt Seitenzahl bei BOOK-Typ und verwandten T. aus -FUNCTION {format.pages.book} -{ pages empty$ - { "" } - { "" pages n.dashify tie.or.space.connect " S" *} %% 17/12/95 - if$ -} - -%%$$$ alle anderen Seitenang. zB. Zeitschrft., INBOOK usw. a la Orig., 9/3/94 FUNCTION {format.pages} { pages empty$ { "" } - { "S." pages n.dashify tie.or.space.connect } + { url empty$ + { "S." pages n.dashify tie.or.space.connect } + { pages } + if$ + } if$ } -%% Angaben v. Jahrgang, Jahr, Heftnr., Seiten bei Artikel-Typ -%% 14/3/94, 26/2/97 +FUNCTION {format.pages.book} +{ pages empty$ + { "" } + { note empty$ isbn empty$ AND + { "" pages n.dashify tie.or.space.connect " S" * + add.period$ } + { "" pages n.dashify tie.or.space.connect " S" * } + if$ + } + if$ +} + +FUNCTION {format.pages.bkcollation} +{ pages empty$ + { "" } + { "" pages n.dashify tie.or.space.connect } + if$ +} + +FUNCTION {format.bkpages.collat.check} +{ 's := + #1 'ptr := + s text.length$ 'collation := + collation #1 = + { format.pages.book } + { + collation 'collrest := + { collrest #0 > } + { s ptr #2 substring$ 't := + t "S." = + { format.pages.bkcollation + #0 'collrest := } + { ptr #1 + 'ptr := + collrest #1 - 'collrest := + #1 collrest = + { format.pages.book } + { skip$ } + if$ + } + if$ + } + while$ + } + if$ +} FUNCTION {format.vol.year.num.pages} { volume field.or.null year empty$ - { "Es gibt einen Jahrgang, aber kein Jahr in " cite$ * warning$ } + { "there's no year in " cite$ * warning$ } { " (" year * ")" * * } if$ month empty$ - 'skip$ - { ", " month * * } + 'skip$ + { ", " month * * } if$ number empty$ - 'skip$ - { ", Nr. " number * * } - if$ - pages empty$%% Lo, 26/2/97 'skip$ - { ", " format.pages * *}%% + { ", Nr. " number * * } if$ - -%% pages empty$%% das war die Fass. Nov. 96, die auch ging -%% 'skip$ -%% { duplicate$ empty$ -%% { pop$ format.pages }%% da pages leer, wird nur "" auf stack gelegt -%% { ", " format.pages * *} -%% if$ -%% } -%% if$ - + pages empty$ + 'skip$ + { duplicate$ empty$ + { pop$ "" } + { title missing$ + { ", " pages format.bkpages.collat.check * *} + { ", " format.pages * *} + if$ + } + if$ + } + if$ } -%% geaendert 21/2/94 +FUNCTION {format.chapter.inbook} +{ duplicate$ empty$ + { pop$ "empty chapter in " cite$ * warning$ } + { type empty$ + { "\emph{Kapitel\/} " swap$ tie.or.space.connect } + { type " " * swap$ * }%% wenn keine bes. Abschnittsform gen. werden soll, + %% koennte e. kl. Zwischenraum gewaehlt werden, z.B. " \, " + if$ + } + if$ + } + FUNCTION {format.chapter.pages} { chapter empty$ 'format.pages { type empty$ - { "Kapitel " } - { type } + { "Kapitel " } + { url empty$ + { type } + { "Kapitel " } + if$ + } if$ chapter tie.or.space.connect pages empty$ - 'skip$ - { ", " * format.pages * } + 'skip$ + { ", " * format.pages * } if$ } if$ } -%%$$$ geaendert 21/2/94 FUNCTION {format.in.ed.booktitle.din} { booktitle empty$ { "" } { editor empty$ - { volume empty$ - { "{In: }" booktitle emphasize * }%% n. Belieben fettes In: - { "{In: }" booktitle emphasize * %% - " - - " Bd." volume tie.or.space.connect * + { volume empty$ + { "{In: }" booktitle emphasize * } + { "{In: }" booktitle emphasize * + " Bd." volume tie.or.space.connect * } if$ } - { volume empty$ + { volume empty$ { "{In: }" format.ed.incoll * ": " * booktitle emphasize * } - { "{In: }" format.ed.incoll * ": " * booktitle emphasize * - " Bd." volume tie.or.space.connect * + { "{In: }" format.ed.incoll * ": " * booktitle emphasize * + " Bd." volume tie.or.space.connect * } if$ } @@ -735,257 +1120,312 @@ FUNCTION {format.in.ed.booktitle.din} if$ } -%% geaendert 1/3/94 -FUNCTION {format.thesis.type} +FUNCTION {format.thesis.tr.type} { type empty$ 'skip$ - { pop$ - type - } - if$ + { pop$ + type + } + if$ } -%% geaendert 23/2/94 i.Orig. wird zuerst die number, dann der type getestet -FUNCTION {format.tr.number.din} -{ type empty$ - { number empty$ - { " -- Forschungsbericht" } %% bei Minimalangaben besser ohne "."! - { "(" number tie.or.space.connect "). -- Forschungsbericht" * } - if$ - } - { number empty$ - { " -- " type * } %% bei Minimalangaben besser ohne "."! - { "(" number tie.or.space.connect "). -- " * type * } - if$ - } - if$ +FUNCTION {format.online.lastcheck} +{ lastchecked empty$ + { url empty$ doi empty$ urn empty$ and and + { skip$ } + { "" output } + if$ + } + { url empty$ doi empty$ urn empty$ and and + { "there's a lastchecked date but no url, urn or doi in " + cite$ * warning$ + } + { part.of.sentence + lastchecked "Abruf: " swap$ * output + } + if$ + } + if$ } +FUNCTION {format.maillist.lastcheck} + { type empty$ NOT + { type #-1 #4 substring$ "mail" = + type #1 #4 substring$ "Mail" = + OR + { format.online.lastcheck } + 'skip$ + if$ + } + 'skip$ + if$ + } + + FUNCTION {format.article.crossref} { key empty$ { journal empty$ - { "need key or journal for " cite$ * " to crossref " * crossref * - warning$ - "" - } - { "{In: }{\em " journal * "\/}" * }%% + { "need key or journal for " cite$ * " to crossref " * crossref * + warning$ + "" + } + { "{In: }{\emph " journal * "}" * } if$ } - { "{In: }" key * }%% + { "{In: }" key * } if$ - "{\cite{" * crossref * "}" * "}" * ", " * format.pages * -%% " (siehe \cite{" * crossref * "}" * "), " * format.pages * + "\cite{" * crossref * "}" * ", " * format.pages * } -%%geaendert 7/3/94 und noch einmal nach Lueddecke, s.o. FUNCTION {format.crossref.editor} -%vorher,Lue { editor #1 "{vv~}{ll}" format.name$ " (Hrsg.)" * { editor #1 "{ll}" format.name$ " (Hrsg.)" * editor num.names$ duplicate$ #2 > - { pop$ " [u.~a.]" * } -%% { pop$ " et~al." * } + { pop$ ua.etal * }%% --->u. a. { #2 < - 'skip$ - { editor #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" = - { " [u.~a.]" } -%% { " et~al." * } - { " ; " * editor #2 "{vv~}{ll}" format.name$ * " (Hrsg.)" * } - if$ - } + 'skip$ + { editor #2 "{ff }{vv }{ll}{ jj}" format.name$ "others" = + { ua.etal } + { " ; " * editor #2 "{vv~}{ll}" format.name$ * " (Hrsg.)" * } + if$ + } if$ } if$ } +FUNCTION {format.inbk.vol.title} +{ volume empty$ + { " In: " } + { title empty$ + { " In: Bd." volume tie.or.space.connect + " von " * + } + { "In: Bd." volume tie.or.space.connect ": " * title emphasize * + " (" * year * ") in " * + } + if$ + } + if$ + } + FUNCTION {format.book.crossref} -{ volume empty$ - { "empty volume in " cite$ * "'s crossref of " * crossref * warning$ - "{\texttt{siehe}} " -%% "(siehe " - } - { ". -- Bd." volume tie.or.space.connect - " von " * +{ type$ "inbook" = + { format.inbk.vol.title } + { volume empty$ + { "empty volume in " cite$ * "'s crossref of " * crossref * warning$ + " " + } + { ". -- Bd." volume tie.or.space.connect + " von " * + } + if$ } if$ editor empty$ editor field.or.null author field.or.null = or { key empty$ - { series empty$ - { "need editor, key, or series for " cite$ * " to crossref " * - crossref * warning$ - "" * - } - { "" * }%% dadurch kommt nach der Bandzaehl. gleich das label 2/6/99 -%% { "{\emph{" * series * "}} {\texttt{siehe}}" * } - if$ - } - { key * } + { series empty$ + { "need editor, key, or series for " cite$ * " to crossref " * + crossref * warning$ + "" * + } + { "" * } + if$ + } + { key * } if$ } - { "" * }%% nach der Bandzaehlung kommt gleich das label; Lo 2/6/99 -%% { format.crossref.editor * } + { "" * } if$ - "{\cite{" * crossref * "}" * "}" * -%% "{\cite{" * crossref * "}" * "}" * %%"), " * format.pages * + "\cite{" * crossref * "}" * } FUNCTION {format.incoll.inproc.crossref} { editor empty$ - editor field.or.null author field.or.null = - or - { key empty$ - { booktitle empty$ - { "need editor, key, or booktitle for " cite$ * " to crossref " * - crossref * warning$ - "" - } - { "{In: }{\emph " booktitle * "}" * }%% fettes In: n. Belieben - if$ - } - { "{In: }" }%% 26/5/99 -%% { "{In: }" key * } + editor field.or.null author field.or.null = + or + { key empty$ + { booktitle empty$ + { "need editor, key, or booktitle for " cite$ * " to crossref " * + crossref * warning$ + "" + } + { "{In: }{\emph " booktitle * "}" * }%% + if$ + } + { "{In: }" } if$ - } -%% { "{In: }{\em " booktitle * "\/}" * }%% - { "{In: }" }%% Lo, 10/2/99 es sieht der reine Bezug (Referenz) besser aus! + } + { "{In: }" } if$ -%% " (siehe \cite{" * crossref * "}" * "), " * format.pages * - "{\cite{" * crossref * "}" * "}" * ", " * format.pages *%% das fette label, Lo 23/2/99 -%% alte Vers. bis 27/2/97 " (siehe \cite{" * crossref * "}" * ")" * + "\cite{" * crossref * "}" * %% ", " * format.pages * 5.12.2005 } -%%geaendert + FUNCTION {article} { output.bibitem format.authors "author" output.check set.colon.after format.title "title" output.check crossref missing$ - { journal article.in.journal output.nonnull % 26/2/97 - new.sentence + { journal article.in.journal output.nonnull + new.sentence format.vol.year.num.pages output + format.url output } { format.article.crossref output.nonnull } if$ - note set.period.dash.check - note output + format.online.lastcheck + doi set.period.dash.check + urn set.period.dash.check + format.doi.urn output issn set.period.dash.check format.isbn.issn output + note set.period.dash.check + note output fin.entry } -%%$$$ geaendert, 20/2/94 FUNCTION {book} { output.bibitem author empty$ { format.editors "author and editor" output.check } - { format.authors format.editors output.nonnull } + { format.authors format.editors output.nonnull } if$ set.colon.after crossref missing$ { format.btitle.vol "title" output.check } { format.btitle "title" output.check } if$ - format.edition "edition" output.check + format.edition output format.address.publisher.year "publisher" output.check new.sentence crossref missing$ - { format.series.number.din output - pages set.period.dash.check%% 19/5/99 wie bei adinat.bst - format.pages.book output - } - { format.book.crossref output.nonnull - pages set.period.dash.check - format.pages.book output + { format.series.number.din output } + { format.book.crossref output.nonnull } + if$ + pages empty$ + { skip$ } + { pages set.period.dash.check + pages format.bkpages.collat.check output } if$ - note set.period.dash.check - note output + format.doi output + format.url output + new.block isbn set.period.dash.check format.isbn.issn output + note set.period.dash.check + note output fin.entry } -%% geaendert 23/2/94 -FUNCTION {inbook} +FUNCTION {booklet} { output.bibitem -%% unselbst. Teile eines Buches werden am Anf. genannt, dann d selbst. Quelle - chapter empty$ - { "Es fehlen die Kapitelangaben in " cite$ * warning$ } - { type empty$ - { "Kap. " }%% d.i. die Standardvorgabe - { type }%% wenn man keine bes. Typform angeben will, koennte ein kl. -%% Zwischenraum gewaehlt werden, z.B. " \, " - if$ - chapter tie.or.space.connect " {In: }" * *%% n. Belieben fettes "In:" - %% diese Plazierung und der 2. * stammt v. N. Zacharias, Oldenburg, Juli 2000 - } - if$ - -%% -------- jetzt kommt der bibliogr. selbst. Teil author empty$ { format.editors "author and editor" output.check } - { format.authors output.nonnull - } + { format.authors format.editors output.nonnull } if$ set.colon.after - format.btitle.vol "title" output.check - crossref missing$ - { format.edition output - format.address.publisher.year "publisher" output.check - new.sentence - format.series.number.din output - part.of.sentence - format.pages "pages" output.check - note set.period.dash.check - note output - } - { format.book.crossref output.nonnull - note set.period.dash.check - note output + format.btitle "title" output.check + format.edition.or.version output + format.url output + format.online.lastcheck + format.howpublished output + series new.sentence.checka + format.series.number.din output + pages empty$ + { skip$ } + { pages set.period.dash.check + pages format.bkpages.collat.check output } if$ - isbn set.period.dash.check + type set.period.dash.check + format.digital.type output + doi set.period.dash.check + urn set.period.dash.check + format.doi.urn output + note set.period.dash.check + note output format.isbn.issn output fin.entry } -%% geaenderte Seitenzahlausgabe, wenn crossref-Feld benutzt wird, 27/2/97 + +FUNCTION {inbook} +{ output.bibitem + chapter format.chapter.inbook output.nonnull + crossref missing$ + { author empty$ + { format.editors "\,{In:\,}" swap$ * "author and editor" output.check } + { format.authors "\,{In:\,}" swap$ * output.nonnull } + if$ + author empty$ editor empty$ AND + { before.all 'output.state := } + { set.colon.after } + if$ + format.btitle.vol "title" output.check + format.edition output + format.address.publisher.year "publisher" output.check + new.sentence + format.series.number.din output + isbn set.period.dash.check + format.isbn.issn output + } + { format.book.crossref output.nonnull } + if$ + part.of.sentence + format.pages output + note set.period.dash.check + note output + fin.entry +} + FUNCTION {incollection} { output.bibitem format.authors "author" output.check set.colon.after format.title "title" output.check + format.version.url output + type empty$ NOT + { type #-1 #4 substring$ "mail" = + type #1 #4 substring$ "Mail" = + OR + 'skip$ + { format.online.lastcheck } + if$ + } + { format.online.lastcheck } + if$ crossref missing$ { format.in.ed.booktitle.din "booktitle" output.check format.edition output format.address.publisher.year "publisher" output.check + format.maillist.url output + format.maillist.lastcheck new.sentence format.series.number.din output - note set.period.dash.check - note output - isbn set.period.dash.check - issn set.period.dash.check - format.isbn.issn output - part.of.sentence - format.chapter.pages "pages" output.check - } - { format.incoll.inproc.crossref output.nonnull - note set.period.dash.check - note output + doi set.period.dash.check + urn set.period.dash.check + format.doi.urn output isbn set.period.dash.check issn set.period.dash.check format.isbn.issn output } - if$ - fin.entry + { format.incoll.inproc.crossref output.nonnull } + if$ + part.of.sentence + format.chapter.pages "pages" output.check + note set.period.dash.check + note output + fin.entry } -%% geaendert 22/2/94, 15/11/96 (Hinweis v. Alin Shindun, Uni Siegen) + FUNCTION {inproceedings} { output.bibitem format.authors "author" output.check @@ -994,101 +1434,112 @@ FUNCTION {inproceedings} crossref missing$ { format.in.ed.booktitle.din "booktitle" output.check address empty$ - { organization new.sentence.checka - organization output + { organization new.sentence.checka + organization output part.of.sentence format.address.publisher.year output - } - { format.address.publisher.year "publisher" output.check } + } + { format.address.publisher.year "publisher" output.check } if$ new.sentence - series empty$ %%neu nach Hinweis v. Alin Shindun, 15/11/96 + series empty$ 'skip$ { format.series.number.din output } if$ - note set.period.dash.check - note output - isbn set.period.dash.check - issn set.period.dash.check - format.isbn.issn output - part.of.sentence - format.pages output - } - { format.incoll.inproc.crossref output.nonnull - note set.period.dash.check - note output isbn set.period.dash.check issn set.period.dash.check format.isbn.issn output } - if$ - fin.entry -} - -FUNCTION {conference} { inproceedings }%% nach Patashnik, wg US-Kompatibilitaet - -%% geaendert, 11/6/99 -FUNCTION {manual} -{ output.bibitem - author empty$ - { organization empty$ - { title empty$ - 'skip$ - {format.btitle "title" output.check } - if$ - } - { organization output.nonnull - set.colon.after - format.btitle "title" output.check - } - if$ - } - { format.authors output.nonnull - set.colon.after - format.btitle "title" output.check - } + { format.incoll.inproc.crossref output.nonnull } if$ - format.edition "edition" output.check - author empty$ - { organization empty$ - { address output - part.of.sentence - } - 'skip$ - if$ - } - { address ": " * organization * output - part.of.sentence - } - if$ - format.date output - pages set.period.dash.check - format.pages.book output + part.of.sentence + format.pages "pages" output.check note set.period.dash.check note output fin.entry } -%% MASTERSTHESIS KFL, 17/2/94 -%% Ausgabe-Standard ist "Diplomarbeit", fuer andere Abschlussarbeiten -%% bei der Erfassung TYPE="anderer Typ" eingeben. -%% z.B. TYPE={Dissertation}, TYPE={Diss.}, TYPE={Habil.}, TYPE={Magisterarb.} -%% +FUNCTION {conference} { inproceedings }%% nach Patashnik, wg US-Kompatibilitaet + +FUNCTION {manual} +{ output.bibitem + author empty$ + { organization empty$ + { title empty$ + 'skip$ + {format.btitle "title" output.check } + if$ + } + 'skip$ + if$ + } + 'skip$ + if$ + format.authors.organization output.nonnull + set.colon.after + format.btitle "title" output.check + format.edition "edition" output.check + author empty$ organization empty$ AND + { address "address" output.check + part.of.sentence + } + { organization empty$ + { address "address" output.check + part.of.sentence + } + { address ": " * organization * output + part.of.sentence + } + if$ + } + if$ + format.date output + number empty$ + 'skip$ + { "(" number * ") " * output } + if$ + pages empty$ + { skip$ } + { pages set.period.dash.check + pages format.bkpages.collat.check output + } + if$ + format.doi output + format.url output + format.online.lastcheck + note set.period.dash.check + note output + fin.entry +} + +%% Standard ist "Diplomarbeit", anderes mit TYPE="anderer Typ" erfassen! +%% z.B. TYPE={Hausarbeit}, TYPE={Diss.}, TYPE={Habil.}, TYPE={Magisterarb.} FUNCTION {mastersthesis} { output.bibitem format.authors "author" output.check set.colon.after format.btitle "title" output.check address output - part.of.sentence + part.of.sentence school "school" output.check part.of.sentence - "Diplomarbeit" format.thesis.type output.nonnull + "Diplomarbeit" format.thesis.tr.type output.nonnull part.of.sentence format.date "year" output.check -%% pages new.sentence.checka - pages set.period.dash.check - format.pages.book output + format.url output + format.online.lastcheck +%% format.digital.resource.type + doi set.period.dash.check + urn set.period.dash.check + format.doi.urn output +%% pages set.period.dash.check +%% format.pages.book output + pages empty$ + { skip$ } + { pages set.period.dash.check + pages format.bkpages.collat.check output + } + if$ note set.period.dash.check note output fin.entry @@ -1100,76 +1551,172 @@ FUNCTION {phdthesis} %% {mastersthesis}% ist identisch bis auf Standardwert, s. set.colon.after format.btitle "title" output.check address output - part.of.sentence + part.of.sentence school "school" output.check part.of.sentence - "Diss." format.thesis.type output.nonnull % koennte auch `Dissertation' sein + "Diss." format.thesis.tr.type output.nonnull % koennte auch `Dissertation' sein part.of.sentence format.date "year" output.check - pages set.period.dash.check - format.pages.book output + format.url output + format.online.lastcheck +%% format.digital.resource.type + doi set.period.dash.check + urn set.period.dash.check + format.doi.urn output + pages empty$ + { skip$ } + { pages set.period.dash.check + pages format.bkpages.collat.check output + } + if$ +%% pages set.period.dash.check +%% format.pages.book output note set.period.dash.check note output fin.entry } -%% hiermit werden u.a. Normen erfasst +%% Normen, Vornormen, Schutzrechte (Patente) werden hiermit erfasst; +%% (z.Zt. auch noch Internetressourcen) +%% das type-Feld uebernimmt eine wichtige Steuerfunktion: FUNCTION {misc} { output.bibitem - note empty$ - { title empty$ - { "" } - { format.authors format.editors output.nonnull - format.btitle output - howpublished output - format.date output - } - if$ - } - { note duplicate$ #1 #4 substring$ "Norm" = - { output new.sentence - format.date output - format.title output - } - { pop$ "" - author empty$ - { editor empty$ - { organization empty$ - { 'skip$ } - { format.editors.organization output.nonnull - set.colon.after } - if$ - } - { format.editors format.editors.organization output.nonnull - set.colon.after } - if$ - } - { format.authors format.editors output.nonnull - set.colon.after } - if$ - format.btitle output - howpublished output - format.date output + type missing$ not + { type duplicate$ #1 #4 substring$ "Norm" = + type #1 #4 substring$ "Vorn" = OR + { " " * + format.number * output new.sentence - format.misc.series output%% neu 16/6/99 + format.date output + title empty$ + { skip$ } + { add.period$ new.sentence } + if$ + format.btitle "title" output.check note set.period.dash.check note output } + { duplicate$ #1 #6 substring$ "Schutz" = + { " " * format.number * output + new.sentence + "(" * format.date ")" * output + add.period$ new.sentence + format.authors.organization add.period$ output + note output + } + %% wenn irgendein anderer Typ eingetragen ist + { pop$ pop$ "" + title empty$ + { note empty$ + { url empty$ + { "there's no relevant field in " cite$ warning$ + pop$ "" + } + { format.url output }%%% + if$ + } + { note " " * output.nonnull } + if$ + } + { author empty$ + { editor empty$ + { organization empty$ + { skip$ } + { format.editors.organization output.nonnull + set.colon.after + } + if$ + } + { format.editors format.editors.organization + output.nonnull set.colon.after + } + if$ + } + { format.authors format.editors output.nonnull + set.colon.after + } + if$ + format.btitle output.nonnull + url empty$ + { format.edition output + format.howpublished output} + { format.howpublished output + format.edition.or.date output + format.url output + } + if$ + format.online.lastcheck + new.sentence + format.misc.series output +%% note set.period.dash.check + note output + } + if$ + } if$ + } + if$ } - if$ - fin.entry + %% wenn es keinen type gibt + { title empty$ + { note empty$ + { url empty$ + { "there's no relevant field in " cite$ warning$ + pop$ "" + } + { format.url output }%%% das waere e. reine URL + if$ + } + { note " " * output.nonnull + %% format.url format.date output + } + if$ + } + { author empty$ + { editor empty$ + { organization empty$ + { skip$ } + { format.editors.organization output.nonnull + set.colon.after + } + if$ + } + { format.editors format.editors.organization + output.nonnull set.colon.after + } + if$ + } + { format.authors format.editors output.nonnull + set.colon.after + } + if$ + format.btitle output.nonnull + url empty$ + { format.edition output + format.howpublished output} + { format.howpublished output + format.url output + format.edition.or.date output + format.online.lastcheck + } + if$ + new.sentence + format.misc.series output + note set.period.dash.check + note output + } + if$ + } + if$ + fin.entry } -FUNCTION {booklet} {misc}%% booklet ist nach dt. Vorgehensweise oft ueberfluessig - -%% geaendert 21/5/99 FUNCTION {proceedings} { output.bibitem editor empty$ { organization empty$ - { "" } + { "empty organization and editor in " cite$ * warning$ } { organization " (Veranst.)" * output } if$ } @@ -1178,60 +1725,79 @@ FUNCTION {proceedings} set.colon.after format.btitle "title" output.check volume empty$ - { "" output.nonnull } + { skip$ } { "{\textnormal{Bd.}}" volume tie.or.space.connect emphasize "volume" output.check } if$ format.address.publisher.year "publisher" output.check new.sentence format.series.number.din output.nonnull - pages set.period.dash.check - format.pages.book output - note set.period.dash.check - note output + pages empty$ + { skip$ } + { pages set.period.dash.check + pages format.bkpages.collat.check output + } + if$ isbn set.period.dash.check issn set.period.dash.check format.isbn.issn output + note set.period.dash.check + note output fin.entry } -%% geaendert 23/2/94 auch fuer Firmenschriften u."a. zu benutzen FUNCTION {techreport} { output.bibitem author empty$ - { format.editors "author and editor" output.check } + { format.editors "author and editor" output.check + format.tr.institution output.nonnull } { format.authors format.editors output.nonnull } if$ set.colon.after format.title "title" output.check - institution new.sentence.checka institution empty$ 'skip$ - { " / " institution * output.nonnull } + { author empty$ editor empty$ AND + 'skip$ + { institution new.sentence.checka + "/ " institution * output.nonnull + } + if$ + } if$ + format.version.url output + format.online.lastcheck format.address.publisher.year output number new.sentence.checka - format.tr.number.din "number" output.check -%% new.sentence - pages set.period.dash.check - format.pages.book output - note "note" output.check + format.tr.series.or.number "number" output.check + "Forschungsbericht" format.thesis.tr.type set.period.dash.check + "Forschungsbericht" format.thesis.tr.type output +%% format.digital.resource.type + pages empty$ + { skip$ } + { pages set.period.dash.check + pages format.bkpages.collat.check output + } + if$ isbn set.period.dash.check issn set.period.dash.check format.isbn.issn output + note set.period.dash.check + note "note" output.check fin.entry } -FUNCTION {unpublished} {misc}%% author, title, note muessen sein! howpublished -%% %% entfaellt natuerlich +FUNCTION {unpublished} {misc}%% AUTHOR, TITLE, NOTE muessen sein! +%% andere Felder sind optional + FUNCTION {default.type} { misc } + MACRO {jan} {"Januar"} MACRO {feb} {"Februar"} MACRO {mar} {"M{\^^b a}rz"} -%% nach Bernd Raichle, Febr. 1999 MACRO {apr} {"April"} @@ -1257,31 +1823,12 @@ MACRO {dez} {"Dezember"} MACRO {dec} {"Dezember"} - - -%%$$$ stillgelegte Beispiele fr den Gebrauch von Krzeln (hier Zs-Titel). +%%$$$ stillgelegte Beispiele fuer den Gebrauch von Kuerzeln (hier Zs-Titel). %%MACRO {acmcs} {"ACM Computing Surveys"} %%MACRO {acta} {"Acta Informatica"} -%%MACRO {cacm} {"Communications of the ACM"} - -%%MACRO {ibmjrd} {"IBM Journal of Research and Development"} - -%%MACRO {ibmsj} {"IBM Systems Journal"} - -%%MACRO {ieeese} {"IEEE Transactions on Software Engineering"} - -%%MACRO {ieeetc} {"IEEE Transactions on Computers"} - -%%MACRO {ieeetcad} -%% {"IEEE Transactions on Computer-Aided Design of Integrated Circuits"} - -%%MACRO {ipl} {"Information Processing Letters"} - -%%MACRO {jacm} {"Journal of the ACM"} - READ FUNCTION {sortify} @@ -1289,8 +1836,6 @@ FUNCTION {sortify} "l" change.case$ } -INTEGERS { len } - FUNCTION {chop.word} { 's := 'len := @@ -1308,18 +1853,13 @@ FUNCTION {sort.format.names} numnames 'namesleft := { namesleft #0 > } { nameptr #1 > - { " " * } - 'skip$ + { " " * } + 'skip$ if$ -%% s nameptr "{vv{ } }{ll{ }}{ ff{ }}{ jj{ }}" format.name$ 't := -% -% Zeile geaendert, damit die Namenszusaetze wie "von", "de" usw nach deutscher -% Norm richtig einsortiert werden. 27.10.94 Lueddecke -% s nameptr "{ll{ }}{ ff{ }}{ vv{ }}{ jj{ }}" format.name$ 't := nameptr numnames = t "others" = and - { "et al" * } - { t sortify * } + { ua.etal * } + { t sortify * } if$ nameptr #1 + 'nameptr := namesleft #1 - 'namesleft := @@ -1335,7 +1875,7 @@ FUNCTION {sort.format.title} "Die " #4 "Das " #4 "Ein " #4 - "Eine " #5 + "Eine " #5 "The " #4 t chop.word chop.word chop.word @@ -1351,10 +1891,10 @@ FUNCTION {sort.format.title} FUNCTION {author.sort} { author empty$ { key empty$ - { "to sort, need author or key in " cite$ * warning$ - "" - } - { key sortify } + { "to sort, need author or key in " cite$ * warning$ + "" + } + { key sortify } if$ } { author sort.format.names } @@ -1364,14 +1904,14 @@ FUNCTION {author.sort} FUNCTION {author.editor.sort} { author empty$ { editor empty$ - { key empty$ - { "to sort, need author, editor, or key in " cite$ * warning$ - "" - } - { key sortify } - if$ - } - { editor sort.format.names } + { key empty$ + { "to sort, need author, editor, or key in " cite$ * warning$ + "" + } + { key sortify } + if$ + } + { editor sort.format.names } if$ } { author sort.format.names } @@ -1381,14 +1921,14 @@ FUNCTION {author.editor.sort} FUNCTION {author.organization.sort} { author empty$ { organization empty$ - { key empty$ - { "to sort, need author, organization, or key in " cite$ * warning$ - "" - } - { key sortify } - if$ - } - { "The " #4 organization chop.word sortify } + { key empty$ + { "to sort, need author, organization, or key in " cite$ * warning$ + "" + } + { key sortify } + if$ + } + { "The " #4 organization chop.word sortify } if$ } { author sort.format.names } @@ -1398,14 +1938,14 @@ FUNCTION {author.organization.sort} FUNCTION {editor.organization.sort} { editor empty$ { organization empty$ - { key empty$ - { "to sort, need editor, organization, or key in " cite$ * warning$ - "" - } - { key sortify } - if$ - } - { "The " #4 organization chop.word sortify } + { key empty$ + { "to sort, need editor, organization, or key in " cite$ * warning$ + "" + } + { key sortify } + if$ + } + { "The " #4 organization chop.word sortify } if$ } { editor sort.format.names } @@ -1418,12 +1958,12 @@ FUNCTION {presort} or 'author.editor.sort { type$ "proceedings" = - 'editor.organization.sort - { type$ "manual" = - 'author.organization.sort - 'author.sort - if$ - } + 'editor.organization.sort + { type$ "manual" = + 'author.organization.sort + 'author.sort + if$ + } if$ } if$ @@ -1444,10 +1984,6 @@ ITERATE {presort} SORT -STRINGS { longest.label } - -INTEGERS { number.label longest.label.width } - FUNCTION {initialize.longest.label}%% nicht identisch mit der Fkt.im ALPHA-Stil { "" 'longest.label := #1 'number.label := @@ -1466,7 +2002,7 @@ FUNCTION {longest.label.pass} } EXECUTE { initialize.longest.label } - + ITERATE { longest.label.pass } FUNCTION {begin.bib} @@ -1475,6 +2011,17 @@ FUNCTION {begin.bib} { preamble$ write$ newline$ } if$ "\begin{thebibliography}{" longest.label * "}" * write$ newline$ + newline$ + "% this bibliography is generated by plaindin.bst [8.2] from 2005-12-21" + write$ newline$ newline$ + "\providecommand{\url}[1]{\texttt{#1}}" + write$ newline$ + "\expandafter\ifx\csname urlstyle\endcsname\relax" + write$ newline$ + " \providecommand{\doi}[1]{doi: #1}\else" + write$ newline$ + " \providecommand{\doi}{doi: \begingroup \urlstyle{rm}\Url}\fi" + write$ newline$ } EXECUTE {begin.bib} @@ -1489,5 +2036,3 @@ FUNCTION {end.bib} } EXECUTE {end.bib} - -%% Ende von PLAINDIN.BST KFL, 10/10/00 \ No newline at end of file diff --git a/report/report.tex b/report/report.tex index d52eac4..9afbf67 100644 --- a/report/report.tex +++ b/report/report.tex @@ -7,6 +7,13 @@ \usepackage{upquote} \usepackage{courier} \usepackage{microtype} +\usepackage{url} +\usepackage{tikz} +\usepackage{pgfplotstable} + +\newcounter{treeline} +\RequirePackage{mymacros} + \lstset{basicstyle=\footnotesize\ttfamily,breaklines=true,xleftmargin=1cm} @@ -26,17 +33,18 @@ \title{LCTP – Abschlussaufgabe Chef \\ Wintersemester 2013 / 2014} \begin{document} -\section{Aufgabenstellung} -\label{sec:aufgabenstellung} +\section{Chef - Konfigurationsmanagementsystem (Jörg Thalheim)} -\begin{enumerate} -\item Analysieren Sie die Funktionsweise von Chef und gehen Sie auf - Unterschiede zwischen Chef und Puppet ein -\item Wählens Sie zwei Netzwerkdienste aus die während der Lehrveranstaltung - besprochen wurden und erstellen Sie Provisionierungsvorlagen für diese -\item Beschreiben Sie wie die Verifikatioin von Provisionierungsvorlagen - bei der Bereitstellung von HPC-Software verwendet werden kann -\end{enumerate} +\input{task} +\input{comparison} +\input{services} +\input{tests} +\input{resume} + +\bibliography{sources}{} +\bibliographystyle{plain} + +\input{appandix} -% section aufgabenstellung (end) \end{document} +% vim: set spell spelllang=de_de diff --git a/report/resume.tex b/report/resume.tex new file mode 100644 index 0000000..bdf896a --- /dev/null +++ b/report/resume.tex @@ -0,0 +1,8 @@ +\subsection{Zusammenfassung} +\label{sub:Zusammenfassung} + +%TODO Resume und Ausblick +% welche Erkenntnisse wurden gewonnen +% Ansible, Salt. + +Chef diff --git a/report/services.tex b/report/services.tex new file mode 100644 index 0000000..6a3cfa6 --- /dev/null +++ b/report/services.tex @@ -0,0 +1,141 @@ +\subsection{Einrichtung der Netzwerkdienste} +\label{sub:einrichtung-der-netzwerkdienste} + +Für die Provisionierung der Netzwerkdienste wurde +\href{http://vagrantup.com}{Vagrant} verwendet. Dies ist ein Programm, um +schnell und reproduzierbar virtuelle Maschinen für Virtualbox und andere +Virtualsierungslösungen zu erstellen und zu starten. Die Einstellungen hierfür +werden in der Datei \texttt{Vagrantfile} hinterlegt, welche Vagrant beim Start +einliest. Vagrant kann Chef beim Erstellen von virtuellen Maschinen integrieren. +Zum Einsatz kam das Betriebssystem Ubuntu in der Version 12.04. Das Basisimage +hierfür wurde von \texttt{Chef}, der gleichnamigen Firma, bereitgestellt. Für +die Kommunikation mit Vagrant wurde die virtuelle Netzwerkkarte \texttt{eth0} +konfiguriert. Ein weitere Karte (\texttt{eth1}) wird für das interne virtuelle +Netzwerk zwischen den VMs zum Betreiben der Netzwerkdienste benötigt. + +Vagrant bietet keine Optionen, ein virtuelles Netzwerk zu erstellen, ohne das +jeder VM eine IP-Adresse fest oder DHCP unmittelbar nach dem Start zugewiesen +wird. In dem genannten Netzwerk sollte allerdings DHCP von dem Head-Node bereit +gestellt werden. Deswegen waren zusätzliche Kommandozeilenargumente an den +Befehl \texttt{VBoxManage} im Vagrantfile nötig, welches von Vagrant genutzt +wird um Virtualbox zu verwalten. Dies schränkt die Nutzung allerdings auf den +Hypervisor Virtualbox ein. + +Des weiteren wird Ruby auf dem Host benötigt, um beispielsweise die Tests +ausführen zu können. Auf Unix-Ähnlichen Systemen kann man diese +Programmiersprache mit dem Befehl: + +\shellcmd{curl -sSL https://get.rvm.io | bash -s stable} + +installiert werden. Auf dem Betriebssystem Windows kann auf den +\href{http://rubyinstaller.org/}{RubyInstaller} zurückgegriffen werden. Um die +benötigten Ruby-Bibliotheken zu installieren, müssen folgende 2 Befehle im +Projektverzeichnis ausgeführt werden: + +\shellcmd{gem install bundler} + +\shellcmd{bundle install} + +Zur Verwaltung der externen und selbst geschriebenen Cookbooks wurde die +Abhängigkeitsverwaltung \href{http://berkshelf.com}{Berkshelf} verwendet. Bei +diesem werden die zu ladenden Cookbooks und die gewünschte Version in einer +Datei namens Berksfile angegeben (vergleichbar mit +\href{http://bundler.io}{Bundler} und Gemfiles in Ruby). Berkshelf unterstützt +dabei verschiedene Quellen (per API von der Communityseite von Chef, Git, lokal) +und kann Abhängigkeiten zu anderen Cookbooks auflösen. Um die Cookbooks initial +zu laden, muss der Befehl: + +\shellcmd{berks install} + +im Projektverzeichnis ausgeführt werden. + +Für das Zusammenspiel mit Vagrant gibt es das Plugin +\href{https://github.com/berkshelf/vagrant-berkshelf}{vagrant-berkshelf}, so +dass die von Berkshelf verwalteten Cookbooks auch in Vagrant zur Verfügung +stehen. + +Für bestimmte Funktionen, wie Gemeinsame Ordner (shared folders) zwischen VM und +Host, müssen die \texttt{virtualbox\--client\--modules} in der VM installiert +sein. Diese sind in vielen Images bereits vorhanden, die es für Vagrant gibt. +Allerdings muss die Virtualbox-Version des Host mit der Version in der VM +übereinstimmen. Abhilfe schafft das Vagrantplugin +\href{https://github.com/dotless-de/vagrant-vbguest}{vagrant-vbguest}. Beim +Start der VM installiert das Plugin die gleiche Version des Modul in der VM. Wenn +Virtualbox mit Linux als Host-System ausgeführt wird, muss das Kernelmodule +\texttt{vboxdrv} geladen sein. Manche Linux-Distributionen installieren dieses +Module bereits während der Installation von Virtualbox. Auf Mac OS X und +Windows sind keine weiteren Schritte notwendig. + +Beide Plugins werden mit den Befehlen: + +\shellcmd{vagrant plugin install vagrant-vbguest} + +\shellcmd{vagrant plugin install vagrant-berkshelf} + +installiert. + +Gestartet wird die VM mit dem Befehl: + +\shellcmd{vagrant up} + +Während des ersten Starts wird die VM mit Chef provisioniert. Später kann Chef +erneut mit Befehl: + +\shellcmd{vagrant provision} + +gestartet werden. + +Die Netzwerkdienste sollen die Protokolle DHCP, DNS und NTP bereitstellen. Es +wird wie im Praktikum zwischen \texttt{Head-Nodes} und \texttt{Compute-Nodes} +unterschieden. Die Head-Node bietet die genannten Dienste an. Die Compute-Nodes +fordern auf dem internen Netzwerk per DHCP eine IP-Adresse an und nutzen den +DNS- und NTP-Dienst der ihr zugewiesenen Head-Node. + +Die Attribute für die Rollen und den Nodes wurden in JSON-Dateien in den +Verzeichnissen \texttt{roles/} und \texttt{nodes/} abgelegt. Es gibt je eine +Rollen-Datei für Compute-Nodes und Head-Nodes. In der aktuellen Konfiguration +erzeugt Vagrant eine Head-Node mit der FQDN \texttt{node0.lctp} und zwei +Compute-Nodes (\texttt{node1.lctp} und \texttt{node2.lctp}). + +Es wurden fünf Cookbooks geschrieben: +\begin{description} + \item[bind] + Für Bereitstellung des DNS-Dienstes wird Named aus dem BIND-Packet + installiert. Das Cookbook richtet diesen Dienst ein und fügt die in den + Attributen konfigurierten DNS-Einträge zu den entsprechenden Zonen hinzu. + \item[dhcp] + Dieses Cookbook richtet den \href{https://www.isc.org/downloads/dhcp/}{ISC-DHCP-Server} ein. Neben der + Zuordnung von festen IP-Adressen zu Nodes, kann ein DNS-Server und ein + NTP-Server + festgelegt werden. + \item[lctp-network] + Dieses Cookbook ist ein Wrapper um das + \href{https://github.com/redguide/network_interfaces}{network\_interfaces} + Cookbook. Wrapper-Cookbooks werden häufig dazu benutzt um bestehende + Cookbooks aus anderen Quellen um Funktionalität zu erweitern. Für + Compute-Nodes aktiviert das Cookbook für die DHCP in dem + virtuellen Netzwerk. Im Falle eines Head-Nodes wird eine statische + IP-Adresse gesetzt, der DNS-Server auf localhost festgelegt und + IP-Forwarding sowie Masquerading via iptables für den Router-Betrieb + aktiviert. + \item[ntp] + Dieses Cookbook richtet den NTP-Deamon ein, welcher die Zeit zwischen den + einzelnen Nodes synchronisiert. + \item[main] + Dieses Cookbook fasst alle oben genannten Cookbooks für Compute- und + Head-Node zusammen. Man könnte dies prinzipiell auch in den jeweiligen + Rollen erledigen. Rollen haben allerdings den Nachteil, dass diese + im Gegensatz zu Cookbooks nicht versionierbar sind und (bei Chef-Server) über + alle Umgebungen identisch sind. Somit ist eine Trennung zwischen Test- und + Produktivumgebung schwierig. +\end{description} + +Es wurden folgende externen Cookbooks verwendet: +\begin{description} + \item[apt] aktualisert die lokalen Paketlisten und den Paketcache. + \item[network\_interfaces] verwaltet Debian's Netzkonfiguration + \item[minitest-handler] Sammelt alle Tests in den Cookbooks und führt diese + nach der Provisionierung aus (siehe~\ref{minitest_handler}). +\end{description} + +% vim: set spell spelllang=de_dihr zugewiesenen e diff --git a/report/sources.bib b/report/sources.bib new file mode 100644 index 0000000..5c793c3 --- /dev/null +++ b/report/sources.bib @@ -0,0 +1,79 @@ +@misc{chefenterprise, + author = {Chef}, + title = {Enterprise-class features and support}, + url = {http://www.getchef.com/enterprise-chef/#features-and-support}, + year = {2014}, + month = {März} +} + +@misc{chefrun, + author = {Chef}, + title = {About the chef-client Run}, + url = {http://docs.opscode.com/essentials_nodes_chef_run.html}, + year = {2014}, + month = {März} +} + +@misc{chefhistory, + author = {Chef}, + title = {History of Chef: What's in a Name?}, + url = {http://www.youtube.com/watch?v=Ia2ItmjRsw8&feature=plcp}, + year = {2014}, + month = {März} +} + +@misc{puppetlanguage, + author = {Puppet-Labs}, + title = {Docs: Language: Basics}, + url = {http://docs.puppetlabs.com/puppet/latest/reference/lang_summary.html#compilation-and-catalogs}, + year = {2014}, + month = {März} +} + +@misc{puppetlanguagechangelog, + author = {Puppet-Labs}, + title = {Docs: History of Puppet Language Features}, + url = {http://docs.puppetlabs.com/guides/language_history.html#puppet-language-features-by-release}, + year = {2014}, + month = {März} +} + +@misc{chefscale, + author = {Chef}, + title = {Opscode Unleashes New Generation of Chef}, + url = {http://www.getchef.com/press-releases/opscode-unleashes-new-generation-of-chef/}, + year = {2013}, + month = {Februar} +} + +@misc{facebooklikeschef, + author = {Chef}, + title = {Scaling systems configuration at Facebook - Phil Dibowitz}, + url = {http://www.youtube.com/watch?v=SYZ2GzYAw_Q}, + year = {2013}, + month = {April} +} + +@misc{chefcommunitylist, + author = {Chef}, + title = {Opscode Mailing Lists}, + url = {http://lists.opscode.com/sympa/info/chef}, + year = {2014}, + month = {März} +} + +@misc{chefdeveloperlist, + author = {Chef}, + title = {Opscode Mailing Lists}, + url = {http://lists.opscode.com/sympa/info/chef-dev}, + year = {2014}, + month = {März} +} + +@misc{puppetcommunitylist, + author = {Puppet-Labs}, + title = {Anfrage auf Twitter}, + url = {https://twitter.com/puppetlabs/status/450760644329881600}, + year = {2014}, + month = {März} +} diff --git a/report/task.tex b/report/task.tex new file mode 100644 index 0000000..490a8b2 --- /dev/null +++ b/report/task.tex @@ -0,0 +1,13 @@ +\subsection{Aufgabenstellung} +\label{ssub:aufgabenstellung} + +\begin{itemize} +\item Analysieren Sie die Funktionsweise von Chef und gehen Sie auf + Unterschiede zwischen Chef und Puppet ein. +\item Wählen Sie zwei Netzwerkdienste aus, die während der Lehrveranstaltung + besprochen wurden und erstellen Sie Provisionierungsvorlagen für diese. +\item Beschreiben Sie, wie die Verifikation von Provisionierungsvorlagen + bei der Bereitstellung von HPC-Software verwendet werden kann. +\end{itemize} + +% vim: set spell spelllang=de_de diff --git a/report/tests.tex b/report/tests.tex new file mode 100644 index 0000000..7f0e594 --- /dev/null +++ b/report/tests.tex @@ -0,0 +1,132 @@ +\subsection{Verifikation} +\label{ssub:verifikation} + +Wie auch in der Softwareentwicklung müssen Konfigurationssysteme getestet +werden. Dies gestaltet sich oft als schwierig, weil nicht immer eine exakte +Kopie des aktuellen Produktionssystems zur Verfügung steht. Mit steigender +Komplexität steigt der Aufwand, Cookbooks manuell zu testen. Im Folgenden werden +verschiedene Möglichkeiten aufgeführt, wie dies automatisiert werden kann. + +Die erste und einfachste Methode ist der Befehl: + +\shellcmd{knife cookbook test [COOKBOOKS...]} + +Das Kommandozeilenprogramm \texttt{knife} ist ein Teil von Chef. Es ist das +primäre Verwaltungsprogramm für Chef-Administratoren. Der Unterbefehl +\texttt{cookbook test} überprüft den Ruby-Quellcode und die Templates des +Cookbooks auf Syntaxfehler. Allerdings treten viele Fehler erst zur Laufzeit +auf, im Besonderen da Ruby dynamisch typisiert ist und der Compiler +beispielsweise Tippfehler in Methoden und Variablennamen nicht erkennen kann. +Ein anderes Programm ist foodcritic. Es führt eine statische Codeanalyse ähnlich +\href{http://www.jslint.com/}{JSlint} oder +\href{http://perl-critic.stacka.to/}{Perl::Critic} auf der eigenen Codebasis +durch. Dabei wird der Ruby-Quellcode gegen einen Regelsatz getestet, um so +häufige Programmierfehler zu erkennen oder um Code-Konventionen innerhalb eines +Projekts einzuhalten. Dieser Regelsatz kann durch eigene Regeln erweitern +werden. + +\subsubsection{Chefspec} +\label{chefspec} + +Chefspec baut auf das in Ruby verbreitete Testframework +\href{http://rspec.info/}{RSpec} auf. Chefspec erweitert dabei RSpec um die +Funktion, Cookbooks zu laden und stellt spezielle Matcher (RSpec-Terminologie +für Assertions) bereit, um diese zu testen. Wie bereits in +Abschnitt~\ref{ablauf_einer_provisionierung} erwähnt, gibt es zwei Phasen bei +der Ausführung von Chef. Bei Chefspec wird der Provisionierungsprozess nur bis +zur Convergingphase durchlaufen. Die eigenen Tests überprüfen nur die erzeugten +\texttt{Ressourcen}. Dies hat den Vorteil, das Tests sehr schnell durchlaufen +werden, da keine Änderungen an einem System vorgenommen werden müssen. Dies hat +Vorteile beim Entwickeln, weil man auf diese Weise schnell Feedback bekommt. Das +Zusammenspiel mehrerer Cookbooks lässt sich dadurch gut testen. Außerdem +ermöglicht es, verschiedene Konfigurationen/Betriebssysteme zu testen, ohne das +diese (zeit)aufwendig aufgesetzt werden müssen. Da Chefspec allerdings zu keinen +Zeitpunkt Code auf dem System ausführt, sind weitere Integrationstest +unerlässlich. + +Der folgende Test wurde aus dem selbst geschriebenen NTP-Cookbook +(\ref{sub:einrichtung-der-netzwerkdienste}) entnommen. +\begin{lstlisting}[language=Ruby,caption={Chefspec-Test für das NTP-Cookbook}] +require_relative '../spec_helper' + +describe 'ntp::default' do + let(:chef_run) do + ChefSpec::Runner.new do |node| + node.set["ntp"]["subnets"] = ["::1", "127.0.0.1", "172.28.128.0 mask 255.255.255.0 nomodify notrap nopeer"] + end.converge(described_recipe) + end + + it "should setup ntp" do + chef_run.should install_package("ntp") + chef_run.should render_file("/etc/ntp.conf").with_content("172.28.128.0") + end +end +\end{lstlisting} + +Im \texttt{chef\_run}-Block wird dem fiktiven Node Attribute zugewiesen und das zu +testende Cookbook ausgeführt. Das Ergebnis wird in diesem Beispiel in dem Objekt +\texttt{chef\_run} gespeichert. Gegen dieses Objekt wird getestet, ob bestimmte +\texttt{Ressourcen} korrekt initialisiert wurden. In diesem Fall wird überprüft, ob +das Paket \texttt{ntp} installiert werden soll und ob das Subnetz in dem Template +in der Konfigurationsdatei \texttt{/etc/ntp.conf} richtig gesetzt wird. + +Die Tests werden mit dem Befehl \texttt{rspec} ausgeführt. Wenn keine weiteren Argumente +angegeben sind, führt dieses Programm alle Dateien unterhalb des Ordners \texttt{spec} +aus, dessen Dateinamen auf \texttt{\_spec.rb} enden. + +Um alle drei oben genannten Testmethoden gleichzeitig ausführen zu lassen, wurde +ein Rakefile geschrieben. \href{http://rake.rubyforge.org/}{Rake} ist das in +Ruby geschriebene Äquivalent zu Make, welches ein verbreitetes Buildprogramm +auf UNIX-ähnlichen Plattformen ist. Die Tests werden durch den Befehl: + +\shellcmd{rake test} + +ausgeführt. + +Dieser muss innerhalb Projektverzeichnisses aufgerufen werden. + +\subsubsection{Minitest-Handler} +\label{minitest_handler} + +\href{https://github.com/btm/minitest-handler}{Minitest-Handler} hingegen wird +nach jedem Provisionierungsdurchgang ausgeführt. Im Gegensatz zu Chefspec nutzt +es das Minitest-Framework, welches schon mit Ruby mitgeliefert wird. Um +Minitest-Handler zu nutzen, muss das Recipe aus +\texttt{Minitest-Handler-Cookbook} als erstes Recipe in der Node geladen werden. +Minitest-Handler durchsucht beim Durchlauf in jedem anderen Cookbook, in den +Unterordnern in \texttt{files/} nach dem Verzeichnis \texttt{test} und lädt alle +Tests aus diesem Verzeichnis. Über die Zeile: + +\begin{lstlisting}[language=Ruby] +describe_recipe "ntp::default" do # +#... +end +\end{lstlisting} + +wird angeben, zu welchem Test das Recipe gehört (In diesem Fall das +Recipe aus dem NTP-Cookbook). Wenn das entsprechende Recipe von dem Node +ausgeführt wird, wird der dazugehörige Test nach dem Provisionierungsdurchlauf +ebenfalls ausgeführt. Minitest-Handler erweitert RSpec um nützliche Methoden, um +den Status des Systems zu überprüfen. Nachfolgend ist ein Beispiel aus dem Bind-Cookbook, +welches in Abschnitt~\ref{sub:einrichtung-der-netzwerkdienste} erwähnt wurde: + +\begin{lstlisting}[language=Ruby, caption={\texttt{Minitest}-Test für das Bind-Cookbook}] +describe_recipe 'bind::default' do + it "starts the named daemon" do + service("bind9").must_be_running + end + it "should resolve dns" do + assert_sh("dig localhost @localhost") + end +end +\end{lstlisting} + +Die Methode \texttt{assert\_sh} überprüft den Exit-Code eines Befehls und schlägt +fehl, wenn dieser ungleich der Zahl Null ist, während die \texttt{service}-Methode den +Status eines Systemdienst überprüft. Weitere Testmethoden sind zum Beispiel +das Überprüfen von Verzeichnissen, Inhalte von Dateien oder Mountpoints. Viele +Fehler werden in der Regel schon von den Provider erkannt und festgestellt. +Minitest-Handler kann dies Erweitern um protokollspezifische Tests durchzuführen +oder das Testen von Funktionalität bestimmter Dienste. + +% vim: set spell spelllang=de_de diff --git a/script/fix_stdin_error.sh b/script/fix_stdin_error.sh deleted file mode 100644 index 0102a29..0000000 --- a/script/fix_stdin_error.sh +++ /dev/null @@ -1,10 +0,0 @@ -# If last line is `mesg n`, replace with conditional. -if [ "`tail -1 /root/.profile`" = "mesg n" ]; then - echo 'Patching basebox to prevent future `stdin: is not a tty` errors...' - sed -i '$d' /root/.profile - cat << 'EOH' >> /root/.profile - if `tty -s`; then - mesg n - fi -EOH -fi