Merge from trunk

This commit is contained in:
Charles Haley 2011-05-10 15:18:53 +01:00
commit 05e9dc65d1
17 changed files with 156 additions and 78 deletions

View File

@ -21,14 +21,19 @@ class Fronda(BasicNewsRecipe):
feeds = [(u'Infformacje', u'http://fronda.pl/news/feed')] feeds = [(u'Infformacje', u'http://fronda.pl/news/feed')]
keep_only_tags = [dict(name='h1', attrs={'class':'big'}), keep_only_tags = [dict(name='h2', attrs={'class':'news_title'}),
dict(name='ul', attrs={'class':'about clear'}), dict(name='div', attrs={'class':'naglowek_tresc'}),
dict(name='div', attrs={'class':'content'})] dict(name='div', attrs={'id':'czytaj'}) ]
remove_tags = [dict(name='a', attrs={'class':'print'})]
preprocess_regexps = [ preprocess_regexps = [
(re.compile(i[0], re.IGNORECASE | re.DOTALL), i[1]) for i in (re.compile(i[0], re.IGNORECASE | re.DOTALL), i[1]) for i in
[ (r'<a href="#" class="print">Drukuj</a>', lambda match: ''), [ (r'<p><a href="http://fronda.pl/sklepy">.*</a></p>', lambda match: ''),
(r'<p><a href="http://fronda.pl/sklepy">.*</a></p>', lambda match: ''),
(r'<p><a href="http://fronda.pl/pasaz">.*</a></p>', lambda match: ''), (r'<p><a href="http://fronda.pl/pasaz">.*</a></p>', lambda match: ''),
(r'<h3><strong>W.* lektury.*</a></p></div>', lambda match: '</div>'), (r'<h3><strong>W.* lektury.*</a></p></div>', lambda match: '</div>'),
(r'<h3>Zobacz t.*?</div>', lambda match: '</div>') ] (r'<h3>Zobacz t.*?</div>', lambda match: '</div>'),
(r'<p[^>]*>&nbsp;</p>', lambda match: ''),
(r'<p><span style=".*?"><br /></span></p> ', lambda match: ''),
(r'<a style=\'float:right;margin-top:3px;\' href="http://www.facebook.com/share.php?.*?</a>', lambda match: '')]
] ]

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
recipes/icons/ziuaveche.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 554 B

View File

