I wrote a Python code to format the CSS or SCSS code, using the Allman style

How to solve the incorrect indentation of the opening brackets of 3rd level elements?

Table of contents

No heading

No headings in the article.

I wrote a code in Python to format the CSS or SCSS code, using the Allman style.

However, the code failed to indent correctly the opening brackets of the 3rd level elements with spaces. I also cogitate to use the Allman style for any development language with this style support.

I used the regular expressions to locate the number of spaces, the elements, the opening bracket and to replace with the same number of spaces, the elements, a new line and an opening bracket with the same number of spaces. For example:

code = re.sub(("") + r'(.*)' + r'\s(\{)', "" + r"\1" + r"\n\2", code)
code = re.sub(("  ") + r'(.*)' + r'\s(\{)', "  " + r"\1" + r"\n  \2", code)
code = re.sub(("    ") + r'(.*)' + r'\s(\{)', "    " + r"\1" + r"\n    \2", code)

Location:

  • ("") searches and counts the number of spaces;

  • r'(.*)' searches any element regardless of any character, any number, any digit or any special character;

  • r'\s(\{)' searches a space and an opening bracket, just after the element.

Substitution:

  • "" replaces ("") with a number of spaces before an element;

  • r"\1" replaces and inserts r'(.*)';

  • r"\n\2" replaces r'\s(\{)' and inserts a new line, a number of spaces and an opening bracket.

It is important to observe that I use the spaces.

For example, copy, enable whitespace rendering and analyse attentively the whitespaces:

import re

css_code = """
body {
  background-color: #000000;
  color: #ffffff;
  font-family: sans-serif;
  font-size: 16px;
  line-height: 1.5;
  margin: 0;
  padding: 0;

  h1 {
    font-size: 2em;
    line-height: 1.25;
    margin-bottom: 0.5em;

    a {
      color: #ffffff;
      text-decoration: none;
    }
  }

  .element {
    background-color: #ffffff;
    border: 1px solid #000000;
    color: #000000;
    display: block;

    &::before {
      content: "";
      display: block;
    }
  }

  &.element--modifier {
    background-color: #000000;
    color: #ffffff;
  }

  &::before {
    content: "";
    display: block;
  }
}
"""

def format(code):
    code = re.sub(("") + r'(.*)' + r'\s(\{)', "" + r"\1" + r"\n\2", code)
    code = re.sub(("  ") + r'(.*)' + r'\s(\{)', "  " + r"\1" + r"\n  \2", code)
    code = re.sub(("    ") + r'(.*)' + r'\s(\{)', "    " + r"\1" + r"\n    \2", code)
    return print(code)

format(css_code)

While the first two lines containing re.sub worked, but the third failed to indent correctly the opening brackets of 3rd level elements (a and &::before).

See the result and notice the elements a and &::before.

body
{
  background-color: #000000;
  color: #ffffff;
  font-family: sans-serif;
  font-size: 16px;
  line-height: 1.5;
  margin: 0;
  padding: 0;

  h1
  {
    font-size: 2em;
    line-height: 1.25;
    margin-bottom: 0.5em;

    a
  {
      color: #ffffff;
      text-decoration: none;
    }
  }

  .element
  {
    background-color: #ffffff;
    border: 1px solid #000000;
    color: #000000;
    display: block;

    &::before
  {
      content: "";
      display: block;
    }
  }

  &.element--modifier
  {
    background-color: #000000;
    color: #ffffff;
  }

  &::before
  {
    content: "";
    display: block;
  }
}

It should look like:

body
{
  background-color: #000000;
  color: #ffffff;
  font-family: sans-serif;
  font-size: 16px;
  line-height: 1.5;
  margin: 0;
  padding: 0;

  h1
  {
    font-size: 2em;
    line-height: 1.25;
    margin-bottom: 0.5em;

    a
   {
      color: #ffffff;
      text-decoration: none;
   }
  }

  .element
  {
    background-color: #ffffff;
    border: 1px solid #000000;
    color: #000000;
    display: block;

    &::before
   {
      content: "";
      display: block;
   }
  }

  &.element--modifier
  {
    background-color: #000000;
    color: #ffffff;
  }

  &::before
  {
    content: "";
    display: block;
  }
}