Created
June 7, 2021 15:41
-
-
Save Bachstelze/b6e83881f0608816ba444b6394eafa58 to your computer and use it in GitHub Desktop.
Bootstrap migration from 3 to 4 to 5
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import shutil | |
import re | |
# insert you local path into the template_path | |
# the script is migrating the subdirectories and files of the templates into a folder copy | |
template_path = "/weblate/templates/" | |
diff_3_to_4 = { | |
'@media (min-width: $screen-xs-min) and (max-width: $screen-sm-max)': '@media (min-width: map-get($grid-breakpoints, xs)) and (max-width: map-get($grid-breakpoints, xs))', | |
'@media (min-width: $screen-xs) and (max-width: ($screen-md-min - 1))': '@media (min-width: map-get($grid-breakpoints, xs)) and (max-width: map-get($grid-breakpoints, md)-1)', | |
'@media (min-width: $screen-sm-min) and (max-width: $screen-sm-max)': '@include media-breakpoint-only(md)', | |
'@media (min-width: $screen-xs-min)': '@include media-breakpoint-up(xs)', | |
'@media (min-width: $screen-sm)': '@include media-breakpoint-up(md)', | |
'@media (min-width: $screen-sm-min)': '@include media-breakpoint-up(md)', | |
'@media (min-width: $screen-md-min)': '@include media-breakpoint-up(md)', | |
'@media (min-width: $screen-md)': '@include media-breakpoint-up(md)', | |
'@media (min-width: $screen-md-max)': '@include media-breakpoint-up(md)', | |
'@media (min-width: $screen-lg-min)': '@include media-breakpoint-up(lg)', | |
'@media (max-width: ($screen-xs-min - 1))': '@include media-breakpoint-down(xs)', | |
'@media (max-width: $screen-xs-max)': '@include media-breakpoint-down(xs)', | |
'@media (max-width: ($screen-sm-min - 1))': '@include media-breakpoint-down(md)', | |
'@media (max-width: $screen-sm)': '@include media-breakpoint-down(md)', | |
'@media (max-width: $screen-sm-min)': '@include media-breakpoint-down(md)', | |
'@media (max-width: $screen-sm-max)': '@include media-breakpoint-down(lg)', | |
'@media (max-width: $screen-md-max)': '@include media-breakpoint-down(md)', | |
'@media (max-width: $screen-lg-max)': '@include media-breakpoint-down(lg)', | |
'@media (max-width: $screen-xs-min - 1)': '@include media-breakpoint-down(xs)', | |
'@media (max-width: $screen-md-min)': '@include media-breakpoint-down(md)', | |
# bootstrap 2 | |
'@media (max-width: $screen-xxs)': '@include media-breakpoint-down(xs)', | |
'.col-*-offset-*': '.offset-*', | |
'.col-*-push-*': '.order-*-2', | |
'.col-*-pull-*': '.order-*-1', | |
'.panel': '.card', | |
'.panel-heading': '.card-header', | |
'.panel-title': '.card-title', | |
'.panel-body': '.card-body', | |
'.panel-footer': '.card-footer', | |
'.panel-primary': '.card.bg-primary.text-white', | |
'.panel-success': '.card.bg-success.text-white', | |
'.panel-info': '.card.text-white.bg-info', | |
'.panel-warning': '.card.bg-warning', | |
'.panel-danger': '.card.bg-danger.text-white', | |
'.well': '.card.card-body', | |
'.thumbnail': '.card.card-body', | |
'.list-inline > li': '.list-inline-item', | |
'.dropdown-menu > li': '.dropdown-item', | |
'.nav navbar > li': '.nav-item', | |
'.nav navbar > li > a': '.nav-link', | |
'.navbar-right': '.ml-auto', | |
'.navbar-btn': '.nav-item', | |
'.navbar-fixed-top': '.fixed-top', | |
'.nav-stacked': '.flex-column', | |
'.btn-default': '.btn-secondary', | |
'.img-responsive': '.img-fluid', | |
'.img-circle': '.rounded-circle', | |
'.img-rounded': '.rounded', | |
#'.form-horizontal': '', // @note: removed | |
'.radio': '.form-check', | |
'.checkbox': '.form-check', | |
'.input-lg': '.form-control-lg', | |
'.input-sm': '.form-control-sm', | |
'.control-label': '.form-control-label', | |
'.table-condensed': '.table-sm', | |
'.pagination > li': '.page-item', | |
'.pagination > li > a': '.page-link', | |
#'.item': '.carousel-item', // @note: this is too much basic word | |
'.text-help': '.form-control-feedback', | |
'.pull-right': '.float-right', | |
'.pull-left': '.float-left', | |
'.center-block': '.mx-auto', | |
'.hidden-xs': '.d-none', | |
'.hidden-sm': '.d-sm-none', | |
'.hidden-md': '.d-md-none', | |
'.visible-xs': '.d-block.d-sm-none', | |
'.visible-sm': '.d-block.d-md-none', | |
'.visible-md': '.d-block.d-lg-none', | |
'.visible-lg': '.d-block.d-xl-none', | |
'.label': '.badge', | |
'.badge': '.badge.badge-pill', | |
# twig | |
'col-xs-': 'col-', | |
'col-md-': 'col-lg-', | |
'col-sm-': 'col-md-' | |
} | |
diff_4_to_5 = { | |
"no-gutters" : "g-0", | |
"custom-check" : "form-check", | |
"custom-switch" : "form-switch", | |
"custom-select" : "form-select", | |
"custom-file" : "form-control", | |
"form-file" : "form-control", | |
"custom-range" : "form-range", | |
"badge-pill" : "rounded-pill", | |
"close" : "btn-close", | |
"whiteList" : "allowList", | |
"left-" : "start-", | |
"right-" : "end-", | |
"float-left" : "float-start", | |
"float-right" : "float-end", | |
"border-left" : "border-start", | |
"border-right" : "border-end", | |
"rounded-left" : "rounded-start", | |
"rounded-right" : "rounded-end", | |
"ml-" : "ms-", | |
"mr-" : "me-", | |
"pl-" : "ps-", | |
"pr-" : "pe-", | |
"text-left" : "text-start", | |
"text-right" : "text-end", | |
"text-monospace" : "font-monospace", | |
"font-weight-" : "fw-", | |
"font-style-" : "fst-", | |
"rounded-sm" : "rounded-0", | |
"rounded-lg" : "rounded-3", | |
"sr-only" : "visually-hidden", | |
# sass functions | |
"table-row-variant()" : "table-variant()", | |
"lighten()" : "tint-color()", | |
"darken()" : "shade-color()", | |
"scale-color()" : "shift-color()" | |
} | |
dropped = [ | |
"pre-scrollable", | |
"text-justify", | |
"thead-light", | |
"thead-dark", | |
"media ", | |
"color-level()", | |
"theme-color-interval", | |
"bg-gradient-", | |
"form-control-file", | |
"form-control-range", | |
"input-group-append", | |
"input-group-prepend", | |
"form-group", | |
"form-row", | |
"form-inline", | |
"badge-", | |
"btn-block", | |
"card-deck", | |
"card-columns", | |
"card", | |
"flip", | |
"jumbotron", | |
"arrow", # to "popover-arrow" or tooltip-arrow | |
"text-hide", | |
"embed-responsive-item" | |
] | |
def get_html_css_file(template_path): | |
for filename in os.listdir(template_path): | |
f = os.path.join(template_path, filename) | |
# checking if it is a file | |
if os.path.isfile(f): | |
if f.endswith(".html") or f.endswith(".css"): | |
yield(f) | |
else: | |
# we have an other directory like at the beginning | |
for recursive_filename in get_html_css_file(f): | |
yield recursive_filename | |
drops = 0 | |
changes = 0 | |
def migrate_file(file_path): | |
global drops | |
global changes | |
short_path = file_path.split("/new_templates/")[1] | |
old_file = open(file_path) | |
old_content = old_file.read() | |
#new_file = open(file_path, "wt") | |
#new_file_path = file_path.replace("/old_templates/", "/templates/") | |
for diff_key in diff_3_to_4.keys(): | |
# we first migrate from version 3 to 4 | |
old_content = old_content.replace(diff_key, diff_3_to_4[diff_key]) | |
if diff_key in old_content: | |
changes+=1 | |
for diff_key in diff_4_to_5.keys(): | |
old_content = old_content.replace(diff_key, diff_4_to_5[diff_key]) | |
if diff_key in old_content: | |
changes+=1 | |
for drop in dropped: | |
for match in re.finditer(drop, old_content): | |
print("\ndropped '" + drop + "' in " + short_path + " with the following context:") | |
print(old_content[int(match.start()-25) : int(match.end()+25)]) | |
drops+=1 | |
# handle special case "by" to "x" with a number ratio | |
for match in re.finditer("by", old_content): | |
pre_number = old_content[match.start()-1:match.start()] | |
sur_number = old_content[match.end():match.end()+1] | |
if pre_number.isnumeric() and sur_number.isnumeric(): | |
old_content = "".join(old_content[:match.start()],"x",old_content[match.end():]) | |
changes += 1 | |
old_file.close() | |
write_file = open(file_path, "w") | |
write_file.write(old_content) | |
write_file.close() | |
def process_directory(dir_path, dir_name): | |
old_template_path = dir_path[:] | |
new_template_path = dir_path.replace("/"+dir_name+"/", "/new_"+dir_name+"/") | |
if os.path.exists(new_template_path): | |
shutil.rmtree(new_template_path) | |
shutil.copytree(old_template_path, new_template_path) | |
for filename in get_html_css_file(new_template_path): | |
migrate_file(filename) | |
#print(filename) | |
print("created migrated files in") | |
print(new_template_path) | |
process_directory(template_path, "templates") | |
print("changes: " + str(changes)) | |
print("drops: " + str(drops)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment