aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Czygan <martin.czygan@gmail.com>2020-11-12 20:45:17 +0100
committerMartin Czygan <martin.czygan@gmail.com>2020-11-12 20:45:17 +0100
commit4eab32b1c5929b2d7f2e6d8fed76bdb49bf9c699 (patch)
treec326180ad8e5431026cd2f46da571307d226aa38
parent7c1927dd2800069b74bbe2f561127122daa0870f (diff)
parent30eab70787584a333714b18f1d64f362e4768730 (diff)
downloadfuzzycat-4eab32b1c5929b2d7f2e6d8fed76bdb49bf9c699.tar.gz
fuzzycat-4eab32b1c5929b2d7f2e6d8fed76bdb49bf9c699.zip
Merge branch 'bnewbold-sandcrawler' of https://github.com/bnewbold/fuzzycat into bnewbold-bnewbold-sandcrawler
* 'bnewbold-sandcrawler' of https://github.com/bnewbold/fuzzycat: sandcrawler slugify: yet more unicode corner-cases add sandcrawler-style title key method cluster: count empty keys (and don't return them) pipenv: explicit regex dependency gitignore: add .swp (vim) make: run pytest over fuzzycat/ to catch inline tests add support for key denylist
-rw-r--r--.gitignore4
-rw-r--r--Makefile6
-rw-r--r--Pipfile1
-rw-r--r--fuzzycat/__main__.py37
-rw-r--r--fuzzycat/cluster.py208
-rw-r--r--fuzzycat/sandcrawler-title-denylist.txt559
6 files changed, 761 insertions, 54 deletions
diff --git a/.gitignore b/.gitignore
index a1e72a2..d3e0e29 100644
--- a/.gitignore
+++ b/.gitignore
@@ -133,3 +133,7 @@ dmypy.json
/names.db
/tmp
fixtures/cluster_title_normalized_dups_size_keylen.tsv
+
+# Text Editors
+*~
+*.swp
diff --git a/Makefile b/Makefile
index 7a0490e..25efac0 100644
--- a/Makefile
+++ b/Makefile
@@ -16,7 +16,7 @@ deps: ## Install dependencies from setup.py into pipenv
pipenv install --pre '-e .[dev]'
.PHONY: style
-style: ## Apply import sorting and black source formatting on all files
+style: ## Apply import sorting and yapf source formatting on all files
isort --atomic fuzzycat/*
yapf -p -i -r fuzzycat/*
yapf -p -i -r tests
@@ -27,11 +27,11 @@ dist: ## Create source distribution and wheel
.PHONY: cov
cov: ## Run coverage report
- pytest --cov=fuzzycat tests/
+ pytest --cov=fuzzycat fuzzycat/*.py tests/
.PHONY: test
test: ## Run coverage report
- pytest -v tests/
+ pytest -v fuzzycat/*.py tests/
.PHONY: lint
lint: $(PY_FILES)
diff --git a/Pipfile b/Pipfile
index b7fc1cb..49b7e7a 100644
--- a/Pipfile
+++ b/Pipfile
@@ -20,6 +20,7 @@ importlib-metadata = "==1.7.0"
tokenizers = "*"
spacy = "*"
nltk = "*"
+regex = "*"
[requires]
python_version = "3.7"
diff --git a/fuzzycat/__main__.py b/fuzzycat/__main__.py
index 3845245..a65eb63 100644
--- a/fuzzycat/__main__.py
+++ b/fuzzycat/__main__.py
@@ -20,9 +20,9 @@ import pstats
import sys
import tempfile
-from fuzzycat.build import NgramLookup, TitleTokenList
from fuzzycat.cluster import (Cluster, release_key_title, release_key_title_ngram,
- release_key_title_normalized, release_key_title_nysiis)
+ release_key_title_normalized, release_key_title_nysiis,
+ release_key_title_sandcrawler)
def run_cluster(args):
@@ -32,10 +32,16 @@ def run_cluster(args):
'tnorm': release_key_title_normalized,
'tnysi': release_key_title_nysiis,
'tss': release_key_title_ngram,
+ 'tsandcrawler': release_key_title_sandcrawler,
}
+ key_denylist = None
+ if args.key_denylist:
+ with open(args.key_denylist, 'r') as f:
+ key_denylist = [l.strip() for l in f.readlines()]
cluster = Cluster(iterable=fileinput.input(args.files),
key=types.get(args.type),
tmpdir=args.tmpdir,
+ key_denylist=key_denylist,
prefix=args.prefix)
stats = cluster.run()
logger.debug(json.dumps(dict(stats)))
@@ -49,20 +55,6 @@ def run_verify(args):
pass
-def run_build(args):
- """
- Trying out.
- """
- if args.type == "ss":
- builder = NgramLookup(files=args.files, output=args.output)
- builder.run()
- elif args.type == "tt":
- builder = TitleTokenList(files=args.files, output=args.output)
- builder.run()
- else:
- raise NotImplementedError()
-
-
if __name__ == '__main__':
logging.basicConfig(
level=logging.DEBUG,
@@ -82,25 +74,16 @@ if __name__ == '__main__':
sub_cluster = subparsers.add_parser('cluster', help='group entities', parents=[parser])
sub_cluster.set_defaults(func=run_cluster)
sub_cluster.add_argument('-f', '--files', default="-", help='input files')
+ sub_cluster.add_argument('--key-denylist', help='file path to key denylist')
sub_cluster.add_argument('-t',
'--type',
default='title',
- help='cluster algorithm: title, tnorm, tnysi, tss')
+ help='cluster algorithm: title, tnorm, tnysi, tss, tsandcrawler')
sub_verify = subparsers.add_parser('verify', help='verify groups', parents=[parser])
sub_verify.add_argument('-f', '--files', default="-", help='input files')
sub_verify.set_defaults(func=run_verify)
- sub_build = subparsers.add_parser('build', help='build auxiliary databases', parents=[parser])
- sub_build.add_argument('-f', '--files', default="-", help='input files')
- sub_build.add_argument('-t', '--type', default="ss", help='type of database to build')
- sub_build.add_argument('-o',
- '--output',
- type=argparse.FileType('w'),
- default=sys.stdout,
- help='output file')
- sub_build.set_defaults(func=run_build)
-
args = parser.parse_args()
if not args.__dict__.get("func"):
print(__doc__, file=sys.stderr)
diff --git a/fuzzycat/cluster.py b/fuzzycat/cluster.py
index 97509e7..87b010e 100644
--- a/fuzzycat/cluster.py
+++ b/fuzzycat/cluster.py
@@ -69,15 +69,18 @@ import string
import subprocess
import sys
import tempfile
+import unicodedata
from dataclasses import dataclass, field
from typing import IO, Any, Callable, Dict, Generator, List, Optional, Tuple
import fuzzy
+import regex
__all__ = [
"release_key_title",
"release_key_title_normalized",
"release_key_title_nysiis",
+ "release_key_title_sandcrawler",
"sort_by_column",
"group_by",
"Cluster",
@@ -157,6 +160,159 @@ def release_key_title_nysiis(doc: KeyDoc) -> Tuple[str, str]:
return (ident, fuzzy.nysiis(title))
+# from http://zderadicka.eu/removing-diacritics-marks-from-strings/
+SANDCRAWLER_CHAR_MAP = {
+ '\N{Latin capital letter AE}': 'AE',
+ '\N{Latin small letter ae}': 'ae',
+ '\N{Latin capital letter Eth}': 'D',
+ '\N{Latin small letter eth}': 'd',
+ '\N{Latin capital letter O with stroke}': 'O',
+ '\N{Latin small letter o with stroke}': 'o',
+ '\N{Latin capital letter Thorn}': 'Th',
+ '\N{Latin small letter thorn}': 'th',
+ '\N{Latin small letter sharp s}': 's',
+ '\N{Latin capital letter D with stroke}': 'D',
+ '\N{Latin small letter d with stroke}': 'd',
+ '\N{Latin capital letter H with stroke}': 'H',
+ '\N{Latin small letter h with stroke}': 'h',
+ '\N{Latin small letter dotless i}': 'i',
+ '\N{Latin small letter kra}': 'k',
+ '\N{Latin capital letter L with stroke}': 'L',
+ '\N{Latin small letter l with stroke}': 'l',
+ '\N{Latin capital letter Eng}': 'N',
+ '\N{Latin small letter eng}': 'n',
+ '\N{Latin capital ligature OE}': 'Oe',
+ '\N{Latin small ligature oe}': 'oe',
+ '\N{Latin capital letter T with stroke}': 'T',
+ '\N{Latin small letter t with stroke}': 't',
+
+ # bnewbold additions
+ '\N{MICRO SIGN}': 'u',
+ '\N{LATIN SMALL LETTER C}': 'c',
+ '\N{LATIN SMALL LETTER F WITH HOOK}': 'f',
+ # bnewbold map-to-null (for non-printing stuff not in the regex)
+ '\N{PARTIAL DIFFERENTIAL}': '',
+ '\N{LATIN LETTER INVERTED GLOTTAL STOP}': '',
+ '\N{N-ARY SUMMATION}': '',
+ '\N{N-ARY PRODUCT}': '',
+ '\N{MODIFIER LETTER CIRCUMFLEX ACCENT}': '',
+ '\N{SNOWMAN}': '',
+ '\N{CARON}': '',
+}
+
+SANDCRAWLER_PREFIX_REMOVE = [
+ "original article: ",
+ "original article ",
+ "article: ",
+ "title: ",
+]
+
+# regex that matches all characters which should be removed
+SANDCRAWLER_REMOVE_CHAR_REGEX = regex.compile(
+ r"[\s\p{Punctuation}\p{M}\p{InCombiningDiacriticalMarks}\u2000-\u206F\u2E00-\u2E7F’·“”‘’“”«»「」¿–±§_`°ʖ©®¤=<>|+$^~≈√∫≤≥÷ƒ∆¬£¢∞¥◊€]"
+)
+
+
+def sandcrawler_slugify(raw: str) -> str:
+ """
+ Python re-implementation of sandcrawler Scala code for string comparison
+ ("scorable" strings)
+ """
+ slug = raw.strip().lower()
+
+ # transforms before running regex
+ for prefix in SANDCRAWLER_PREFIX_REMOVE:
+ if slug.startswith(prefix):
+ slug = slug[:len(prefix)]
+
+ slug = slug.replace("&apos;", "'")
+
+ # iterate over all chars and replace from map, if in map; then lower-case again
+ slug = ''.join([SANDCRAWLER_CHAR_MAP.get(c, c) for c in slug])
+
+ # early bailout before executing regex
+ if not slug:
+ return ""
+
+ slug = unicodedata.normalize('NFKD', slug)
+ slug = SANDCRAWLER_REMOVE_CHAR_REGEX.sub('', slug)
+
+ return slug.lower()
+
+
+def test_sandcrawler_slugify() -> None:
+ test_cases = [
+ ("", ""),
+ ("asdf", "asdf"),
+ ("'Hello World!'", "helloworld"),
+ ("ASDF", "asdf"),
+ ("as\n df", "asdf"),
+ ("as\u0142 bb \u00f8", "aslbbo"),
+ ("`hello¿", "hello"),
+ ("علمية", "علمية"),
+ ("期刊的数字", "期刊的数字"),
+ ("les pré-impressions explorées à partir", "lespreimpressionsexploreesapartir"),
+
+ # "MICRO SIGN"
+ ("\xb5meter", "umeter"),
+ # "GREEK SMALL LETTER MU"
+ ("\u03bcmeter", "\u03bcmeter"),
+
+ # TODO: ("salt &and; pepper", "saltpepper"),
+ # TODO: ("new <b>and</b> improved", "newandimproved"),
+
+ # some via https://github.com/minimaxir/big-list-of-naughty-strings/blob/master/blns.txt
+ ("-9223372036854775808/-1", "92233720368547758081"),
+ (r",./;'[]\-= <>?:\"{}|_+ !@#$%^&*()`~", ""),
+ (" \n\r \x85 \u1680\u2002\u2003\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u202f\u205f\u3000",
+ ""),
+ (r"Ω≈ç√∫˜≤≥÷", "ωc"),
+ (r"åß∂ƒ©˙∆˚¬…æ", "asfae"),
+ (r"œ∑´®†¥¨ˆøπ“‘", "oeoπ"),
+ (r"¡™£¢∞§¶•ªº–≠ ", "tmao"),
+ (r"¸˛Ç◊ı˜Â¯˘¿", "cia"),
+ (r"ÅÍÎÏ˝ÓÔÒÚÆ☃", "aiiiooouae"),
+ (r"Œ„´‰ˇÁ¨ˆØ∏”’", "oeao"),
+ (r"`⁄€‹›fifl‡°·‚—±", "fifl"),
+ (r"ЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя",
+ "еђгєѕііјљњћкиуџабвгдежзииклмнопрстуфхцчшщъыьэюяабвгдежзииклмнопрстуфхцчшщъыьэюя"),
+ (r"⁰⁴⁵₀₁₂", "045012"),
+ (r"社會科學院語學研究所", "社會科學院語學研究所"),
+ # TODO: ("パーティーへ行かないか", "パーティーへ行かないか"),
+ # TODO: ("表ポあA鷗ŒéB逍Üߪąñ丂㐀𠀀", "表ポあa鷗oeebB逍usaan丂㐀𠀀"),
+ (r"( ͡° ͜ʖ ͡°)", ""),
+ # emoji ok? I guess
+ (r"👾 🙇 💁 🙅 🙆 🙋 🙎 🙍", "👾🙇💁🙅🙆🙋🙎🙍"),
+ (r"2️⃣ 3️⃣ 4️⃣ 5️⃣", "2345"),
+ (r"﷽ ", "﷽"),
+ (r"̗̺͖̹̯͓Ṯ̤͍̥͇͈h̲́e͏͓̼̗̙̼̣͔ ͇̜̱̠͓͍ͅN͕͠e̗̱z̘̝̜̺͙p̤̺̹͍̯͚e̠̻̠͜r̨̤͍̺̖͔̖̖d̠̟̭̬̝͟i̦͖̩͓͔̤a̠̗̬͉̙n͚͜ ̻̞̰͚ͅh̵͉i̳̞v̢͇ḙ͎͟-҉̭̩̼͔m̤̭̫i͕͇̝̦n̗͙ḍ̟ ̯̲͕͞ǫ̟̯̰̲͙̻̝f ̪̰̰̗̖̭̘͘c̦͍̲̞͍̩̙ḥ͚a̮͎̟̙͜ơ̩̹͎s̤.̝̝ ҉Z̡̖̜͖̰̣͉̜a͖̰͙̬͡l̲̫̳͍̩g̡̟̼̱͚̞̬ͅo̗͜.̟",
+ "thenezperdianhivemindofchaoszalgo"),
+ (r"The quick brown fox jumps over the lazy dog", "thequickbrownfoxjumpsoverthelazydog"),
+ (r"The quick brown fox jumps over the lazy dog", "thequickbrownfoxjumpsoverthelazydog"),
+ (r"𝕋𝕙𝕖 𝕢𝕦𝕚𝕔𝕜 𝕓𝕣𝕠𝕨𝕟 𝕗𝕠𝕩 𝕛𝕦𝕞𝕡𝕤 𝕠𝕧𝕖𝕣 𝕥𝕙𝕖 𝕝𝕒𝕫𝕪 𝕕𝕠𝕘 ", "thequickbrownfoxjumpsoverthelazydog"),
+ ]
+
+ for in_str, out_str in test_cases:
+ if sandcrawler_slugify(in_str) != out_str:
+ for c in list(sandcrawler_slugify(in_str)):
+ try:
+ print(unicodedata.name(c))
+ except ValueError:
+ print(ord(c))
+ #print(ord(c))
+ print("----")
+ for c in list(out_str):
+ print(unicodedata.name(c))
+ print(in_str)
+ assert sandcrawler_slugify(in_str) == out_str
+
+
+def release_key_title_sandcrawler(doc: KeyDoc) -> Tuple[str, str]:
+ ident, title = release_key_title(doc)
+ slug = sandcrawler_slugify(title)
+ return (ident, slug)
+
+
def release_key_title_ngram(doc: KeyDoc, n=3) -> Tuple[str, str]:
"""
Derive a key from title.
@@ -198,22 +354,24 @@ class Cluster:
iterable: collections.abc.Iterable,
key: Callable[[Any], Tuple[str, str]],
output: IO[str] = sys.stdout,
+ key_denylist: Optional[List[str]] = None,
prefix: str = "fuzzycat-",
tmpdir: str = tempfile.gettempdir(),
strict: bool = False):
- """
- Setup a clusterer, using a custom key function.
- """
self.iterable: collections.abc.Iterable = iterable
self.key: Callable[[Any], Tuple[str, str]] = key
self.output: IO[str] = output
self.prefix: str = prefix
self.tmpdir: str = tmpdir
self.counter: Dict[str, int] = collections.Counter({
- "key_err": 0,
+ "key_fail": 0,
"key_ok": 0,
+ "key_empty": 0,
+ "key_denylist": 0,
"num_clusters": 0,
})
+ self.strict = strict
+ self.key_denylist = key_denylist
def run(self):
"""
@@ -226,29 +384,31 @@ class Cluster:
try:
doc = json.loads(line)
id, key = self.key(doc)
- # XXX: if the line itself contains tabs, we need to remove
- # them here; maybe offer TSV and JSON output and extra flag
- print("{}\t{}\t{}".format(id, key, line.replace("\t", " ")), file=tf)
except (KeyError, ValueError):
if strict:
raise
- self.counter["key_err"] += 1
- else:
- self.counter["key_ok"] += 1
-
- try:
- sf = self.sort(tf.name, opts='-k 2')
- with open(sf) as f:
- for doc in self.group_by(f, key=cut(f=1)):
- self.counter["num_clusters"] += 1
- json.dump(doc, self.output)
- self.output.write("\n")
- except Exception as exc:
- raise
- finally:
- os.remove(sf)
- os.remove(tf.name)
-
+ self.counter["key_fail"] += 1
+ continue
+ if not key:
+ self.counter["key_empty"] += 1
+ continue
+ if self.key_denylist and key in self.key_denylist:
+ self.counter["key_denylist"] += 1
+ continue
+ self.counter["key_ok"] += 1
+ # XXX: if the line itself contains tabs, we need to remove
+ # them here; maybe offer TSV and JSON output and extra flag
+ print("{}\t{}\t{}".format(id, key, line.replace("\t", " ")), file=tf)
+
+ sf = self.sort(tf.name, opts='-k 2')
+ with open(sf) as f:
+ for doc in self.group_by(f, key=cut(f=1)):
+ self.counter["num_clusters"] += 1
+ json.dump(doc, self.output)
+ self.output.write("\n")
+
+ os.remove(sf)
+ os.remove(tf.name)
return self.counter
def sort(self, filename: str, opts: str = "-k 2", fast: bool = True, mode: str = "w"):
diff --git a/fuzzycat/sandcrawler-title-denylist.txt b/fuzzycat/sandcrawler-title-denylist.txt
new file mode 100644
index 0000000..ef575b4
--- /dev/null
+++ b/fuzzycat/sandcrawler-title-denylist.txt
@@ -0,0 +1,559 @@
+abbreviations
+abbreviationsandacronyms
+aboutauthors
+abouttheauthor
+abouttheauthors
+aboutthecover
+abouttheeditors
+abreviations
+abstract
+abstractnotsubmittedforonlinepublication
+abstractoriginalarticle
+abstracts
+abstractsofaapaposterandpodiumpresentations
+abstractsofcommunications
+abstractsofthesesfromthescandinaviancountries
+abstractwithdrawn
+acknowledgement
+acknowledgements
+acknowledgementsvii
+acknowledgementtoreferees
+acknowledgementtoreviewers
+acknowledgment
+acknowledgmentofreferees
+acknowledgments
+addendum
+additionalresources
+address
+advertisement
+advertisersindex
+affect
+affiliation
+afterword
+agenda
+agradecimentos
+agradecimientos
+aimsandscope
+analysis
+annexa
+announcement
+announcements
+annualacknowledgementofmanuscriptreviewers
+anotefromtheeditor
+appendices
+appendix
+appendix1
+appendixa
+appendixb
+appointmentsandstaffchanges
+approximation
+apresentacao
+article
+articlenumber
+articles
+articlesofsignificantinterestselectedfromthisissuebytheeditors
+associationnews
+ataglance
+atribute
+attention
+authorguidelines
+authorindex
+authorindexforvolume81
+authorreply
+authors
+authorsreply
+authorsresponse
+avantpropos
+award
+awardsappointmentsannouncements
+backcover
+background
+backmatter
+berichtigung
+besprechungen
+bibliografia
+bibliographie
+bibliography
+bigdata
+blankpage
+blood
+boardoftrustees
+booknotes
+booknotices
+bookofabstracts
+bookreview
+bookreviews
+bookreviewsandnotices
+bookreviewssection
+booksreceived
+buchbesprechung
+buchbesprechungen
+bulletin
+calendar
+calendarofevents
+calendarofmeetings
+callforarticles
+callforpapers
+casereport
+casereports
+casestudy
+chairmansopeningremarks
+changes
+chaos
+chapter1
+chapter10
+chapter1introduction
+chapter2
+chapter7
+chapteri
+chapterone
+chapteroneintroduction
+chaptertwo
+chapterx
+citation
+classes
+classified
+classifieds
+closingremarks
+collaborateurs
+comment
+commentaries
+commentary
+commentaryon
+commenton
+comments
+commentto
+committee
+communication
+communications
+communicationstotheeditor
+communiquedepresse
+community
+components
+comptesrendus
+computerscience
+concludingremarks
+conclusion
+conclusions
+conferencereport
+congratulations
+congresscalendar
+conservation
+content
+contents
+context
+continuingeducation
+continuingmedicaleducation
+contributors
+copyright
+copyrightform
+copyrightnotice
+correction
+corrections
+correspondence
+corrigenda
+corrigendum
+councilminutes
+cover
+coverimage
+currentresearch
+curriculumvitae
+danksagung
+dearreaders
+decisionmaking
+dedication
+dedicatoria
+definition
+description
+discussion
+diskussion
+distribution
+documents
+ear
+economics
+editorial
+editorialadvisoryboard
+editorialannouncement
+editorialboard
+editorialcomment
+editorialcomments
+editorialconsultants
+editoriale
+editorialeditorial
+editorialforeword
+editorialinformation
+editorialintroduction
+editorialintroductions
+editorialnote
+editorialnotes
+editorialpreface
+editorials
+editorialsoftwaresurveysection
+editorialstaff
+editorialstatement
+editorinchief
+editors
+editorschoice
+editorscomment
+editorscomments
+editorscorner
+editorscorrespondence
+editorsforeword
+editorsintroduction
+editorsletter
+editorsnote
+editorsnotes
+editorspage
+editorspicks
+editorspreface
+education
+einfuhrung
+einleitung
+electrophoresis
+employment
+endnotes
+entrevista
+entscheidungsverzeichnis
+epilogue
+equipment
+errata
+erratum
+essay
+essays
+executivesummary
+exercises
+expediente
+extendedabstracts
+feature
+features
+fichatecnica
+figure3
+finalexam
+finalreport
+focus
+foreward
+foreword
+forthcomingarticles
+forthcomingevents
+fortherecord
+forum
+frequentlyaskedquestions
+fromtheeditor
+fromtheeditorinchief
+fromtheeditors
+fromtheeditorsdesk
+fromthepresident
+frontmatter
+furtherreadings
+genealogy
+generaldiscussion
+generalinformation
+generalintroduction
+germany
+gettingstarted
+glosario
+glossary
+glossaryofterms
+guesteditorial
+guesteditorsforeword
+guesteditorsintroduction
+guideforauthors
+guidelinesforcontributors
+health
+heartfailure
+highlights
+highlightsfromthisissue
+highlightsofthisissue
+history
+home
+homework
+hypothesis
+iii
+imageofthemonth
+impactfactor
+importantnotice
+impressum
+inbrief
+index
+indexofauthors
+indexofauthorsandtitles
+indice
+indicegeneral
+informationforauthors
+informationtoauthors
+inhalt
+inhaltsverzeichnis
+inleiding
+inmemoriam
+inreply
+inresponse
+insidethisissue
+institutenews
+instructionsforauthors
+instructionstoauthors
+interview
+inthestudy
+inthisissue
+introducao
+introduccion
+introduction
+introductionandoverview
+introductiongenerale
+introductiontotheissue
+introductiontothespecialissue
+introductorycomments
+introductoryremarks
+introduzione
+inventions
+invitedcommentary
+issuesandevents
+jobdescription
+journalclub
+journalscan
+keywords
+kurzkommentiert
+languageteaching
+lecture
+letter
+letterfromtheeditor
+letterfromtheeditorinchief
+letterfromtheeditors
+letterfromthepresident
+letters
+letterstotheeditor
+letterstotheeditors
+lettertotheeditor
+lettertotheeditors
+liminaire
+linearalgebra
+linearregression
+links
+listedestableaux
+listofabbreviations
+listofcontributors
+listoffigures
+listofparticipants
+listofpublications
+listofreferees
+listofreviewers
+listoftables
+literacy
+literatur
+literature
+literaturecited
+literaturereview
+literaturrundschau
+literaturverzeichnis
+litteraturverzeichniss
+livresrecus
+lucina
+lungcancer
+magazin
+maintenance
+materials
+materialsafetydatasheet
+materialsandmethods
+medicinalchemistry
+meetingabstracts
+meetingreport
+meetings
+meetingsandconferences
+meetingsofinterest
+membershipapplication
+memoranda
+memorandum
+messagefromgeneralcochairs
+messagefromthechairs
+messagefromtheeditor
+messagefromtheeditorinchief
+messagefromthepresident
+messagefromtheprogramchairs
+messagefromtheprogramcochairs
+metaanalysis
+miscellanea
+miscellaneous
+miscellany
+missionstatement
+motivation
+mrsnews
+name
+newbooks
+newlyelectedmembersofthecollege
+newproducts
+news
+newsandnotes
+newsandreviews
+newsandviews
+newsbriefs
+newsinbrief
+newsnotes
+newsviews
+noii
+note
+notefromtheeditor
+notes
+notesandcomments
+notesandnews
+notesdelecture
+notesforcontributors
+notesoncontributors
+notice
+noticeboard
+notitle
+notitleavailable
+nr
+obituaries
+obituary
+online
+openaccess
+openingaddress
+openingremarks
+oralabstracts
+oralpresentations
+organizingcommittee
+originalarticle
+originalarticles
+other
+outline
+overview
+panorama
+papers
+paperstoappearinforthcomingissues
+partone
+personalandmiscellaneous
+perspective
+perspectives
+philosophy
+pictureofthemonth
+place
+pointofview
+positionsavailable
+poster
+posterpresentations
+postscript
+preface
+prefaceandacknowledgements
+prefacetothesecondedition
+preliminarymaterial
+presentacio
+presentacion
+presentation
+presidentialaddress
+presidentsmessage
+presidentsreport
+pressrelease
+print
+printing
+proceedings
+proceedingsofthenationalacademyofsciences
+profile
+programcommittee
+projectmanagement
+prologue
+publication
+publichealth
+publishersnote
+question
+questionsandanswers
+radiology
+readersforum
+recensiones
+recensions
+recentpublications
+redaktorensforord
+referate
+references
+referenciasbibliograficas
+regression
+rehabilitation
+rejoinder
+remerciements
+reply
+replybyauthors
+researchresearchers
+resenas
+resources
+response
+responsetothelettertotheeditor
+results
+resume
+resumen
+resumes
+resumo
+retraction
+review
+reviewarticle
+revieweracknowledgement
+revieweracknowledgement2013
+reviewers
+reviewessay
+reviews
+reviewsanddescriptionsoftablesandbooks
+reviewsofbooks
+rezension
+rezensionen
+safety
+section
+security
+selectedbibliography
+shortcommunication
+shorternotices
+shortnotices
+socialengineering
+sociology
+sommaire
+sommario
+specialreport
+specialsection
+specifications
+spistresci
+subjectindex
+subscriptions
+suggestedreadings
+sumario
+summaries
+summariesofkeyjournalarticles
+summary
+summaryofproceedings
+summer
+sun
+supplementarymaterial
+symposium
+symptom
+synthese
+tabledesmatieres
+tableofcontents
+tableofcontentsandprologue
+technicalreport
+theauthors
+theauthorsreply
+thebasics
+theeditorsdesk
+thefirstauthorreplies
+thelancet
+theoreticalbackground
+thetimes
+theworldbank
+theyearinreview
+thismonthin
+thismonthinthejournal
+timemanagement
+titeleiinhaltsverzeichnis
+title
+titlepage
+titlepagei
+tocorrespondents
+totheeditor
+unitedkingdom
+unitednations
+unitedstates
+upcomingevents
+vorwort
+website
+welcome
+whatshappening
+whatsnew
+workscited
+yourquestionsanswered
+zudiesemheft
+zusammenfassung