@ -2,7 +2,7 @@ from calibre.web.feeds.news import BasicNewsRecipe
class RzeczpospolitaRecipe(BasicNewsRecipe): class RzeczpospolitaRecipe(BasicNewsRecipe):
__license__ = 'GPL v3' __license__ = 'GPL v3'
__author__ = 'kwetal' __author__ = u'kwetal and Tomasz Dlugosz'
language = 'pl' language = 'pl'
version = 1 version = 1
@ -38,6 +38,8 @@ class RzeczpospolitaRecipe(BasicNewsRecipe):
remove_tags.append(dict(name = 'div', attrs = {'class' : 'clr'})) remove_tags.append(dict(name = 'div', attrs = {'class' : 'clr'}))
remove_tags.append(dict(name = 'div', attrs = {'id' : 'share_bottom'})) remove_tags.append(dict(name = 'div', attrs = {'id' : 'share_bottom'}))
remove_tags.append(dict(name = 'div', attrs = {'id' : 'copyright_law'})) remove_tags.append(dict(name = 'div', attrs = {'id' : 'copyright_law'}))
remove_tags.append(dict(name = 'div', attrs = {'class' : 'more'}))
remove_tags.append(dict(name = 'div', attrs = {'class' : 'editorPicks'}))
extra_css = ''' extra_css = '''
body {font-family: verdana, arial, helvetica, geneva, sans-serif ;} body {font-family: verdana, arial, helvetica, geneva, sans-serif ;}
@ -48,6 +50,13 @@ class RzeczpospolitaRecipe(BasicNewsRecipe):
.fot{font-size: x-small; color: #666666;} .fot{font-size: x-small; color: #666666;}
''' '''
def skip_ad_pages(self, soup):
if ('advertisement' in soup.find('title').string.lower()):
href = soup.find('a').get('href')
return self.index_to_soup(href, raw=True)
else:
return None
def print_version(self, url): def print_version(self, url):
start, sep, rest = url.rpartition('/') start, sep, rest = url.rpartition('/')
forget, sep, index = rest.rpartition(',') forget, sep, index = rest.rpartition(',')

View File

@ -1,17 +1,12 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
__license__ = 'GPL v3'
__copyright__ = '2009, Gerhard Aigner <gerhard.aigner at gmail.com>'
import re
from calibre.web.feeds.news import BasicNewsRecipe from calibre.web.feeds.news import BasicNewsRecipe
class TelepolisNews(BasicNewsRecipe): class TelepolisNews(BasicNewsRecipe):
title = u'Telepolis (News+Artikel)' title = u'Telepolis (News+Artikel)'
__author__ = 'Gerhard Aigner' __author__ = 'syntaxis'
publisher = 'Heise Zeitschriften Verlag GmbH & Co KG' publisher = 'Heise Zeitschriften Verlag GmbH & Co KG'
description = 'News from telepolis' description = 'News from Telepolis'
category = 'news' category = 'news'
oldest_article = 7 oldest_article = 7
max_articles_per_feed = 100 max_articles_per_feed = 100
@ -20,14 +15,19 @@ class TelepolisNews(BasicNewsRecipe):
encoding = "utf-8" encoding = "utf-8"
language = 'de' language = 'de'
use_embedded_content =False
remove_empty_feeds = True remove_empty_feeds = True
preprocess_regexps = [(re.compile(r'<a[^>]*>', re.DOTALL|re.IGNORECASE), lambda match: ''),
(re.compile(r'</a>', re.DOTALL|re.IGNORECASE), lambda match: ''),]
keep_only_tags = [dict(name = 'td',attrs={'class':'bloghead'}),dict(name = 'td',attrs={'class':'blogfliess'})]
remove_tags = [dict(name='img'), dict(name='td',attrs={'class':'blogbottom'}), dict(name='td',attrs={'class':'forum'})] keep_only_tags = [dict(name = 'div',attrs={'class':'head'}),dict(name = 'div',attrs={'class':'leftbox'}),dict(name='td',attrs={'class':'strict'})]
remove_tags = [ dict(name='td',attrs={'class':'blogbottom'}),
dict(name='div',attrs={'class':'forum'}), dict(name='div',attrs={'class':'social'}),dict(name='div',attrs={'class':'blog-letter p-news'}),
dict(name='div',attrs={'class':'blog-sub'}),dict(name='div',attrs={'class':'version-div'}),dict(name='div',attrs={'id':'breadcrumb'})
,dict(attrs={'class':'tp-url'}),dict(attrs={'class':'blog-name entry_'}) ]
remove_tags_after = [dict(name='span', attrs={'class':['breadcrumb']})]
feeds = [(u'News', u'http://www.heise.de/tp/news-atom.xml')] feeds = [(u'News', u'http://www.heise.de/tp/news-atom.xml')]
@ -39,15 +39,8 @@ class TelepolisNews(BasicNewsRecipe):
html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"' html2epub_options = 'publisher="' + publisher + '"\ncomments="' + description + '"\ntags="' + category + '"'
def get_article_url(self, article):
'''if the linked article is of kind artikel don't take it'''
if (article.link.count('artikel') > 1) :
return None
return article.link
def preprocess_html(self, soup): def preprocess_html(self, soup):
mtag = '<meta http-equiv="Content-Type" content="text/html; charset=' + self.encoding + '">' mtag = '<meta http-equiv="Content-Type" content="text/html; charset=' + self.encoding + '">'
soup.head.insert(0,mtag) soup.head.insert(0,mtag)
return soup return soup

53
recipes/ziuaveche.recipe Normal file
View File

@ -0,0 +1,53 @@
# -*- coding: utf-8 -*-
#!/usr/bin/env python
__license__ = 'GPL v3'
__copyright__ = u'2011, Silviu Cotoar\u0103'
'''
ziuaveche.ro
'''
from calibre.web.feeds.news import BasicNewsRecipe
class ZiuaVeche(BasicNewsRecipe):
title = u'Ziua Veche'
__author__ = u'Silviu Cotoar\u0103'
description = 'Cotidian online'
publisher = 'Ziua Veche'
oldest_article = 5
language = 'ro'
max_articles_per_feed = 100
no_stylesheets = True
use_embedded_content = False
category = 'Ziare,Cotidiane,Stiri'
encoding = 'utf-8'
cover_url = 'http://www.ziuaveche.ro/wp-content/themes/tema/images/zv-logo-alb-old.png'
conversion_options = {
'comments' : description
,'tags' : category
,'language' : language
,'publisher' : publisher
}
keep_only_tags = [
dict(name='div', attrs={'id':'singlePost'})
]
remove_tags = [
dict(name='div', attrs={'id':'LikePluginPagelet'})
]
remove_tags_after = [
dict(name='div', attrs={'id':'LikePluginPagelet'})
]
feeds = [
(u'Feeds', u'http://www.ziuaveche.ro/feed/rss')
]
def preprocess_html(self, soup):
return self.adeify_images(soup)

View File

@ -203,9 +203,11 @@ class ITUNES(DriverBase):
# 0x1294 iPhone 3GS # 0x1294 iPhone 3GS
# 0x1297 iPhone 4 # 0x1297 iPhone 4
# 0x129a iPad # 0x129a iPad
# 0x12a2 iPad2 # 0x129f iPad2 (WiFi)
# 0x12a2 iPad2 (GSM)
# 0x12a3 iPad2 (CDMA)
VENDOR_ID = [0x05ac] VENDOR_ID = [0x05ac]
PRODUCT_ID = [0x1292,0x1293,0x1294,0x1297,0x1299,0x129a,0x12a2] PRODUCT_ID = [0x1292,0x1293,0x1294,0x1297,0x1299,0x129a,0x129f,0x12a2,0x12a3]
BCD = [0x01] BCD = [0x01]
# Plugboard ID # Plugboard ID

View File

@ -68,7 +68,8 @@ def check_command_line_options(parser, args, log):
raise SystemExit(1) raise SystemExit(1)
output = args[2] output = args[2]
if output.startswith('.') and output != '.': if output.startswith('.') and (output != '.' and not
output.startswith('..')):
output = os.path.splitext(os.path.basename(input))[0]+output output = os.path.splitext(os.path.basename(input))[0]+output
output = os.path.abspath(output) output = os.path.abspath(output)

View File

@ -7,7 +7,6 @@ __copyright__ = '2011, John Schember <john@nachtimwald.com>'
__docformat__ = 'restructuredtext en' __docformat__ = 'restructuredtext en'
import os import os
import posixpath
from calibre import guess_type, walk from calibre import guess_type, walk
from calibre.customize.conversion import InputFormatPlugin from calibre.customize.conversion import InputFormatPlugin
@ -74,22 +73,23 @@ class HTMLZInput(InputFormatPlugin):
meta_info_to_oeb_metadata(mi, oeb.metadata, log) meta_info_to_oeb_metadata(mi, oeb.metadata, log)
# Get the cover path from the OPF. # Get the cover path from the OPF.
cover_href = None cover_path = None
opf = None opf = None
for x in walk('.'): for x in walk('.'):
if os.path.splitext(x)[1].lower() in ('.opf'): if os.path.splitext(x)[1].lower() in ('.opf'):
opf = x opf = x
break break
if opf: if opf:
opf = OPF(opf) opf = OPF(opf, basedir=os.getcwd())
cover_href = posixpath.relpath(opf.cover, os.path.dirname(stream.name)) cover_path = opf.raster_cover
# Set the cover. # Set the cover.
if cover_href: if cover_path:
cdata = None cdata = None
with open(cover_href, 'rb') as cf: with open(os.path.join(os.getcwd(), cover_path), 'rb') as cf:
cdata = cf.read() cdata = cf.read()
id, href = oeb.manifest.generate('cover', cover_href) cover_name = os.path.basename(cover_path)
oeb.manifest.add(id, href, guess_type(cover_href)[0], data=cdata) id, href = oeb.manifest.generate('cover', cover_name)
oeb.manifest.add(id, href, guess_type(cover_name)[0], data=cdata)
oeb.guide.add('cover', 'Cover', href) oeb.guide.add('cover', 'Cover', href)
return oeb return oeb

View File

@ -8,12 +8,11 @@ Read meta information from extZ (TXTZ, HTMLZ...) files.
''' '''
import os import os
import posixpath
from cStringIO import StringIO from cStringIO import StringIO
from calibre.ebooks.metadata import MetaInformation from calibre.ebooks.metadata import MetaInformation
from calibre.ebooks.metadata.opf2 import OPF, metadata_to_opf from calibre.ebooks.metadata.opf2 import OPF
from calibre.ptempfile import PersistentTemporaryFile from calibre.ptempfile import PersistentTemporaryFile
from calibre.utils.zipfile import ZipFile, safe_replace from calibre.utils.zipfile import ZipFile, safe_replace
@ -31,9 +30,9 @@ def get_metadata(stream, extract_cover=True):
opf = OPF(opf_stream) opf = OPF(opf_stream)
mi = opf.to_book_metadata() mi = opf.to_book_metadata()
if extract_cover: if extract_cover:
cover_href = posixpath.relpath(opf.cover, os.path.dirname(stream.name)) cover_href = opf.raster_cover
if cover_href: if cover_href:
mi.cover_data = ('jpg', zf.read(cover_href)) mi.cover_data = (os.path.splitext(cover_href)[1], zf.read(cover_href))
except: except:
return mi return mi
return mi return mi
@ -59,18 +58,15 @@ def set_metadata(stream, mi):
except: except:
pass pass
if new_cdata: if new_cdata:
cover = opf.cover cpath = opf.raster_cover
if not cover: if not cpath:
cover = 'cover.jpg' cpath = 'cover.jpg'
cpath = posixpath.join(posixpath.dirname(opf_path), cover)
new_cover = _write_new_cover(new_cdata, cpath) new_cover = _write_new_cover(new_cdata, cpath)
replacements[cpath] = open(new_cover.name, 'rb') replacements[cpath] = open(new_cover.name, 'rb')
mi.cover = cover mi.cover = cpath
# Update the metadata. # Update the metadata.
old_mi = opf.to_book_metadata() opf.smart_update(mi, replace_metadata=True)
old_mi.smart_update(mi)
opf.smart_update(metadata_to_opf(old_mi), replace_metadata=True)
newopf = StringIO(opf.render()) newopf = StringIO(opf.render())
safe_replace(stream, opf_path, newopf, extra_replacements=replacements, add_missing=True) safe_replace(stream, opf_path, newopf, extra_replacements=replacements, add_missing=True)

View File

@ -338,7 +338,7 @@ class Amazon(Source):
q['field-author'] = ' '.join(author_tokens) q['field-author'] = ' '.join(author_tokens)
if not ('field-keywords' in q or 'field-isbn' in q or if not ('field-keywords' in q or 'field-isbn' in q or
('field-title' in q and 'field-author' in q)): ('field-title' in q)):
# Insufficient metadata to make an identify query # Insufficient metadata to make an identify query
return None return None

View File

@ -212,6 +212,9 @@ class Source(Plugin):
def is_customizable(self): def is_customizable(self):
return True return True
def customization_help(self):
return 'This plugin can only be customized using the GUI'
def config_widget(self): def config_widget(self):
from calibre.gui2.metadata.config import ConfigWidget from calibre.gui2.metadata.config import ConfigWidget
return ConfigWidget(self) return ConfigWidget(self)
@ -288,10 +291,10 @@ class Source(Plugin):
parts = parts[1:] + parts[:1] parts = parts[1:] + parts[:1]
for tok in parts: for tok in parts:
tok = remove_pat.sub('', tok).strip() tok = remove_pat.sub('', tok).strip()
if len(tok) > 2 and tok.lower() not in ('von', ): if len(tok) > 2 and tok.lower() not in ('von', 'van',
_('Unknown').lower()):
yield tok yield tok
def get_title_tokens(self, title, strip_joiners=True, strip_subtitle=False): def get_title_tokens(self, title, strip_joiners=True, strip_subtitle=False):
''' '''
Take a title and return a list of tokens useful for an AND search query. Take a title and return a list of tokens useful for an AND search query.

View File

@ -20,6 +20,9 @@ class GenerateCatalogAction(InterfaceAction):
action_spec = (_('Create a catalog of the books in your calibre library'), 'catalog.png', 'Catalog builder', None) action_spec = (_('Create a catalog of the books in your calibre library'), 'catalog.png', 'Catalog builder', None)
dont_add_to = frozenset(['menubar-device', 'toolbar-device', 'context-menu-device']) dont_add_to = frozenset(['menubar-device', 'toolbar-device', 'context-menu-device'])
def genesis(self):
self.qaction.triggered.connect(self.generate_catalog)
def generate_catalog(self): def generate_catalog(self):
rows = self.gui.library_view.selectionModel().selectedRows() rows = self.gui.library_view.selectionModel().selectedRows()
if not rows or len(rows) < 2: if not rows or len(rows) < 2:

View File

@ -19,17 +19,23 @@ class MessageBox(QDialog, Ui_Dialog): # {{{
INFO = 2 INFO = 2
QUESTION = 3 QUESTION = 3
def __init__(self, type_, title, msg, det_msg='', show_copy_button=True, def __init__(self, type_, title, msg,
parent=None): det_msg='',
q_icon=None,
show_copy_button=True,
parent=None):
QDialog.__init__(self, parent) QDialog.__init__(self, parent)
icon = { if q_icon is None:
self.ERROR : 'error', icon = {
self.WARNING: 'warning', self.ERROR : 'error',
self.INFO: 'information', self.WARNING: 'warning',
self.QUESTION: 'question', self.INFO: 'information',
}[type_] self.QUESTION: 'question',
icon = 'dialog_%s.png'%icon }[type_]
self.icon = QIcon(I(icon)) icon = 'dialog_%s.png'%icon
self.icon = QIcon(I(icon))
else:
self.icon = q_icon
self.setupUi(self) self.setupUi(self)
self.setWindowTitle(title) self.setWindowTitle(title)
@ -44,7 +50,6 @@ class MessageBox(QDialog, Ui_Dialog): # {{{
self.bb.ActionRole) self.bb.ActionRole)
self.ctc_button.clicked.connect(self.copy_to_clipboard) self.ctc_button.clicked.connect(self.copy_to_clipboard)
self.show_det_msg = _('Show &details') self.show_det_msg = _('Show &details')
self.hide_det_msg = _('Hide &details') self.hide_det_msg = _('Hide &details')
self.det_msg_toggle = self.bb.addButton(self.show_det_msg, self.bb.ActionRole) self.det_msg_toggle = self.bb.addButton(self.show_det_msg, self.bb.ActionRole)

