|
|
|
#! /usr/bin/env python
|
|
|
|
|
|
|
|
"""This file is part of the KDE project
|
|
|
|
Copyright (C) 2006 Alfredo Beaumont Sainz <alfredo.beaumont@gmail.com>
|
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU Library General Public
|
|
|
|
License as published by the Free Software Foundation; either
|
|
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
Library General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
|
Boston, MA 02110-1301, USA.
|
|
|
|
"""
|
|
|
|
import codecs
|
|
|
|
import sys
|
|
|
|
import string
|
|
|
|
import time
|
|
|
|
import os
|
|
|
|
|
|
|
|
###
|
|
|
|
# If operator element's attributes change in the future, just update this list
|
|
|
|
# and the attr dictionary below
|
|
|
|
attr_list = [
|
|
|
|
'lspace',
|
|
|
|
'rspace',
|
|
|
|
'maxsize',
|
|
|
|
'minsize',
|
|
|
|
'fence',
|
|
|
|
'separator',
|
|
|
|
'stretchy',
|
|
|
|
'symmetric',
|
|
|
|
'largeop',
|
|
|
|
'movablelimits',
|
|
|
|
'accent'
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
def write_header( f ):
|
|
|
|
print('''//
|
|
|
|
// Created: ''' + time.ctime(time.time()) + '''
|
|
|
|
// by: ''' + os.path.basename( sys.argv[0] ) + '''
|
|
|
|
// from: ''' + os.path.basename( sys.argv[1] ) + '''
|
|
|
|
//
|
|
|
|
// WARNING! All changes made in this file will be lost!
|
|
|
|
|
|
|
|
/* This file is part of the KDE project
|
|
|
|
Copyright (C) 2006 Alfredo Beaumont Sainz <alfredo.beaumont@gmail.com>
|
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU Library General Public
|
|
|
|
License as published by the Free Software Foundation; either
|
|
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
Library General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
|
* Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
''', file=f)
|
|
|
|
|
|
|
|
def write_h( f ):
|
|
|
|
print('''
|
|
|
|
#ifndef OPERATORDICTIONARY_H
|
|
|
|
#define OPERATORDICTIONARY_H
|
|
|
|
|
|
|
|
#include "kformuladefs.h"
|
|
|
|
|
|
|
|
KFORMULA_NAMESPACE_BEGIN
|
|
|
|
|
|
|
|
struct DictionaryKey
|
|
|
|
{
|
|
|
|
int operator==( const DictionaryKey& right ) const {
|
|
|
|
if ( qstrcmp( name, right.name ) || qstrcmp( form, right.form ) ) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
const char* name;
|
|
|
|
const char* form;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct OperatorDictionary {
|
|
|
|
static int size();
|
|
|
|
int operator<( const DictionaryKey& right ) const {
|
|
|
|
int equal = qstrcmp( key.name, right.name );
|
|
|
|
if ( equal != 0 ) {
|
|
|
|
return equal < 0;
|
|
|
|
}
|
|
|
|
return qstrcmp( key.form, right.form ) < 0;
|
|
|
|
}
|
|
|
|
const DictionaryKey key;
|
|
|
|
const char* lspace;
|
|
|
|
const char* rspace;
|
|
|
|
const char* maxsize;
|
|
|
|
const char* minsize;
|
|
|
|
bool fence;
|
|
|
|
bool separator;
|
|
|
|
bool stretchy;
|
|
|
|
bool symmetric;
|
|
|
|
bool largeop;
|
|
|
|
bool movablelimits;
|
|
|
|
bool accent;
|
|
|
|
};
|
|
|
|
|
|
|
|
extern const OperatorDictionary operators[];
|
|
|
|
|
|
|
|
KFORMULA_NAMESPACE_END
|
|
|
|
|
|
|
|
#endif // OPERATORDICTIONARY_H
|
|
|
|
''', file=f)
|
|
|
|
|
|
|
|
def write_cc( fr, fw ):
|
|
|
|
print('''
|
|
|
|
#include "operatordictionary.h"
|
|
|
|
|
|
|
|
KFORMULA_NAMESPACE_BEGIN
|
|
|
|
|
|
|
|
const OperatorDictionary operators[] = {''', file=fw)
|
|
|
|
|
|
|
|
entities = get_entities()
|
|
|
|
parse( fr, fw, entities )
|
|
|
|
|
|
|
|
print('''
|
|
|
|
};
|
|
|
|
|
|
|
|
// Needed since sizeof is a macro and we cannot be used until size is known
|
|
|
|
int OperatorDictionary::size()
|
|
|
|
{
|
|
|
|
return sizeof( operators ) / sizeof( OperatorDictionary );
|
|
|
|
}
|
|
|
|
|
|
|
|
KFORMULA_NAMESPACE_END
|
|
|
|
''', file=fw)
|
|
|
|
|
|
|
|
def get_entities():
|
|
|
|
# First, read entity list into a dict
|
|
|
|
fd = open( 'entity.list' )
|
|
|
|
entities = {}
|
|
|
|
for line in fd.readlines():
|
|
|
|
fields = line.split()
|
|
|
|
entities[fields[0]] = string.atoi( fields[1], 16 )
|
|
|
|
fd.close()
|
|
|
|
return entities
|
|
|
|
|
|
|
|
def key_cmp( a, b ):
|
|
|
|
|
|
|
|
if a[0] < b[0]:
|
|
|
|
return -1
|
|
|
|
if a[0] > b[0]:
|
|
|
|
return 1
|
|
|
|
|
|
|
|
if a[1] < b[1]:
|
|
|
|
return -1
|
|
|
|
if a[1] > b[1]:
|
|
|
|
return 1
|
|
|
|
print('WARNING: Same key in operator dictionary: ' + a[0] + ', ' + b[0])
|
|
|
|
return 0
|
|
|
|
|
|
|
|
def parse( fr, fw, entities ):
|
|
|
|
entries = []
|
|
|
|
line = fr.readline()
|
|
|
|
while line != "":
|
|
|
|
if line[0] == '"':
|
|
|
|
###
|
|
|
|
# If operator element's attributes or default values change in the future,
|
|
|
|
# just update this dictionary and the list at the beginning of the file
|
|
|
|
attr_dict = {
|
|
|
|
attr_list[0]: '"thickmathspace"',
|
|
|
|
attr_list[1]: '"thickmathspace"',
|
|
|
|
attr_list[2]: '"infinity"',
|
|
|
|
attr_list[3]: '"1"',
|
|
|
|
attr_list[4]: '"false"',
|
|
|
|
attr_list[5]: '"false"',
|
|
|
|
attr_list[6]: '"false"',
|
|
|
|
attr_list[7]: '"true"',
|
|
|
|
attr_list[8]: '"false"',
|
|
|
|
attr_list[9]: '"false"',
|
|
|
|
attr_list[10]: '"false"'
|
|
|
|
}
|
|
|
|
fields = line.split()
|
|
|
|
name = string.replace( fields[0], '&', '&' )
|
|
|
|
fields.pop(0) # Remove name
|
|
|
|
entities_found = True
|
|
|
|
while True:
|
|
|
|
begin = string.find( name, '&' )
|
|
|
|
end = string.find( name, ';' )
|
|
|
|
if begin == -1 or end == -1:
|
|
|
|
break
|
|
|
|
###
|
|
|
|
# TODO: Support multicharacter entities, should also be supported by
|
|
|
|
# application. The best solution would probably to map to a single
|
|
|
|
# character provided by the font in the private area of Unicode
|
|
|
|
entity_name = name[begin + 1:end]
|
|
|
|
if entity_name in entities :
|
|
|
|
name = name.replace( '&' + entity_name + ';', chr(entities[entity_name]));
|
|
|
|
else:
|
|
|
|
entities_found = False
|
|
|
|
break
|
|
|
|
if entities_found:
|
|
|
|
form = string.split( fields[0], '=' )[1]
|
|
|
|
fields.pop(0) # Remove form
|
|
|
|
for f in fields:
|
|
|
|
attr, value = string.split( f, '=' )
|
|
|
|
if attr not in attr_dict :
|
|
|
|
print('Unsupported attribute: ' + attr)
|
|
|
|
print('If it is valid, update attribute dictionary')
|
|
|
|
sys.exit(-1)
|
|
|
|
# Spec has a typo, fix it
|
|
|
|
if string.count( value, '"' ) == 3:
|
|
|
|
value = value[:-1]
|
|
|
|
attr_dict[attr] = value
|
|
|
|
entries.append( [name, form, attr_dict] )
|
|
|
|
line = fr.readline()
|
|
|
|
entries.sort( key_cmp, None, True )
|
|
|
|
|
|
|
|
while True:
|
|
|
|
e = entries.pop()
|
|
|
|
print(' { {' + e[0] + ', ' + e[1] + '},', file=fw)
|
|
|
|
d = e[2]
|
|
|
|
for a in attr_list:
|
|
|
|
# Convert, at least, bool values
|
|
|
|
value = d[a]
|
|
|
|
if value == '"true"' or value == '"false"':
|
|
|
|
value = string.strip( value, '"' )
|
|
|
|
print('\t\t' + value, end=' ', file=fw)
|
|
|
|
if a != attr_list[len(attr_list) - 1]:
|
|
|
|
print(',', file=fw)
|
|
|
|
print('}', end=' ', file=fw)
|
|
|
|
if len( entries ) == 0:
|
|
|
|
break
|
|
|
|
print(',\n', file=fw)
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
fh = open( '../operatordictionary.h', 'w' )
|
|
|
|
write_header( fh )
|
|
|
|
write_h( fh )
|
|
|
|
fh.close()
|
|
|
|
fcc = codecs.open( '../operatordictionary.cpp', 'w', 'utf-8' )
|
|
|
|
write_header( fcc )
|
|
|
|
fr = open( sys.argv[1] )
|
|
|
|
write_cc( fr , fcc )
|
|
|
|
fcc.close()
|
|
|
|
fr.close()
|
|
|
|
|