As [breadcrumb menùs](https://en.wikipedia.org/wiki/Breadcrumb_%28navigation%29) are quite popular today, I won't digress much on explaining them, leaving the wiki link to do all the dirty work in my place.

What might not be so trivial is instead to get a decent breadcrumb from your current url. For this kata, your purpose is to create a function that takes a url, strips the first part (labelling it always `HOME`) and then builds it making each element but the last a `` element linking to the relevant path; last has to be a `` element getting the `active` `class`.

All elements need to be turned to uppercase and separated by a separator, given as the second parameter of the function; the last element can terminate in some common extension like `.html`, `.htm`, `.php` or `.asp`; if the name of the last element is `index`.something, you treat it as if it wasn't there, sending users automatically to the upper level folder.

A few examples can be more helpful than thousands of words of explanation, so here you have them:
```python
generate_bc("mysite.com/pictures/holidays.html", " : ") == 'HOME : PICTURES : HOLIDAYS'
generate_bc("www.codewars.com/users/GiacomoSorbi", " / ") == 'HOME / USERS / GIACOMOSORBI'
generate_bc("www.microsoft.com/docs/index.htm", " * ") == 'HOME * DOCS'
```
Seems easy enough?

Well, probably not so much, but we have one last extra rule: if one element (other than the root/home) is longer than 30 characters, you have to shorten it, acronymizing it (i.e.: taking just the initials of every word); url will be always given in the format `this-is-an-element-of-the-url` and you should ignore words in this array while acronymizing: `["the","of","in","from","by","with","and", "or", "for", "to", "at", "a"]`; a url composed of more words separated by `-` and equal or less than 30 characters long needs to be just uppercased with hyphens replaced by spaces.

Ignore anchors (`www.url.com#lameAnchorExample`) and parameters (`www.url.com?codewars=rocks&pippi=rocksToo`) when present.

Examples:
```python
generate_bc("mysite.com/very-long-url-to-make-a-silly-yet-meaningful-example/example.htm", " > ") == 'HOME > VLUMSYME > EXAMPLE'
generate_bc("www.very-long-site_name-to-make-a-silly-yet-meaningful-example.com/users/giacomo-sorbi", " + ") == 'HOME + USERS + GIACOMO SORBI'
```

You will always be provided **valid url** to webpages **in common formats**, so you probably shouldn't bother validating them.

If you like to test yourself with actual work/interview related kata, please also consider this one about building [a string filter for Angular.js](http://www.codewars.com/kata/number-shortening-filter).

_Special thanks to [the colleague](http://www.codewars.com/users/jury89) that, seeing my code and commenting that I worked on that as if it was I was on CodeWars, made me realize that it could be indeed a good idea for a kata_ :)

Source: codewars | Difficulty: MEDIUM_HARD

Starter code: def generate_bc(url, separator):
	

Solutions:
from re import sub
ignoreList = ['THE', 'OF', 'IN', 'FROM', 'BY', 'WITH', 'AND', 'OR', 'FOR', 'TO', 'AT', 'A']

def generate_bc(url, separator):
	url = sub('https?://', '', url.strip('/'))
	url = sub('/index\\..+$', '', url)
	url = url.split('/')
	url[-1] = sub('[\\.#\\?].*', '', url[-1])
	menu = ['HOME']
	for item in url[1:]:
		item = sub('-', ' ', item.upper())
		if len(item) > 30:
			item = ''.join([w[0] for w in item.split() if w not in ignoreList])
		menu.append(item)
	path = ['/']
	for i in range(len(url) - 1):
		path.append(path[i] + url[i + 1] + '/')
	html = []
	for i in range(len(url) - 1):
		html.append('<a href="' + path[i] + '">' + menu[i] + '</a>')
	html.append('<span class="active">' + menu[-1] + '</span>')
	return separator.join(html)


import re
INVALID_WORDS = set('the of in from by with and or for to at a'.upper().split())

def formater(part):
	part = part.replace('-', ' ').upper()
	if len(part) > 30:
		part = ''.join((w[0] for w in part.split() if w not in INVALID_WORDS))
	return part

def generate_bc(url, separator):
	(ans, urlLst) = ([], re.sub('(/index\\..*)|(\\?.*)|(#.*)|(https?://)|/$', '', url).split('/'))
	lenLst = len(urlLst)
	for i in range(lenLst):
		if i == 0 and lenLst > 1:
			ans.append('<a href="/">HOME</a>')
		elif i != lenLst - 1 and len(urlLst) > 2:
			ans.append('<a href="/{}/">{}</a>'.format('/'.join(urlLst[1:i + 1]), formater(urlLst[i])))
		elif i == lenLst - 1:
			ans.append('<span class="active">{}</span>'.format('HOME' if i == 0 else formater(re.sub('\\..*', '', urlLst[-1]))))
	return separator.join(ans)


from re import sub, search

def generate_bc(url, separator):
	url = sub('https?:\\/\\/', '', sub('\\/index\\..+$', '', sub('[?#].+$', '', url)))
	base = search('.+?\\/', url).group(0) if search('.+?\\/', url) else url
	paths = url[len(base):].split('/')
	path = '/'
	breadcrumbedPath = ['<a href="/">HOME</a>']
	if url == base:
		return '<span class="active">HOME</span>'
	classes = None
	last = False
	for i in xrange(len(paths)):
		if i == len(paths) - 1:
			classes = 'active'
			last = True
		path += paths[i] + '/'
		bcName = paths[i]
		if len(paths[i]) > 30:
			bcName = acronymize(bcName)
		bcName = parseName(bcName)
		breadcrumbedPath += [createHTMLPath(bcName, path, classes, last)]
	return separator.join(breadcrumbedPath)
createHTMLPath = lambda bcName, url, classes, last: ''.join(['<a href="', url, '"', '' if classes == None else ''.join([' class="', classes, '"']), '>', bcName, '</a>']) if not last else ''.join(['<span', '' if classes == None else ''.join([' class="', classes, '"']), '>', bcName, '</span>'])
parseName = lambda bcName: sub('\\.\\w+', '', ' '.join(bcName.split('-'))).upper()
acronymize = lambda bcName: ''.join([x[0] for x in bcName.lower().split('-') if x not in ['the', 'of', 'in', 'from', 'by', 'with', 'and', 'or', 'for', 'to', 'at', 'a']])


def generate_bc(url, separator):
	(a, span) = ('<a href="%s/">%s</a>', '<span class="active">%s</span>')
	restricted = set('THE OF IN FROM BY WITH AND OR FOR TO AT A'.split())

	def bc(menu):
		menu = menu.upper().replace('-', ' ')
		if len(menu) > 30:
			menu = ''.join((w[0] for w in menu.split() if w not in restricted))
		return menu or 'HOME'
	url = ''.join(url.strip('/').rpartition('//')[2].partition('/')[1:]).rsplit('?', 1)[0].rsplit('#', 1)[0].rsplit('.', 1)[0].rsplit('/index')[0].split('/')
	return separator.join([a % ('/'.join(url[:i]), bc(m)) for (i, m) in enumerate(url[:-1], 1)] + [span % bc(url[-1])])


IGNORE = 'THE OF IN FROM BY WITH AND OR FOR TO AT A'.split()

def generate_bc(url, separator):
	if url.startswith('http'):
		url = url.split('//')[1]
	crumbs = url.split('/')
	links = crumbs[1:]
	crumbs[0] = 'HOME'
	for (i, crumb) in enumerate(crumbs):
		crumb = crumb.split('.')[0].split('?')[0].split('#')[0].replace('-', ' ').upper()
		if len(crumb) > 30:
			crumb = [c for c in crumb.split() if c not in IGNORE]
			crumb = ''.join(map(lambda c: c[0], crumb))
		crumbs[i] = crumb
	if crumbs[-1] in ('', 'INDEX'):
		crumbs.pop()
	output = []
	for (i, crumb) in enumerate(crumbs[:-1]):
		element = '<a href="/%s/">%s</a>' % ('/'.join(links[:i]), crumb)
		output += [element.replace('//', '/')]
	output += ['<span class="active">%s</span>' % crumbs[-1]]
	return separator.join(output)


import re

def base_name(fullname):
	return re.sub('[.].*$', '', fullname)
ignore_words = ['the', 'of', 'in', 'from', 'by', 'with', 'and', 'or', 'for', 'to', 'at', 'a']

def short_name(name):
	if len(name) <= 30:
		return re.sub('[-]', ' ', name)
	else:
		return ''.join([a[0] for a in name.split('-') if a not in ignore_words])

def generate_bc(url, separator):
	url_striped = re.sub('[#?].*', '', url)
	url_striped = re.sub('(http|https)://', '', url_striped)
	url_striped = re.sub('/$', '', url_striped)
	url_splited = url_striped.split('/')
	if base_name(url_splited[-1]) == 'index':
		del url_splited[-1]
	if len(url_splited) <= 1:
		return '<span class="active">HOME</span>'
	path = '/'
	res = list()
	res.append('<a href="/">HOME</a>')
	for e in url_splited[1:-1]:
		path += e + '/'
		res.append('<a href="%s">%s</a>' % (path, short_name(e).upper()))
	res.append('<span class="active">%s</span>' % short_name(base_name(url_splited[-1])).upper())
	return separator.join(res)


from typing import List, Tuple
from urllib.parse import urlparse
import re

def generate_bc(url: str, separator: str) -> str:
	home_url = '<a href="/">HOME</a>'
	(path_components, last_path) = split_url(url)
	if last_path.startswith('index.'):
		last_path = ''
	last_path = re.sub('(.html|.htm|.php|.asp)$', '', last_path)
	if not path_components:
		if not last_path:
			return '<span class="active">HOME</span>'
	elif not last_path:
		last_path = path_components.pop()
	return separator.join([home_url, *generate_bc_middle(path_components), generate_bc_last(last_path)])

def generate_bc_middle(path_components: List[str]) -> List[str]:
	cumulative_path = ''
	result: List[str] = []
	for path in path_components:
		cumulative_path = cumulative_path + '/' + path if cumulative_path else path
		bc = path.replace('-', ' ').upper() if len(path) <= 30 else acronymyze(path)
		result.append(f'<a href="/{cumulative_path}/">{bc}</a>')
	return result

def acronymyze(long_word: str) -> str:
	ignore_words = ['the', 'of', 'in', 'from', 'by', 'with', 'and', 'or', 'for', 'to', 'at', 'a']
	return ''.join((word[0].upper() for word in long_word.split('-') if word not in ignore_words))

def generate_bc_last(last_path: str) -> str:
	if len(last_path) > 30:
		bc = acronymyze(last_path)
	else:
		bc = last_path.replace('-', ' ').upper()
	return f'<span class="active">{bc}</span>'

def split_url(url: str) -> Tuple[List[str], str]:
	parse_result = urlparse(url)
	if not parse_result.scheme and (not url.startswith('//')):
		parse_result = urlparse('//' + url)
	if not parse_result.path:
		path_components = []
		last_path = ''
	elif parse_result.path.startswith('/'):
		path_components = [component for component in parse_result.path.split('/')]
		path_components.pop(0)
		last_path = path_components.pop()
	else:
		raise Exception('Invalid url')
	return (path_components, last_path)


def generate_bc(url, separator):
	print(url)
	print(separator)
	url = str(url.replace('https://', ''))
	url = str(url.replace('http://', ''))
	try:
		questionIndex = url.index('?')
	except ValueError:
		questionIndex = -1
	try:
		hashIndex = url.index('#')
	except ValueError:
		hashIndex = -1
	if questionIndex != -1:
		url = str(url[:questionIndex])
	if hashIndex != -1:
		url = str(url[:hashIndex])
	names = list(filter(None, url.split('/')))
	html = ''
	commonExtensions = ['.html', '.htm', '.php', '.asp']
	ignoreWords = ['the', 'of', 'in', 'from', 'by', 'with', 'and', 'or', 'for', 'to', 'at', 'a']
	pastLinks = []
	for (index, name) in enumerate(names):
		isFirstIndex = index == 0
		isLastIndex = index == len(names) - 1
		if not isLastIndex and 'index' in names[index + 1]:
			isLastIndex = True
		if isLastIndex:
			for commonExtension in commonExtensions:
				name = name.replace(commonExtension, '')
		tagValue = ''
		if isFirstIndex:
			tagValue = 'HOME'
		elif len(name) > 30:
			tagValue = ''.join((str.upper(a[0:1]) for a in name.split('-') if a not in ignoreWords))
		elif '-' in name:
			tagValue = name.upper().replace('-', ' ')
		else:
			tagValue = name.upper()
		html += '<{element}'.format(element='span' if isLastIndex else 'a')
		if isLastIndex:
			html += ' class="active"'
		else:
			currentLink = name.strip().lower()
			hrefValue = ''
			if isFirstIndex:
				hrefValue = '/'
			elif len(pastLinks) > 0:
				pastLinks.append(currentLink)
				hrefValue = '/{link}/'.format(link='/'.join(pastLinks))
			else:
				pastLinks.append(currentLink)
				hrefValue = '/{link}/'.format(link=currentLink)
			html += ' href="{hrefValue}"'.format(hrefValue=hrefValue)
		html += '>'
		html += tagValue
		html += '</{attribute}>'.format(attribute='span' if isLastIndex else 'a')
		if not isLastIndex:
			html += separator
		if isLastIndex:
			break
	return html


import re

def generate_bc(url, separator):

	def formater(name):
		if len(name) > 30:
			stoplist = ['the', 'of', 'in', 'from', 'by', 'with', 'and', 'or', 'for', 'to', 'at', 'a']
			return ''.join([ch[0].upper() for ch in name.split('-') if ch not in stoplist])
		else:
			return name.replace('-', ' ').upper()
	result = []
	url = re.sub('^https?:\\/\\/', '', url)
	url = re.sub('\\.[^\\/]*$', '', url)
	url = re.sub('(?:\\#|\\?).*$', '', url)
	url = re.sub('index$', '', url)
	url = url.rstrip('/')
	crumbs = url.split('/')
	for (i, crumb) in enumerate(crumbs):
		if i == 0:
			result.append('<a href="/">HOME</a>' if len(crumbs) > 1 else '<span class="active">HOME</span>')
		elif i == len(crumbs) - 1:
			result.append('<span class="active">{}</span>'.format(formater(crumb)))
		else:
			result.append('<a href="/{}/">{}</a>'.format('/'.join(crumbs[1:1 + i]), formater(crumb)))
	return separator.join(result)