]> gitweb.factorcode.org Git - factor.git/commitdiff
Implement math.text.french
authorSamuel Tardieu <sam@rfc1149.net>
Fri, 23 Jan 2009 14:22:26 +0000 (15:22 +0100)
committerSamuel Tardieu <sam@rfc1149.net>
Fri, 23 Jan 2009 14:22:26 +0000 (15:22 +0100)
extra/math/text/french/authors.txt [new file with mode: 0644]
extra/math/text/french/french-docs.factor [new file with mode: 0644]
extra/math/text/french/french-tests.factor [new file with mode: 0644]
extra/math/text/french/french.factor [new file with mode: 0644]
extra/math/text/french/summary.txt [new file with mode: 0644]

diff --git a/extra/math/text/french/authors.txt b/extra/math/text/french/authors.txt
new file mode 100644 (file)
index 0000000..f3b0233
--- /dev/null
@@ -0,0 +1 @@
+Samuel Tardieu
diff --git a/extra/math/text/french/french-docs.factor b/extra/math/text/french/french-docs.factor
new file mode 100644 (file)
index 0000000..702a963
--- /dev/null
@@ -0,0 +1,6 @@
+USING: help.markup help.syntax ;
+IN: math.text.french
+
+HELP: number>text
+{ $values { "n" "an integer" } { "str" "a string" } }
+{ $description "Return the a string describing " { $snippet "n" } " in French. Numbers with absolute value equal to or greater than 10^12 will be returned using their numeric representation." } ;
diff --git a/extra/math/text/french/french-tests.factor b/extra/math/text/french/french-tests.factor
new file mode 100644 (file)
index 0000000..fd84387
--- /dev/null
@@ -0,0 +1,22 @@
+USING: math math.functions math.parser math.text.french sequences tools.test ;
+
+[ "zéro" ] [ 0 number>text ] unit-test
+[ "vingt et un" ] [ 21 number>text ] unit-test
+[ "vingt-deux" ] [ 22 number>text ] unit-test
+[ "deux mille" ] [ 2000 number>text ] unit-test
+[ "soixante et un" ] [ 61 number>text ] unit-test
+[ "soixante-deux" ] [ 62 number>text ] unit-test
+[ "quatre-vingts" ] [ 80 number>text ] unit-test
+[ "quatre-vingt-un" ] [ 81 number>text ] unit-test
+[ "quatre-vingt-onze" ] [ 91 number>text ] unit-test
+[ "deux cents" ] [ 200 number>text ] unit-test
+[ "mille deux cents" ] [ 1200 number>text ] unit-test
+[ "mille deux cent quatre-vingts" ] [ 1280 number>text ] unit-test
+[ "mille deux cent quatre-vingt-un" ] [ 1281 number>text ] unit-test
+[ "un billion deux cent vingt milliards quatre-vingts millions trois cent quatre-vingt mille deux cents" ] [ 1220080380200 number>text ] unit-test
+[ "un million" ] [ 1000000 number>text ] unit-test
+[ "un million un" ] [ 1000001 number>text ] unit-test
+[ "moins vingt" ] [ -20 number>text ] unit-test
+[ 104 ] [ -1 10 102 ^ - number>text length ] unit-test
+! Check that we do not exhaust stack
+[ 1484 ] [ 10 100 ^ 1 - number>text length ] unit-test
diff --git a/extra/math/text/french/french.factor b/extra/math/text/french/french.factor
new file mode 100644 (file)
index 0000000..f8b9710
--- /dev/null
@@ -0,0 +1,97 @@
+! Copyright (c) 2009 Samuel Tardieu.
+! See http://factorcode.org/license.txt for BSD license.
+USING: arrays assocs combinators kernel math math.functions
+math.parser math.text.utils memoize sequences ;
+IN: math.text.french
+
+<PRIVATE
+
+DEFER: basic ( n -- str )
+
+CONSTANT: literals
+    H{ { 0 "zéro" } { 1 "un" } { 2 "deux" } { 3 "trois" } { 4 "quatre" }
+       { 5 "cinq" } { 6 "six" } { 7 "sept" } { 8 "huit" } { 9 "neuf" }
+       { 10 "dix" } { 11 "onze" } { 12 "douze" } { 13 "treize" }
+       { 14 "quatorze" } { 15 "quinze" } { 16 "seize" } { 17 "dix-sept" }
+       { 18 "dix-huit" } { 19 "dix-neuf" } { 20 "vingt" } { 30 "trente" }
+       { 40 "quarante" } { 50 "cinquante" } { 60 "soixante" }
+       { 71 "soixante et onze" } { 80 "quatre-vingts" }
+       { 81 "quatre-vingt-un" }
+       { 100 "cent" } { 1000 "mille" } }
+
+MEMO: units ( -- seq ) ! up to 10^99
+    { "m" "b" "tr" "quadr" "quint" "sext" "sept" "oct"
+      "non" "déc" "unodéc" "duodéc" "trédéc" "quattuordéc"
+      "quindéc" "sexdéc" }
+      [ [ "illion" append ] [ "illiard" append ] bi 2array ] map concat
+      "mille" prefix ;
+
+! The only plurals we have to remove are "quatre-vingts" and "cents",
+! which are also the only strings ending with "ts".
+: unpluralize ( str -- newstr ) dup "ts" tail? [ but-last ] when ;
+: pluralize ( str -- newstr ) CHAR: s suffix ;
+
+: space-append ( str1 str2 -- str ) " " glue ;
+
+! Small numbers (below 100) use dashes between them unless they are
+! separated with "et". Pluralized prefixes must be unpluralized.
+: complete-small ( str n -- str )
+    { { 0 [ ] }
+      { 1 [ " et un" append ] }
+      [ [ unpluralize ] dip basic "-" glue ] } case ;
+
+: smaller-than-60 ( n -- str )
+    dup 10 mod [ - ] keep [ basic ] dip complete-small ;
+
+: base-onto ( n b -- str ) [ nip literals at ] [ - ] 2bi complete-small ;
+
+: smaller-than-80 ( n -- str ) 60 base-onto ;
+
+: smaller-than-100 ( n -- str ) 80 base-onto ;
+
+: if-zero ( n quot quot -- )
+    [ dup zero? ] 2dip [ [ drop ] prepose ] dip if ; inline
+
+: complete ( str n -- newstr )
+    [ ] [ basic space-append ] if-zero ;
+
+: smaller-than-1000 ( n -- str )
+    100 /mod
+    [ "cent" swap dup 1 = [ drop ] [ basic swap space-append ] if ]
+    [ [ pluralize ] [ basic space-append ] if-zero ] bi* ;
+
+: smaller-than-2000 ( n -- str ) "mille" swap 1000 - complete ;
+
+: smaller-than-1000000 ( n -- str )
+    1000 /mod [ basic unpluralize " mille" append ] dip complete ;
+
+: n-units ( n unit -- str/f )
+    {
+        { [ over zero? ] [ 2drop f ] }
+        { [ over 1 = ] [ [ basic ] dip space-append ] }
+        [ [ basic ] dip space-append pluralize ]
+    } cond ;
+
+: over-1000000 ( n -- str )
+    3digit-groups [ 1+ units nth n-units ] map-index sift
+    reverse " " join ;
+
+: decompose ( n -- str ) 1000000 /mod [ over-1000000 ] dip complete ;
+
+: basic ( n -- str )
+    {
+        { [ dup literals key? ] [ literals at ] }
+        { [ dup 0 < ] [ abs basic "moins " swap append ] }
+        { [ dup 60 < ] [ smaller-than-60 ] }
+        { [ dup 80 < ] [ smaller-than-80 ] }
+        { [ dup 100 < ] [ smaller-than-100 ] }
+        { [ dup 1000 < ] [ smaller-than-1000 ] }
+        { [ dup 2000 < ] [ smaller-than-2000 ] }
+        { [ dup 1000000 < ] [ smaller-than-1000000 ] }
+        [ decompose ]
+    } cond ;
+
+PRIVATE>
+
+: number>text ( n -- str )
+    dup abs 10 102 ^ >= [ number>string ] [ basic ] if ;
diff --git a/extra/math/text/french/summary.txt b/extra/math/text/french/summary.txt
new file mode 100644 (file)
index 0000000..c4c89dc
--- /dev/null
@@ -0,0 +1 @@
+Convert integers to French text