#!/usr/bin/perl -w

# Identifies languages named in subjects.

use warnings 'FATAL', 'all';
# Make every warning fatal.

use strict;
# Require strict checking of variable references, etc.

use utf8;
# Make Perl interpret the script and standard files as UTF-8 rather than bytes.

use Unicode::Normalize 'NFC';
# Import a function to normalize Unicode strings.

open IN, '<:utf8', 'goodsubs.txt';
# Open the input file for reading.

open OUT, '>:utf8', 'sublangs.txt';
# Create or truncate an output file and open it for writing.

my (@el, @el0, @el1, @lang, @seg, %sj, $sj);

while (<IN>) {
# For each subject line:

	chomp;
	# Delete its trailing newline.

	s/\. \[from old catalog\]//g;
	# Delete all occurrences of “. [from old catalog]” from it.

	@seg = (split /\t/);
	# Identify a list of its segments.

	if (exists $sj{$seg[1]}) {
	# If the subject has already been encountered:

		$sj{$seg[1]} += $seg[0];
		# Add this line’s count to the subject’s count.

	}

	else {
	# Otherwise, i.e. if the subject has not yet been encountered:

		$sj{$seg[1]} = $seg[0];
		# Add its count to the table of encountered subjects.

	}

}

foreach $sj (sort (keys %sj)) {
# For each subject:

	@seg = ($sj{$sj}, $sj);
	# Identify its count and its text.

	@el = (split / -- /, $seg[1]);
	# Identify its elements.

	if ($seg[1] =~ /(?:Polyglot|Multilingual)/i) {
	# If it is polyglot or multilingual:

		print OUT "t\t-\t-\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 3)
		&& (@el0 = ($el[0] =~ /^(.+? Sign Language)$/i))
		&& (&Lex ($el[1]))
		&& (@el1 = (&TLang ($el[2])))
	) {
	# Otherwise, if the subject is a sign-language lexicon in standard LC format:

		@lang = (&Norm ($el0[0], $el1[0]));
		# Identify a list of the language names normalized.

		print OUT "f\t<l>$lang[0]\t<l>$lang[1]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 3)
		&& ($el[1] =~ /^Sign Language$/i)
		&& (&Lex ($el[2]))
	) {
	# Otherwise, if the subject is an ethnically defined sign-language lexicon with
	# unspecified target language in segmented LC format:

		@lang = (&Norm ("$el[0] Sign Language"));
		# Identify a list of the language names normalized.

		print OUT "f\t<l>$lang[0]\t-\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 3)
		&& ($el[0] eq 'Basic English')
		&& (&Lex ($el[1]))
		&& (@el1 = (&TLang ($el[2])))
	) {
	# Otherwise, if the subject is a Basic English lexicon in standard LC format:

		@lang = (&Norm ($el1[0]));
		# Identify a list of the target-language names normalized.

		print OUT "f\t<d>$el[0]\t<l>$lang[0]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 2)
		&& ($el[0] eq 'Black English')
		&& (&Lex ($el[1]))
	) {
	# Otherwise, if the subject is a Black English lexicon with undefined target language
	# in standard LC format:

		print OUT "f\t<d>$el[0]\t-\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 3)
		&& (@el0 = (&SLang ($el[0])))
		&& (&Lex ($el[1]))
		&& (@el1 = (&TLang ($el[2])))
	) {
	# Otherwise, if the subject is a bilingual lexicon in basic standard LC format:

		@lang = (&Norm ($el0[0], $el1[0]));
		# Identify a list of the language names normalized.

		print OUT "f\t<l>$lang[0]\t<l>$lang[1]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 4)
		&& (@el0 = (&SLang ($el[0])))
		&& (&Lex ($el[1]))
		&& (@el1 = (&TLang ($el[2])))
	) {
	# Otherwise, if the subject is a target-language-qualified bilingual lexicon in
	# basic standard LC format:

		@lang = (&Norm ($el0[0], $el1[0]));
		# Identify a list of the language names normalized.

		print OUT "f\t<l>$lang[0]\t<l>$lang[1]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 4)
		&& (@el0 = (&SLang ($el[1])))
		&& (&Lex ($el[2]))
		&& (@el1 = (&TLang ($el[3])))
	) {
	# Otherwise, if the subject is a preposed-topical bilingual lexicon in
	# basic standard LC format:

		@lang = (&Norm ($el0[0], $el1[0]));
		# Identify a list of the language names normalized.

		print OUT "f\t<l>$lang[0]\t<l>$lang[1]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 3)
		&& ((@el0 = ($el[0] =~ /^(.+?) (?:literature|philology)$/i)) || (@el0 = ($el[0] =~ /^Abbreviations, (.+?)$/i)))
		&& (&Lex ($el[1]))
		&& (@el1 = (&TLang ($el[2])))
	) {
	# Otherwise, if the subject is a bilingual lexicon in elaborated standard LC format:

		@lang = (&Norm ($el0[0], $el1[0]));
		# Identify a list of the language names normalized.

		print OUT "f\t<l>$lang[0]\t<l>$lang[1]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 3)
		&& (@el0 = ($el[0] =~ /^(.+?) dialects?$/i))
		&& (&Lex ($el[1]))
		&& (@el1 = (&TLang ($el[2])))
	) {
	# Otherwise, if the subject is a dialect-to-language lexicon in standard LC format:

		@lang = (&Norm ($el0[0], $el1[0]));
		# Identify a list of the language names normalized.

		print OUT "f\t<d>$lang[0]\t<l>$lang[1]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 3)
		&& (@el0 = (&TLang ($el[0])))
		&& (&Lex ($el[1]))
		&& (@el1 = ($el[2] =~ /^(.+?) dialects?$/i))
	) {
	# Otherwise, if the subject is a language-to-dialect lexicon in standard LC format:

		@lang = (&Norm ($el0[0], $el1[0]));
		# Identify a list of the language names normalized.

		print OUT "f\t<l>$lang[0]\t<d>$lang[1]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 3)
		&& (@el0 = ($el[0] =~ /^(.+?) dialects?$/i))
		&& (&Lex ($el[1]))
		&& (@el1 = ($el[2] =~ /^(.+?) dialects?$/i))
	) {
	# Otherwise, if the subject is a dialect-to-dialect lexicon in standard LC format:

		@lang = (&Norm ($el0[0], $el1[0]));
		# Identify a list of the language names normalized.

		print OUT "f\t<d>$lang[0]\t<d>$lang[1]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 4)
		&& (@el0 = (&TLang ($el[0])))
		&& (&Lex ($el[1]))
		&& (@el1 = ($el[2] =~ /^(.+?) dialects?$/i))
	) {
	# Otherwise, if the subject is a language-to-location-based-dialect lexicon in standard
	# LC format:

		@lang = (&Norm ($el0[0], "$el[3] $el1[0]"));
		# Identify a list of the language names normalized.

		print OUT "f\t<l>$lang[0]\t<d>$lang[1]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 5)
		&& (@el0 = (&TLang ($el[0])))
		&& (&Lex ($el[1]))
		&& ($el[3] eq 'Dialects')
	) {
	# Otherwise, if the subject is a language-to-location-based-dialect lexicon in segmented
	# LC format:

		@lang = (&Norm ($el0[0], "$el[4] $el[2]"));
		# Identify a list of the language names normalized.

		print OUT "f\t<l>$lang[0]\t<d>$lang[1]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 4)
		&& (@el0 = ($el[0] =~ /^(.+?) dialects?$/i))
		&& (&Lex ($el[2]))
		&& (@el1 = (&TLang ($el[3])))
	) {
	# Otherwise, if the subject is a topical dialect-to-language lexicon in standard LC format:

		@lang = (&Norm ($el0[0], $el1[0]));
		# Identify a list of the language names normalized.

		print OUT "f\t<d>$lang[0]\t<l>$lang[1]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 5)
		&& (@el0 = ($el[0] =~ /^(.+?) languages?$/i))
		&& ($el[1] eq 'Dialects')
		&& (&Lex ($el[3]))
		&& (@el1 = (&TLang ($el[4])))
	) {
	# Otherwise, if the subject is a dually language-family-and-location-based-dialect-to-language
	# lexicon in segmented LC format:

		@lang = (&Norm ("$el[2] $el0[0]", $el1[0]));
		# Identify a list of the language names normalized.

		print OUT "f\t<d>$lang[0]\t<l>$lang[1]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 5)
		&& (@el0 = ($el[0] =~ /^(.+?) dialects?$/i))
		&& (&Lex ($el[3]))
		&& (@el1 = (&TLang ($el[4])))
	) {
	# Otherwise, if the subject is a dually topical dialect-to-language lexicon in standard
	# LC format:

		@lang = (&Norm ($el0[0], $el1[0]));
		# Identify a list of the language names normalized.

		print OUT "f\t<d>$lang[0]\t<l>$lang[1]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 6)
		&& (@el0 = ($el[0] =~ /^(.+?) dialects?$/i))
		&& (&Lex ($el[4]))
		&& (@el1 = (&TLang ($el[5])))
	) {
	# Otherwise, if the subject is a triply topical dialect-to-language lexicon in standard
	# LC format:

		@lang = (&Norm ($el0[0], $el1[0]));
		# Identify a list of the language names normalized.

		print OUT "f\t<d>$lang[0]\t<l>$lang[1]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 4)
		&& (@el0 = ($el[0] =~ /^Creole dialects, (.+?)$/i))
		&& (&Lex ($el[2]))
		&& (@el1 = (&TLang ($el[3])))
	) {
	# Otherwise, if the subject is a language-and-location-based-creole-dialect-to-language
	# dictionary in standard LC format:

		@lang = (&Norm ("$el[1] $el0[0] Creole", $el1[0]));
		# Identify a list of the language names normalized.

		print OUT "f\t<d>$lang[0]\t<l>$lang[1]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 5)
		&& (@el0 = ($el[0] =~ /^Creole dialects, (.+?)$/i))
		&& (&Lex ($el[3]))
		&& (@el1 = (&TLang ($el[4])))
	) {
	# Otherwise, if the subject is a language-and-dual-location-based-creole-dialect-to-language
	# dictionary in standard LC format:

		@lang = (&Norm ("$el[2] $el[1] $el0[0] Creole", $el1[0]));
		# Identify a list of the language names normalized.

		print OUT "f\t<d>$lang[0]\t<l>$lang[1]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 4)
		&& ($el[0] eq 'Creole dialects')
		&& (&Lex ($el[2]))
		&& (@el0 = (&TLang ($el[3])))
	) {
	# Otherwise, if the subject is a location-based-creole-dialect-to-language dictionary
	# in standard LC format:

		@lang = (&Norm ("$el[1] Creole", $el0[0]));
		# Identify a list of the language names normalized.

		print OUT "f\t<d>$lang[0]\t<l>$lang[1]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 4)
		&& (@el0 = (&SLang ($el[0])))
		&& (&Lex ($el[1]))
		&& ($el[2] eq 'Creole dialects')
	) {
	# Otherwise, if the subject is a language-to-location-based-creole-dialect dictionary
	# in standard LC format:

		@lang = (&Norm ($el0[0], "$el[3] Creole"));
		# Identify a list of the language names normalized.

		print OUT "f\t<l>$lang[0]\t<d>$lang[1]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 4)
		&& (@el0 = (&SLang ($el[0])))
		&& (&Lex ($el[1]))
		&& (@el1 = ($el[2] =~ /^Creole dialects, (.+?)$/i))
	) {
	# Otherwise, if the subject is a language-to-language-and-location-based-creole-dialect
	# dictionary in standard LC format:

		@lang = (&Norm ($el0[0], "$el[3] $el1[0] Creole"));
		# Identify a list of the language names normalized.

		print OUT "f\t<l>$lang[0]\t<d>$lang[1]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 4)
		&& (@el0 = (&SLang ($el[0])))
		&& (&Lex ($el[2]))
		&& (@el1 = ($el[3] =~ /^Creole dialects, (.+?)$/i))
	) {
	# Otherwise, if the subject is a topical language-to-language-based-creole-dialect
	# dictionary in standard LC format:

		@lang = (&Norm ($el0[0], "$el1[0] Creole"));
		# Identify a list of the language names normalized.

		print OUT "f\t<l>$lang[0]\t<d>$lang[1]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 3)
		&& (@el0 = (&SLang ($el[0])))
		&& (&Lex ($el[1]))
		&& (@el1 = ($el[2] =~ /^Creole dialects, (.+?)$/i))
	) {
	# Otherwise, if the subject is a language-to-language-based-creole-dialect
	# dictionary in standard LC format:

		@lang = (&Norm ($el0[0], "$el1[0] Creole"));
		# Identify a list of the language names normalized.

		print OUT "f\t<l>$lang[0]\t<d>$lang[1]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 1)
		&& (@el0 = ($el[0] =~ /^(.+?)-(.+) Dictionar(?:y|ies)$/i))
	) {
	# Otherwise, if the subject is a dictionary in prepended hyphenated language-pair
	# format:

		@lang = (&Norm (@el0));
		# Identify a list of the language names normalized.

		print OUT "f\t<l>$lang[0]\t<l>$lang[1]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 1)
		&& (@el0 = ($el[0] =~ /^Dictionaries, (.+?)-(.+)$/i))
	) {
	# Otherwise, if the subject is a dictionary in appended hyphenated language-pair format:

		@lang = (&Norm (@el0));
		# Identify a list of the language names normalized.

		print OUT "f\t<l>$lang[0]\t<l>$lang[1]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 2)
		&& (@el0 = ($el[1] =~ /^Dictionaries, (.+?)-(.+)$/i))
	) {
	# Otherwise, if the subject is a topical dictionary in appended hyphenated
	# language-pair format:

		@lang = (&Norm (@el0));
		# Identify a list of the language names normalized.

		print OUT "f\t<l>$lang[0]\t<l>$lang[1]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 2)
		&& (&Lex ($el[0]))
		&& (@el0 = ($el[1] =~ /^(.+?)-(.+)$/i))
	) {
	# Otherwise, if the subject is a dictionary in segmented hyphenated
	# language-pair format:

		@lang = (&Norm (@el0));
		# Identify a list of the language names normalized.

		print OUT "f\t<l>$lang[0]\t<l>$lang[1]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 3)
		&& (&Lex ($el[1]))
		&& (@el0 = ($el[2] =~ /^(.+?)-(.+)$/i))
	) {
	# Otherwise, if the subject is a topical dictionary in segmented hyphenated
	# language-pair format:

		@lang = (&Norm (@el0));
		# Identify a list of the language names normalized.

		print OUT "f\t<l>$lang[0]\t<l>$lang[1]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 5)
		&& (@el0 = (&SLang ($el[0])))
		&& ($el[1] eq 'Dialects')
		&& (&Lex ($el[3]))
	) {
	# Otherwise, if the subject is a location-based-dialect-to-language dictionary in standard
	# LC format:

		@lang = (&Norm ("$el[2] $el0[0]", $el[4]));
		# Identify a list of the language names normalized.

		print OUT "f\t<d>$lang[0]\t<l>$lang[1]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 6)
		&& (@el0 = (&SLang ($el[0])))
		&& ($el[1] eq 'Dialects')
		&& (&Lex ($el[4]))
	) {
	# Otherwise, if the subject is a dual-location-based-dialect-to-language dictionary in standard
	# LC format:

		@lang = (&Norm ("$el[3] $el[2] $el0[0]", $el[5]));
		# Identify a list of the language names normalized.

		print OUT "f\t<d>$lang[0]\t<l>$lang[1]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 6)
		&& (@el0 = (&SLang ($el[0])))
		&& ($el[2] eq 'Dialects')
		&& (&Lex ($el[4]))
	) {
	# Otherwise, if the subject is a language-and-location-based-dialect-to-language dictionary
	# in standard LC format:

		@lang = (&Norm ("$el[3] $el[1] $el0[0]", $el[5]));
		# Identify a list of the language names normalized.

		print OUT "f\t<d>$lang[0]\t<l>$lang[1]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 7)
		&& (@el0 = (&SLang ($el[0])))
		&& ($el[2] eq 'Dialects')
		&& (&Lex ($el[5]))
		&& (@el1 = (&TLang ($el[6])))
	) {
	# Otherwise, if the subject is a language-and-dual-location-based-dialect-to-language dictionary
	# in standard LC format:

		@lang = (&Norm ("$el[4] $el[3] $el[1] $el0[0]", $el1[0]));
		# Identify a list of the language names normalized.

		print OUT "f\t<d>$lang[0]\t<l>$lang[1]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 7)
		&& (@el0 = (&SLang ($el[0])))
		&& ($el[1] eq 'Dialects')
		&& (&Lex ($el[5]))
		&& (@el1 = (&TLang ($el[6])))
	) {
	# Otherwise, if the subject is a triply-location-based-dialect-to-language dictionary
	# in standard LC format:

		@lang = (&Norm ("$el[4] $el[3] $el[2] $el0[0]", $el1[0]));
		# Identify a list of the language names normalized.

		print OUT "f\t<d>$lang[0]\t<l>$lang[1]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 4)
		&& (@el0 = (&SLang ($el[0])))
		&& ($el[1] eq 'Dialects')
		&& (&Lex ($el[3]))
	) {
	# Otherwise, if the subject is a dialect dictionary with unspecified target language
	# in segmented LC format:

		@lang = (&Norm ("$el[2] $el0[0]"));
		# Identify a list of the language names normalized.

		print OUT "f\t<d>$lang[0]\t-\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 2)
		&& (@el0 = ($el[0] =~ /^(.+?) dialects?$/i))
		&& (&Lex ($el[1]))
	) {
	# Otherwise, if the subject is a dialect dictionary with unspecified target language
	# in standard LC format:

		@lang = (&Norm ($el0[0]));
		# Identify a list of the language names normalized.

		print OUT "f\t<d>$lang[0]\t-\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 3)
		&& (@el0 = ($el[0] =~ /^(.+?) dialects?$/i))
		&& (&Lex ($el[2]))
	) {
	# Otherwise, if the subject is a location-based dialect dictionary with unspecified target
	# language in standard LC format:

		@lang = (&Norm ("$el[1] $el0[0]"));
		# Identify a list of the language names normalized.

		print OUT "f\t<d>$lang[0]\t-\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 4)
		&& (@el0 = ($el[0] =~ /^(.+?) dialects?$/i))
		&& (&Lex ($el[3]))
	) {
	# Otherwise, if the subject is a location-based dialect dictionary with unspecified target
	# language in standard LC format:

		@lang = (&Norm ("$el[2] $el[1] $el0[0]"));
		# Identify a list of the language names normalized.

		print OUT "f\t<d>$lang[0]\t-\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 4)
		&& (@el0 = (&SLang ($el[0])))
		&& (&Lex ($el[2]))
		&& (@el1 = (&TLang ($el[3])))
	) {
	# Otherwise, if the subject is a topical bilingual lexicon in standard LC format:

		@lang = (&Norm ($el0[0], $el1[0]));
		# Identify a list of the language names normalized.

		print OUT "f\t<l>$lang[0]\t<l>$lang[1]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 5)
		&& (@el0 = (&SLang ($el[0])))
		&& (&Lex ($el[3]))
		&& (@el1 = (&TLang ($el[4])))
	) {
	# Otherwise, if the subject is a dually topical bilingual lexicon in standard LC format:

		@lang = (&Norm ($el0[0], $el1[0]));
		# Identify a list of the language names normalized.

		print OUT "f\t<l>$lang[0]\t<l>$lang[1]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 6)
		&& (@el0 = (&SLang ($el[0])))
		&& (&Lex ($el[4]))
		&& (@el1 = (&TLang ($el[5])))
	) {
	# Otherwise, if the subject is a topical bilingual lexicon in standard LC format:

		@lang = (&Norm ($el0[0], $el1[0]));
		# Identify a list of the language names normalized.

		print OUT "f\t<l>$lang[0]\t<l>$lang[1]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 3)
		&& (@el0 = ($el[0] =~ /^(.+?) dialect \(([^()]+)\)$/i))
		&& (&Lex ($el[1]))
		&& (@el1 = (&TLang ($el[2])))
	) {
	# Otherwise, if the subject is a parenthetically defined dialect-to-language lexicon
	# in standard LC format:

		@lang = (&Norm ("$el0[1] $el0[0]", $el1[0]));
		# Identify a list of the language names normalized.

		print OUT "f\t<d>$lang[0]\t<l>$lang[1]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 3)
		&& (@el0 = ($el[0] =~ /^(.+?) languages$/i))
		&& (&Lex ($el[1]))
		&& (@el1 = (&TLang ($el[2])))
	) {
	# Otherwise, if the subject is a family-language lexicon in standard LC format:

		@lang = (&Norm ($el0[0], $el1[0]));
		# Identify a list of the language names normalized.

		print OUT "f\t<f>$lang[0]\t<l>$lang[1]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 4)
		&& (@el0 = ($el[0] =~ /^(.+?) languages$/i))
		&& (&Lex ($el[2]))
		&& (@el1 = (&TLang ($el[3])))
	) {
	# Otherwise, if the subject is a topical family-language lexicon in standard LC format:

		@lang = (&Norm ($el0[0], $el1[0]));
		# Identify a list of the language names normalized.

		print OUT "f\t<f>$lang[0]\t<l>$lang[1]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 5)
		&& (@el0 = ($el[0] =~ /^(.+?) languages$/i))
		&& (&Lex ($el[3]))
		&& (@el1 = (&TLang ($el[4])))
	) {
	# Otherwise, if the subject is a dual-location-based-family-language lexicon in standard
	# LC format:

		@lang = (&Norm ("$el[2] $el[1] $el0[0]", $el1[0]));
		# Identify a list of the language names normalized.

		print OUT "f\t<f>$lang[0]\t<l>$lang[1]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 3)
		&& ($el[1] =~ /^Languages$/i)
		&& (&Lex ($el[2]))
	) {
	# Otherwise, if the subject is a locational lexicon in standard LC format:

		@lang = (&Norm ($el[0]));
		# Identify a list of the language names normalized.

		print OUT "f\t<t>$lang[0]\t-\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 4)
		&& ($el[1] =~ /^Languages$/i)
		&& (&Lex ($el[2]))
		&& (@el1 = (&TLang ($el[3])))
	) {
	# Otherwise, if the subject is a locational-to-language lexicon in standard LC
	# format:

		@lang = (&Norm ($el[0], $el1[0]));
		# Identify a list of the language names normalized.

		print OUT "f\t<t>$lang[0]\t<l>$lang[1]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 5)
		&& ($el[2] =~ /^Languages$/i)
		&& (&Lex ($el[3]))
		&& (@el1 = (&TLang ($el[4])))
	) {
	# Otherwise, if the subject is a qualified-locational-to-language lexicon in standard LC
	# format:

		@lang = (&Norm ("$el[1] $el[0]", $el1[0]));
		# Identify a list of the language names normalized.

		print OUT "f\t<t>$lang[0]\t<l>$lang[1]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 4)
		&& ($el[2] =~ /^Languages$/i)
		&& (&Lex ($el[3]))
	) {
	# Otherwise, if the subject is an ethnolocational lexicon in standard LC format:

		@lang = (&Norm (@el[0, 1]));
		# Identify a list of the language names normalized.

		print OUT "f\t<t>$lang[1] $lang[0]\t-\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 5)
		&& ($el[3] =~ /^Languages$/i)
		&& (&Lex ($el[4]))
	) {
	# Otherwise, if the subject is a topically ethnolocational lexicon in standard
	# LC format:

		@lang = (&Norm (@el[0 .. 2]));
		# Identify a list of the language names normalized.

		print OUT "f\t<t>$lang[2] $lang[1] $lang[0]\t-\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 2)
		&& (@el0 = ($el[0] =~ /^(.+? Sign Language)$/i))
		&& (&Lex ($el[1]))
	) {
	# Otherwise, if the subject is a sign-language lexicon with unspecified target
	# language in standard LC format:

		@lang = (&Norm ($el0[0]));
		# Identify a list of the language names normalized.

		print OUT "f\t<l>$lang[0]\t-\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 3)
		&& (@el0 = ($el[0] =~ /^(.+? Sign Language)$/i))
		&& (&Lex ($el[2]))
	) {
	# Otherwise, if the subject is a topical sign-language lexicon with unspecified target
	# language in standard LC format:

		@lang = (&Norm ($el0[0]));
		# Identify a list of the language names normalized.

		print OUT "f\t<l>$lang[0]\t-\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 3)
		&& (&Lex ($el[1]))
		&& (@el0 = ($el[2] =~ /^(.+? Sign Language)$/i))
	) {
	# Otherwise, if the subject is a topical sign-language lexicon with unspecified source
	# language in standard LC format:

		@lang = (&Norm ($el0[0]));
		# Identify a list of the language names normalized.

		print OUT "f\t-\t<l>$lang[0]\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	elsif (
		(@el == 4)
		&& (@el0 = ($el[0] =~ /^(.+? Sign Language)$/i))
		&& (&Lex ($el[3]))
	) {
	# Otherwise, if the subject is a dually topical sign-language lexicon with unspecified
	# target language in standard LC format:

		@lang = (&Norm ($el0[0]));
		# Identify a list of the language names normalized.

		print OUT "f\t<l>$lang[0]\t-\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

	else {
	# Otherwise, i.e. if the subject doesn’t match any of the specified patterns:

		print OUT "~\t\t\t$seg[0]\t$seg[1]\n";
		# Output the line.

	}

}

close IN;
# Close the input file.

close OUT;
# Close the output file.

sub Lex {
# Return whether the specified string is a lexicon specification.
# Arguments:
#	0: string.

	return ($_[0] =~ /^Dictionaries|Glossaries, vocabularies, etc\.?|Vocabulary$/i);
	# Return whether the string is a lexicon specification.

}

sub Norm {
# Normalize the specified language names.
# Arguments:
#	0+: strings.

	my @ret = @_;
	# Identify a list of the strings.

	my $i;

	foreach $i (0 .. $#ret) {
	# For each of them:

		$ret[$i] =~ s/\\u(.{4})/chr (hex ($1))/eg;
		# Convert all of its Unicode hexadecimal encodings to characters.

		($ret[$i] =~ s/^([^,]+), ([^,]+)$/$2 $1/) unless ($ret[$i] =~ /[()]/);
		# If it is inverted with a comma delimiter and contains no parentheses, normalize
		# its order.

		$ret[$i] = (NFC ($ret[$i]));
		# Apply NFC normalization to it.

	}

	return @ret;
	# Return the converted list.

}

sub SLang {
# Return the language name in the specified string if it is a source-language
# specification, or an empty list if not.
# Arguments:
#	0: string.

	if ($_[0] =~ /^(English|French|Pidgin English)$/) {
	# If the string is a major bare language name:

		return ($1);
		# Return it.

	}

	elsif ($_[0] =~ /^(.+?),? (?:language|\(language\))$/i) {
	# Otherwise, if it is a typical source-language specification:

		return ($1);
		# Return the language name.

	}

	elsif ($_[0] =~ /^(.+?),? (?:language|\(language\)), (.+)$/i) {
	# Otherwise, if it is a comma-delimited-qualified source-language
	# specification:

		return ("$2 $1");
		# Return the qualification-prefixed language name.

	}

	elsif ($_[0] =~ /^(.+?),? language \((.+)\)$/i) {
	# Otherwise, if it is a parenthetically qualified source-language specification:

		return ("$2 $1");
		# Return the qualification-prefixed language name.

	}

	elsif ($_[0] eq 'Interlingua (International Auxiliary Language Association)') {
	# Otherwise, if it is Interlingua:

		return ('Interlingua');
		# Return it, without its disambiguator.

	}

	else {
	# Otherwise:

		return ();
		# Return an empty list.

	}

}

sub TLang {
# Return the language name in the specified string if it is a target-language
# specification, or an empty list if not.
# Arguments:
#	0: string.

	return (($_[0] =~ /literature|dialect/i) ? () : ($_[0] =~ /^(.+?)(?: language| definitions)?$/i));
	# Return the target-language name, or an empty list if the string isn’t
	# a target-language specification.

}
