Introduction
In order to solve the layout problem of google code prettify in blogspot, I try to write a simple but useful tool for source code formating. So far, this program is only fully support python. For other programming languages, you can still get a little benefit from this tool.
This program will replace tab or white space with fixed size tab character. Besides, the special character '<' and '>' will be replaced by html code.
Code
UI
#! /usr/bin/python
##################################################################
# Project: Python Code Formatter
# Filename: ui_codeformatter.py
# Description: User interface for source code formatting
# Date: 2009.05.24
# Programmer: Lin Xin Yu
# E-mail: nxforce@yahoo.com
# Website:http://importcode.blogspot.com
##################################################################
#================= import modules ================================
from PyQt4 import QtCore, QtGui
#================= Ui_CodeFormatterClass Start ===================
class Ui_CodeFormatterClass(object):
def setupUi(self, CodeFormatterClass):
CodeFormatterClass.setObjectName("CodeFormatterClass")
CodeFormatterClass.resize(800, 630)
# plain text editor
self.textEdit_raw = QtGui.QTextEdit(CodeFormatterClass)
self.textEdit_raw.setGeometry(QtCore.QRect(10, 10, 780, 285))
self.textEdit_raw.setObjectName("textEdit_raw")
self.textEdit_raw.setTabStopWidth(20)
# formatted text editor
self.textEdit_fmt = QtGui.QTextEdit(CodeFormatterClass)
self.textEdit_fmt.setGeometry(QtCore.QRect(10, 305, 780, 285))
self.textEdit_fmt.setObjectName("textEdit_raw")
self.textEdit_fmt.setTabStopWidth(20)
# language type
self.comboBox_langMode = QtGui.QComboBox(CodeFormatterClass)
self.comboBox_langMode.setGeometry(QtCore.QRect(10, 600, 120, 25))
self.comboBox_langMode.setObjectName("comboBox_langMode")
self.comboBox_langMode.insertItem(0, 'Python')
self.comboBox_langMode.insertItem(1, 'Other')
# Tab Width label
self.label_tabWidth = QtGui.QLabel(CodeFormatterClass)
self.label_tabWidth.setGeometry(QtCore.QRect(140, 600, 70, 25))
self.label_tabWidth.setObjectName("label_tabWidt")
# Tab Width lineEdit
self.lineEdit_tabWidth = QtGui.QLineEdit(CodeFormatterClass)
self.lineEdit_tabWidth.setGeometry(QtCore.QRect(210, 600, 30, 25))
self.lineEdit_tabWidth.setObjectName("lineEdit_tabWidth")
self.lineEdit_tabWidth.setText('4')
# 'Convert' button
self.pushButton_convert = QtGui.QPushButton(CodeFormatterClass)
self.pushButton_convert.setGeometry(QtCore.QRect(250, 600, 90, 25))
self.pushButton_convert.setObjectName("pushButton_convert")
# 'clear all' button
self.pushButton_clear = QtGui.QPushButton(CodeFormatterClass)
self.pushButton_clear.setGeometry(QtCore.QRect(350, 600, 90, 25))
self.pushButton_clear.setObjectName("pushButton_clear")
# 'Open' button
self.pushButton_open = QtGui.QPushButton(CodeFormatterClass)
self.pushButton_open.setGeometry(QtCore.QRect(450, 600, 90, 25))
self.pushButton_open.setObjectName("pushButton_open")
# 'SaveAs' button
self.pushButton_saveAs = QtGui.QPushButton(CodeFormatterClass)
self.pushButton_saveAs.setGeometry(QtCore.QRect(550, 600, 90, 25))
self.pushButton_saveAs.setObjectName("pushButton_saveAs")
# 'Copy to clipboard' button
self.pushButton_clipboard = QtGui.QPushButton(CodeFormatterClass)
self.pushButton_clipboard.setGeometry(QtCore.QRect(650, 600, 140, 25))
self.pushButton_clipboard.setObjectName("pushButton_clipboard")
# Open fileDialog
self.fileDialog_open = QtGui.QFileDialog(CodeFormatterClass)
# SaveAs fileDialog
self.fileDialog_saveAs = QtGui.QFileDialog(CodeFormatterClass)
self.retranslateUi(CodeFormatterClass)
QtCore.QObject.connect(self.pushButton_convert, QtCore.SIGNAL("clicked()"), CodeFormatterClass.onConvertClicked)
QtCore.QObject.connect(self.pushButton_clear, QtCore.SIGNAL("clicked()"), CodeFormatterClass.onClearAllClicked)
QtCore.QObject.connect(self.pushButton_open,QtCore.SIGNAL("clicked()"),CodeFormatterClass.onOpenClicked)
QtCore.QObject.connect(self.pushButton_saveAs, QtCore.SIGNAL("clicked()"), CodeFormatterClass.onSaveAsClicked)
QtCore.QObject.connect(self.pushButton_clipboard, QtCore.SIGNAL("clicked()"), CodeFormatterClass.onCpClipboardClicked)
QtCore.QObject.connect(self.lineEdit_tabWidth,QtCore.SIGNAL("returnPressed()"),CodeFormatterClass.onTabWidthSeted)
QtCore.QMetaObject.connectSlotsByName(CodeFormatterClass)
def retranslateUi(self, CodeFormatterClass):
CodeFormatterClass.setWindowTitle(QtGui.QApplication.translate("CodeFormatterClass", "Code Formatter", None, QtGui.QApplication.UnicodeUTF8))
self.pushButton_convert.setText(QtGui.QApplication.translate("CodeFormatterClass", "Convert", None, QtGui.QApplication.UnicodeUTF8))
self.pushButton_clipboard.setText(QtGui.QApplication.translate("CodeFormatterClass", "Copy to Clipboard", None, QtGui.QApplication.UnicodeUTF8))
self.pushButton_saveAs.setText(QtGui.QApplication.translate("CodeFormatterClass", "Save As...", None, QtGui.QApplication.UnicodeUTF8))
self.pushButton_clear.setText(QtGui.QApplication.translate("CodeFormatterClass", "Clear All", None, QtGui.QApplication.UnicodeUTF8))
self.label_tabWidth.setText(QtGui.QApplication.translate("CodeFormatterClass", "Tab width:", None, QtGui.QApplication.UnicodeUTF8))
self.pushButton_open.setText(QtGui.QApplication.translate("CodeFormatterClass", "Open...", None, QtGui.QApplication.UnicodeUTF8))
#================= Ui_CodeFormatterClass Start ===================
Main Program
#! /usr/bin/python
################################################################
# Project: Python Code Formatter
# Filename: CodeFormatter.py
# Description: An useful tool for source code formatting
# Date: 2009.05.24
# Programmer: Lin Xin Yu
# E-mail: nxforce@yahoo.com
# Website:http://importcode.blogspot.com
################################################################
#================= import modules ==============================
import re
import sys
import ui_codeformatter
from PyQt4 import QtCore, QtGui
#================= CodeFormatter Class Start ===================
class CodeFormatter(QtGui.QMainWindow):
def __init__(self, parent = None):
QtGui.QMainWindow.__init__(self, parent)
self.ui = ui_codeformatter.Ui_CodeFormatterClass()
self.ui.setupUi(self)
self.ui.textEdit_fmt.setEnabled(False)
# default tab width is 4 for all language
self.tabWidth = 4
# init raw text
self.rawText = ''
# init formated text
self.fmtText = ''
# other code phrasing
def otherCodePhrasing(self):
# add the start css tag of google code prettify
self.fmtText = '<code class="prettyprint">'
for line in self.rawText:
self.fmtText += line.replace('<', '<').replace('>','>') + '\n'
# add the end css tag of google code prettify
self.fmtText += '</code>'
self.ui.textEdit_fmt.setPlainText(self.fmtText)
# python source code phrasing
def pythonCodePhrasing(self):
numOfTabs = 0
numOfSpaces = 0
# list for recording the white spaces
list = [0]
# add the start css tag of google code prettify
self.fmtText = '<code class="prettyprint">'
for line in self.rawText:
numOfChrs = 0
nSpaces = 0
matchAnySpace = re.match('[\s]+', line)
if(matchAnySpace):
nSpaces = matchAnySpace.group().count('\t') * self.tabWidth
nSpaces += matchAnySpace.group().count(' ')
numOfChrs += len(matchAnySpace.group())
tmpLine = line[numOfChrs:].replace('<', '<').replace('>','>')
# if this line is newline only
if(tmpLine == ''):
self.fmtText += ' ' * (numOfTabs * self.tabWidth) + '\n'
continue
### reserved function for worst case ###
# if this line is commecnt
#matchComment = re.match('^#', tmpLine)
#if(matchComment):
# self.fmtText += ' ' * (numOfTabs * self.tabWidth) + tmpLine + '\n'
# continue
# update tab character count by verifying the white spaces
if(nSpaces > numOfSpaces):
list.append(nSpaces)
numOfTabs += 1
elif(nSpaces < numOfSpaces):
while list[len(list)-1] != nSpaces:
list.pop()
numOfTabs -= 1
numOfSpaces = nSpaces
# when the line is a new class or function, reset all counts
if(numOfChrs == 0):
numOfSpaces = numOfTabs = 0
self.fmtText += ' ' * (numOfTabs * self.tabWidth) + tmpLine + '\n'
# add the end css tag of google code prettify
self.fmtText += '</code>'
self.ui.textEdit_fmt.setPlainText(self.fmtText)
# SLOT for convert button
def onConvertClicked(self):
self.ui.textEdit_fmt.setEnabled(True)
self.rawText = str(self.ui.textEdit_raw.toPlainText()).split('\n')
if(self.ui.comboBox_langMode.currentIndex() == 0):
self.pythonCodePhrasing()
return True
if(self.ui.comboBox_langMode.currentIndex() == 1):
self.otherCodePhrasing()
return True
def onClearAllClicked(self):
self.ui.textEdit_raw.setText('')
self.ui.textEdit_fmt.setText('')
self.ui.textEdit_raw.setFocus()
def onCpClipboardClicked(self):
self.ui.textEdit_fmt.selectAll()
self.ui.textEdit_fmt.copy()
mimeData = QtGui.QApplication.clipboard().mimeData();
def onOpenClicked(self):
filename = self.ui.fileDialog_open.getOpenFileName(self, 'Open file', QtCore.QDir.homePath()+'/Desktop')
if(filename):
fileIn = open(filename, 'r')
rawText = fileIn.read()
fileIn.close()
self.ui.textEdit_raw.setPlainText(rawText)
def onSaveAsClicked(self):
filename = self.ui.fileDialog_saveAs.getSaveFileName(self, 'Save file', QtCore.QDir.homePath()+'/Desktop')
if(filename):
fileOut = open(filename, 'w')
fileOut.write(self.fmtText)
fileOut.close()
def onTabWidthSeted(self):
self.tabWidth = int(self.ui.lineEdit_tabWidth.text())
#================= CodeFormatter Class End ===================
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
codeFormatter = CodeFormatter()
codeFormatter.show()
sys.exit(app.exec_())
Screenshot
Please make sure the tab width is correct before converting.
0 意見:
Post a Comment