<s> from acrylamid import log , utils <EOL> from acrylamid . filters import Filter <EOL> from acrylamid . compat import filter , text_type as str <EOL> from acrylamid . lib . html import HTMLParser , HTMLParseError <EOL> import os <EOL> import io <EOL> import re <EOL> from os . path import join , dirname , basename <EOL> class HyphenPatternNotFound ( Exception ) : <EOL> pass <EOL> class Hyphenator : <EOL> """<STR_LIT>""" <EOL> __version__ = '<STR_LIT>' <EOL> def __init__ ( self , chars , patterns , exceptions = '<STR_LIT>' ) : <EOL> self . chars = unicode ( '<STR_LIT>' + re . escape ( chars ) + '<STR_LIT:]>' ) <EOL> self . tree = { } <EOL> for pattern in patterns . split ( ) : <EOL> self . _insert_pattern ( pattern ) <EOL> self . exceptions = { } <EOL> for ex in exceptions . split ( ) : <EOL> self . exceptions [ ex . replace ( '<STR_LIT:->' , '<STR_LIT>' ) ] = [ <NUM_LIT:0> ] + [ int ( h == '<STR_LIT:->' ) for h in re . split ( r"<STR_LIT>" , ex ) ] <EOL> def _insert_pattern ( self , pattern ) : <EOL> chars = re . sub ( '<STR_LIT>' , '<STR_LIT>' , pattern ) <EOL> points = [ int ( d or <NUM_LIT:0> ) for d in re . split ( self . chars , pattern ) ] <EOL> t = self . tree <EOL> for c in chars : <EOL> if c not in t : <EOL> t [ c ] = { } <EOL> t = t [ c ] <EOL> t [ None ] = points <EOL> def hyphenate_word ( self , word ) : <EOL> """<STR_LIT>""" <EOL> if len ( word ) <= <NUM_LIT:4> : <EOL> return [ word ] <EOL> if word . lower ( ) in self . exceptions : <EOL> points = self . exceptions [ word . lower ( ) ] <EOL> else : <EOL> work = '<STR_LIT:.>' + word . lower ( ) + '<STR_LIT:.>' <EOL> points = [ <NUM_LIT:0> ] * ( len ( work ) + <NUM_LIT:1> ) <EOL> for i in range ( len ( work ) ) : <EOL> t = self . tree <EOL> for c in work [ i : ] : <EOL> if c in t : <EOL> t = t [ c ] <EOL> if None in t : <EOL> p = t [ None ] <EOL> for j in range ( len ( p ) ) : <EOL> points [ i + j ] = max ( points [ i + j ] , p [ j ] ) <EOL> else : <EOL> break <EOL> points [ <NUM_LIT:1> ] = points [ <NUM_LIT:2> ] = points [ - <NUM_LIT:2> ] = points [ - <NUM_LIT:3> ] = <NUM_LIT:0> <EOL> pieces = [ '<STR_LIT>' ] <EOL> for c , p in zip ( word , points [ <NUM_LIT:2> : ] ) : <EOL> pieces [ - <NUM_LIT:1> ] += c <EOL> if p % <NUM_LIT:2> : <EOL> pieces . append ( '<STR_LIT>' ) <EOL> return pieces <EOL> class Separator ( HTMLParser ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , html , hyphenationfunc , length = <NUM_LIT:10> ) : <EOL> self . hyphenate = hyphenationfunc <EOL> self . length = length <EOL> HTMLParser . __init__ ( self , html ) <EOL> def handle_data ( self , data ) : <EOL> """<STR_LIT>""" <EOL> if any ( filter ( lambda i : i in self . stack , [ '<STR_LIT>' , '<STR_LIT:code>' , '<STR_LIT>' , '<STR_LIT>' ] ) ) : <EOL> pass <EOL> else : <EOL> split = [ word for word in re . split ( r"<STR_LIT>" , data ) <EOL> if len ( word ) > self . length ] <EOL> for word in split : <EOL> hyphenated = '<STR_LIT>' . join ( self . hyphenate ( word ) ) <EOL> data = data . replace ( word , hyphenated ) <EOL> self . result . append ( data ) <EOL> def build ( lang ) : <EOL> """<STR_LIT>""" <EOL> def gethyph ( lang , directory = '<STR_LIT>' , prefix = '<STR_LIT>' ) : <EOL> for la in [ prefix + lang , prefix + lang [ : <NUM_LIT:2> ] ] : <EOL> for p in os . listdir ( directory ) : <EOL> f = os . path . basename ( p ) <EOL> if f . startswith ( la ) : <EOL> return join ( directory , p ) <EOL> else : <EOL> raise HyphenPatternNotFound ( "<STR_LIT>" % lang ) <EOL> dir = os . path . join ( dirname ( __file__ ) , '<STR_LIT>' ) <EOL> fpath = gethyph ( lang , dir ) . rsplit ( '<STR_LIT:.>' , <NUM_LIT:2> ) [ <NUM_LIT:0> ] <EOL> try : <EOL> with io . open ( fpath + '<STR_LIT>' , encoding = '<STR_LIT:utf-8>' ) as f : <EOL> chars = '<STR_LIT>' . join ( [ line [ <NUM_LIT:0> ] for line in f . readlines ( ) ] ) <EOL> with io . open ( fpath + '<STR_LIT>' , encoding = '<STR_LIT:utf-8>' ) as f : <EOL> patterns = f . read ( ) <EOL> except IOError : <EOL> raise HyphenPatternNotFound ( '<STR_LIT>' % ( lang , lang ) ) <EOL> hyphenator = Hyphenator ( chars , patterns , exceptions = '<STR_LIT>' ) <EOL> del patterns <EOL> del chars <EOL> log . debug ( "<STR_LIT>" % basename ( fpath ) ) <EOL> return hyphenator . hyphenate_word <EOL> class Hyphenate ( Filter ) : <EOL> match = [ re . compile ( '<STR_LIT>' ) ] <EOL> version = <NUM_LIT:2> <EOL> priority = <NUM_LIT> <EOL> @ utils . cached_property <EOL> def default ( self ) : <EOL> try : <EOL> return build ( self . conf [ '<STR_LIT>' ] . replace ( '<STR_LIT:_>' , '<STR_LIT:->' ) ) <EOL> except HyphenPatternNotFound as e : <EOL> log . warn ( e . args [ <NUM_LIT:0> ] ) <EOL> return lambda x : [ x ] <EOL> def init ( self , conf , env ) : <EOL> self . conf = conf <EOL> def transform ( self , content , entry , * args ) : <EOL> if entry . lang != self . conf [ '<STR_LIT>' ] : <EOL> try : <EOL> hyphenate_word = build ( entry . lang . replace ( '<STR_LIT:_>' , '<STR_LIT:->' ) ) <EOL> except HyphenPatternNotFound as e : <EOL> log . warn ( e . args [ <NUM_LIT:0> ] ) <EOL> hyphenate_word = lambda x : [ x ] <EOL> else : <EOL> hyphenate_word = self . default <EOL> try : <EOL> length = int ( args [ <NUM_LIT:0> ] ) <EOL> except ( ValueError , IndexError ) as e : <EOL> if e . __class__ . __name__ == '<STR_LIT>' : <EOL> log . warn ( '<STR_LIT>' , args [ <NUM_LIT:0> ] ) <EOL> length = <NUM_LIT:10> <EOL> try : <EOL> return '<STR_LIT>' . join ( Separator ( content , hyphenate_word , length = length ) . result ) <EOL> except HTMLParseError as e : <EOL> log . exception ( '<STR_LIT>' + entry . filename ) <EOL> return content </s>