View File

@ -1126,7 +1126,7 @@ class DateEdit(QDateEdit): # {{{
@dynamic_property @dynamic_property
def current_val(self): def current_val(self):
def fget(self): def fget(self):
return qt_to_dt(self.date()) return qt_to_dt(self.date(), as_utc=False)
def fset(self, val): def fset(self, val):
if val is None: if val is None:
val = UNDEFINED_DATE val = UNDEFINED_DATE

View File

@ -31,6 +31,7 @@ class MetadataSingleDialogBase(ResizableDialog):
view_format = pyqtSignal(object, object) view_format = pyqtSignal(object, object)
cc_two_column = tweaks['metadata_single_use_2_cols_for_custom_fields'] cc_two_column = tweaks['metadata_single_use_2_cols_for_custom_fields']
one_line_comments_toolbar = False one_line_comments_toolbar = False
use_toolbutton_for_config_metadata = True
def __init__(self, db, parent=None): def __init__(self, db, parent=None):
self.db = db self.db = db
@ -71,7 +72,9 @@ class MetadataSingleDialogBase(ResizableDialog):
self.l.addWidget(self.scroll_area) self.l.addWidget(self.scroll_area)
ll = self.button_box_layout = QHBoxLayout() ll = self.button_box_layout = QHBoxLayout()
self.l.addLayout(ll) self.l.addLayout(ll)
ll.addSpacing(10)
ll.addWidget(self.button_box) ll.addWidget(self.button_box)
ll.addSpacing(10)
self.setWindowIcon(QIcon(I('edit_input.png'))) self.setWindowIcon(QIcon(I('edit_input.png')))
self.setWindowTitle(_('Edit Metadata')) self.setWindowTitle(_('Edit Metadata'))
@ -191,7 +194,12 @@ class MetadataSingleDialogBase(ResizableDialog):
font.setBold(True) font.setBold(True)
self.fetch_metadata_button.setFont(font) self.fetch_metadata_button.setFont(font)
self.config_metadata_button = QToolButton(self) if self.use_toolbutton_for_config_metadata:
self.config_metadata_button = QToolButton(self)
self.config_metadata_button.setIcon(QIcon(I('config.png')))
else:
self.config_metadata_button = QPushButton(self)
self.config_metadata_button.setText(_('Configure download metadata'))
self.config_metadata_button.setIcon(QIcon(I('config.png'))) self.config_metadata_button.setIcon(QIcon(I('config.png')))
self.config_metadata_button.clicked.connect(self.configure_metadata) self.config_metadata_button.clicked.connect(self.configure_metadata)
self.config_metadata_button.setToolTip( self.config_metadata_button.setToolTip(
@ -614,6 +622,7 @@ class MetadataSingleDialogAlt1(MetadataSingleDialogBase): # {{{
cc_two_column = False cc_two_column = False
one_line_comments_toolbar = True one_line_comments_toolbar = True
use_toolbutton_for_config_metadata = False
on_drag_enter = pyqtSignal() on_drag_enter = pyqtSignal()
@ -649,10 +658,8 @@ class MetadataSingleDialogAlt1(MetadataSingleDialogBase): # {{{
self.tabs[0].l.addWidget(gb, 0, 0, 1, 1) self.tabs[0].l.addWidget(gb, 0, 0, 1, 1)
gb.setLayout(tl) gb.setLayout(tl)
self.button_box_layout.insertWidget(0, self.fetch_metadata_button) self.button_box_layout.insertWidget(1, self.fetch_metadata_button)
self.config_metadata_button.setToolButtonStyle(Qt.ToolButtonTextOnly) self.button_box_layout.insertWidget(2, self.config_metadata_button)
self.config_metadata_button.setText(_('Configure metadata downloading'))
self.button_box_layout.insertWidget(1, self.config_metadata_button)
sto(self.button_box, self.fetch_metadata_button) sto(self.button_box, self.fetch_metadata_button)
sto(self.fetch_metadata_button, self.config_metadata_button) sto(self.fetch_metadata_button, self.config_metadata_button)
sto(self.config_metadata_button, self.title) sto(self.config_metadata_button, self.title)
@ -767,6 +774,7 @@ class MetadataSingleDialogAlt2(MetadataSingleDialogBase): # {{{
cc_two_column = False cc_two_column = False
one_line_comments_toolbar = True one_line_comments_toolbar = True
use_toolbutton_for_config_metadata = False
def do_layout(self): def do_layout(self):
self.central_widget.clear() self.central_widget.clear()
@ -785,10 +793,8 @@ class MetadataSingleDialogAlt2(MetadataSingleDialogBase): # {{{
l.addWidget(gb, 0, 0, 1, 1) l.addWidget(gb, 0, 0, 1, 1)
gb.setLayout(tl) gb.setLayout(tl)
self.button_box_layout.insertWidget(0, self.fetch_metadata_button) self.button_box_layout.insertWidget(1, self.fetch_metadata_button)
self.config_metadata_button.setToolButtonStyle(Qt.ToolButtonTextOnly) self.button_box_layout.insertWidget(2, self.config_metadata_button)
self.config_metadata_button.setText(_('Configure metadata downloading'))
self.button_box_layout.insertWidget(1, self.config_metadata_button)
sto(self.button_box, self.fetch_metadata_button) sto(self.button_box, self.fetch_metadata_button)
sto(self.fetch_metadata_button, self.config_metadata_button) sto(self.fetch_metadata_button, self.config_metadata_button)
sto(self.config_metadata_button, self.title) sto(self.config_metadata_button, self.title)

View File

@ -10,6 +10,7 @@ License: http://www.opensource.org/licenses/mit-license.php
import re import re
from calibre.utils.icu import capitalize from calibre.utils.icu import capitalize
from calibre.utils.config import prefs
__all__ = ['titlecase'] __all__ = ['titlecase']
__version__ = '0.5' __version__ = '0.5'
@ -67,11 +68,12 @@ def titlecase(text):
line.append(icu_lower(word)) line.append(icu_lower(word))
continue continue
match = MAC_MC.match(word) if prefs['language'].lower().startswith('en'):
if match and not match.group(2)[:3] in ('hin', 'ht'): match = MAC_MC.match(word)
line.append("%s%s" % (capitalize(match.group(1)), if match and not match.group(2)[:3] in ('hin', 'ht'):
capitalize(match.group(2)))) line.append("%s%s" % (capitalize(match.group(1)),
continue capitalize(match.group(2))))
continue
hyphenated = [] hyphenated = []
for item in word.split('-'): for item in word.split('-'):