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_ :)
from typing import List, Tuple
from urllib.parse import urlparse
import re


def generate_bc(url: str, separator: str) -> str:
    # print(f'url = {repr(url)}')
    # print(f'separator = {repr(separator)}')

    home_url = '<a href="/">HOME</a>'  # type: str

    (path_components, last_path) = split_url(url)
    if last_path.startswith("index."):
        last_path = ''

    last_path = re.sub(r"(.html|.htm|.php|.asp)$", "", last_path)

    if not path_components:  # empty
        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]:
    # return ['<a href="/important/">IMPORTANT</a>', '<a href="/important/confidential/">CONFIDENTIAL</a>']
    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:
    """ Shorten it, acronymizing it
    (i.e.: taking just the initials of every word) """
    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]:
    """ Returns a tuple by splitting the given url
    url = 'mysite.com/years/pictures/holidays.html'
    returns a tuple ([years,pictures], 'holidays.html')
    """

    # Example url = 'https://mysite.com/years/pictures/holidays.html'
    parse_result = urlparse(url)
    # ParseResult(scheme='https', netloc='mysite.com', path='/years/pictures/holidays.html',
    #               params='', query='', fragment='')

    # urlparse recognizes a netloc only if it is properly introduced by ‘//’.
    # Otherwise the input is presumed to be a relative URL and thus to start
    # with a path component.

    # Redo urlparse to make sure that parse_result.path has only filepath and not hostpath part
    if not parse_result.scheme and not url.startswith('//'):
        parse_result = urlparse('//' + url)

    if not parse_result.path:  # empty path
        path_components = []
        last_path = ''
    elif parse_result.path.startswith('/'):
        path_components = [
            component for component in parse_result.path.split("/")
        ]
        path_components.pop(0)  # Remove ''
        # ['', 'years', 'pictures', 'holidays.html']
        last_path = path_components.pop()  # type: str
    else:
        raise Exception("Invalid url")

    # (['years', 'pictures'], 'holidays.html')
    return (path_components, last_path)

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


def generate_bc(url: str, separator: str) -> str:
    # print(f'url = {repr(url)}')
    # print(f'separator = {repr(separator)}')

    home_url = '<a href="/">HOME</a>'  # type: str

    (path_components, last_path) = split_url(url)
    if last_path.startswith("index."):
        last_path = ''

    last_path = re.sub(r"(.html|.htm|.php|.asp)$", "", last_path)

    if not path_components:  # empty
        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]:
    # return ['<a href="/important/">IMPORTANT</a>', '<a href="/important/confidential/">CONFIDENTIAL</a>']
    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:
    """ Shorten it, acronymizing it
    (i.e.: taking just the initials of every word) """
    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]:
    """ Returns a tuple by splitting the given url
    url = 'mysite.com/years/pictures/holidays.html'
    returns a tuple ([years,pictures], 'holidays.html')
    """

    # Example url = 'https://mysite.com/years/pictures/holidays.html'
    parse_result = urlparse(url)
    # ParseResult(scheme='https', netloc='mysite.com', path='/years/pictures/holidays.html',
    #               params='', query='', fragment='')

    # urlparse recognizes a netloc only if it is properly introduced by ‘//’.
    # Otherwise the input is presumed to be a relative URL and thus to start
    # with a path component.

    # Redo urlparse to make sure that parse_result.path has only filepath and not hostpath part
    if not parse_result.scheme and not url.startswith('//'):
        parse_result = urlparse('//' + url)

    if not parse_result.path:  # empty path
        path_components = []
        last_path = ''
    elif parse_result.path.startswith('/'):
        path_components = [
            component for component in parse_result.path.split("/")
        ]
        path_components.pop(0)  # Remove ''
        # ['', 'years', 'pictures', 'holidays.html']
        last_path = path_components.pop()  # type: str
    else:
        raise Exception("Invalid url")

    # (['years', 'pictures'], 'holidays.html')
    return (path_components, last_path)
