diff --git a/.credo.exs b/.credo.exs new file mode 100644 index 0000000..7cd4cc9 --- /dev/null +++ b/.credo.exs @@ -0,0 +1,113 @@ +# This file contains the configuration for Credo and you are probably reading +# this after creating it with `mix credo.gen.config`. +# +# If you find anything wrong or unclear in this file, please report an +# issue on GitHub: https://github.com/rrrene/credo/issues +# +%{ + # + # You can have as many configs as you like in the `configs:` field. + configs: [ + %{ + # + # Run any config using `mix credo -C `. If no config name is given + # "default" is used. + name: "default", + # + # these are the files included in the analysis + files: %{ + # + # you can give explicit globs or simply directories + # in the latter case `**/*.{ex,exs}` will be used + included: ["lib/", "src/", "web/", "apps/"], + excluded: [~r"/_build/", ~r"/deps/"] + }, + # + # If you create your own checks, you must specify the source files for + # them here, so they can be loaded by Credo before running the analysis. + requires: [], + # + # Credo automatically checks for updates, like e.g. Hex does. + # You can disable this behaviour below: + check_for_updates: true, + # + # If you want to enforce a style guide and need a more traditional linting + # experience, you can change `strict` to true below: + strict: true, + # + # You can customize the parameters of any check by adding a second element + # to the tuple. + # + # To disable a check put `false` as second element: + # + # {Credo.Check.Design.DuplicatedCode, false} + # + checks: [ + {Credo.Check.Consistency.ExceptionNames}, + {Credo.Check.Consistency.LineEndings}, + {Credo.Check.Consistency.SpaceAroundOperators}, + {Credo.Check.Consistency.SpaceInParentheses}, + {Credo.Check.Consistency.TabsOrSpaces}, + + # For some checks, like AliasUsage, you can only customize the priority + # Priority values are: `low, normal, high, higher` + {Credo.Check.Design.AliasUsage, priority: :low}, + + # For others you can set parameters + + # If you don't want the `setup` and `test` macro calls in ExUnit tests + # or the `schema` macro in Ecto schemas to trigger DuplicatedCode, just + # set the `excluded_macros` parameter to `[:schema, :setup, :test]`. + {Credo.Check.Design.DuplicatedCode, excluded_macros: [:schema, :setup, :test]}, + + # You can also customize the exit_status of each check. + # If you don't want TODO comments to cause `mix credo` to fail, just + # set this value to 0 (zero). + {Credo.Check.Design.TagTODO, exit_status: 0}, + {Credo.Check.Design.TagFIXME, exit_status: 0}, + + {Credo.Check.Readability.FunctionNames}, + {Credo.Check.Readability.LargeNumbers, exit_status: 0}, + {Credo.Check.Readability.MaxLineLength, priority: :low, max_length: 120}, + {Credo.Check.Readability.ModuleAttributeNames}, + {Credo.Check.Readability.ModuleDoc}, + {Credo.Check.Readability.ModuleNames}, + {Credo.Check.Readability.ParenthesesInCondition}, + {Credo.Check.Readability.PredicateFunctionNames}, + {Credo.Check.Readability.TrailingBlankLine}, + {Credo.Check.Readability.TrailingWhiteSpace}, + {Credo.Check.Readability.VariableNames}, + + {Credo.Check.Refactor.ABCSize}, + # {Credo.Check.Refactor.CaseTrivialMatches}, # deprecated in 0.4.0 + {Credo.Check.Refactor.CondStatements}, + {Credo.Check.Refactor.FunctionArity, max_arity: 6}, + {Credo.Check.Refactor.MatchInCondition}, + {Credo.Check.Refactor.PipeChainStart}, + {Credo.Check.Refactor.CyclomaticComplexity, max_complexity: 10}, + {Credo.Check.Refactor.NegatedConditionsInUnless}, + {Credo.Check.Refactor.NegatedConditionsWithElse}, + {Credo.Check.Refactor.Nesting, max_nesting: 3}, + {Credo.Check.Refactor.UnlessWithElse}, + + {Credo.Check.Warning.IExPry}, + {Credo.Check.Warning.IoInspect}, + {Credo.Check.Warning.NameRedeclarationByAssignment}, + {Credo.Check.Warning.NameRedeclarationByCase}, + {Credo.Check.Warning.NameRedeclarationByDef}, + {Credo.Check.Warning.NameRedeclarationByFn}, + {Credo.Check.Warning.OperationOnSameValues}, + {Credo.Check.Warning.BoolOperationOnSameValues}, + {Credo.Check.Warning.UnusedEnumOperation}, + {Credo.Check.Warning.UnusedKeywordOperation}, + {Credo.Check.Warning.UnusedListOperation}, + {Credo.Check.Warning.UnusedStringOperation}, + {Credo.Check.Warning.UnusedTupleOperation}, + {Credo.Check.Warning.OperationWithConstantResult}, + + # Custom checks can be created using `mix credo.gen.check`. + # + ] + } + ] +} diff --git a/.formatter.exs b/.formatter.exs new file mode 100644 index 0000000..9049e3c --- /dev/null +++ b/.formatter.exs @@ -0,0 +1,27 @@ +[ + inputs: [ + "lib/**/*.{ex,exs}", + "test/**/*.{ex,exs}", + "bench/**/*.{ex,exs}", + "mix.exs" + ], + locals_without_parens: [ + mount: 1, + swagger: 1, + helpers: 1, + version: 1, + plug: :*, + plug_overridable: :*, + requires: :*, + optional: :*, + group: :*, + given: :*, + mutually_exclusive: 1, + exactly_one_of: 1, + at_least_one_of: 1, + all_or_none_of: 1, + prefix: :*, + rescue_from: :*, + desc: :* + ] +] diff --git a/.gitignore b/.gitignore index 946cdd6..d3ab0e2 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ bench/graphs bench/snapshots *.beam *.lock +.tool-versions +doc diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a91da05 --- /dev/null +++ b/Makefile @@ -0,0 +1,23 @@ +VERSION=$(strip $(shell cat version)) +RELEASE_VERSION=v$(VERSION) +GIT_BRANCH=$(strip $(shell git symbolic-ref --short HEAD)) +GIT_VERSION="$(strip $(shell git rev-parse --short HEAD))" +GIT_LOG=$(shell git log `git describe --tags --abbrev=0`..HEAD --pretty="tformat:%h | %s [%an]\n" | sed "s/\"/'/g") +RELEASE_BODY=release on branch __$(GIT_BRANCH)__\n\n$(GIT_LOG) +RELEASE_DATA='{"tag_name": "$(RELEASE_VERSION)", "name": "$(RELEASE_VERSION)", "target_commitish": "master", "body": "$(RELEASE_BODY)"}' +RELEASE_URL=https://api.github.com/repos/tyrchen/chinese_translation/releases + +release: +ifeq ($(GITHUB_TOKEN),) + @echo "To generate a release, you need to define 'GITHUB_TOKEN' in your env." +else + @echo "Create a release on $(RELEASE_VERSION)" + @git tag -a $(RELEASE_VERSION) -m "Release $(RELEASE_VERSION). Revision is: $(GIT_VERSION)" + @git push origin $(RELEASE_VERSION) + curl -s -d $(RELEASE_DATA) "$(RELEASE_URL)?access_token=$(GITHUB_TOKEN)" +endif + +delete-release: + @echo "Delete a release on $(RELEASE_VERSION)" + @git tag -d $(RELEASE_VERSION) | true + @git push -f -d origin $(RELEASE_VERSION) | true diff --git a/bench/chinese_translation_bench.exs b/bench/chinese_translation_bench.exs index 1181c32..f2312e9 100644 --- a/bench/chinese_translation_bench.exs +++ b/bench/chinese_translation_bench.exs @@ -34,7 +34,6 @@ defmodule ChineseTranslationBench do ChineseTranslation.slugify(@pinyin, [:pinyin, :tone]) end - bench "slugify a short sentence" do ChineseTranslation.slugify("长大以后变成长工") end diff --git a/config/config.exs b/config/config.exs index 6dfa82f..d2d855e 100644 --- a/config/config.exs +++ b/config/config.exs @@ -1,24 +1 @@ -# This file is responsible for configuring your application -# and its dependencies with the aid of the Mix.Config module. use Mix.Config - -# This configuration is loaded before any dependency and is restricted -# to this project. If another project depends on this project, this -# file won't be loaded nor affect the parent project. For this reason, -# if you want to provide default values for your application for third- -# party users, it should be done in your mix.exs file. - -# Sample configuration: -# -# config :logger, :console, -# level: :info, -# format: "$date $time [$level] $metadata$message\n", -# metadata: [:user_id] - -# It is also possible to import configuration files, relative to this -# directory. For example, you can emulate configuration per environment -# by uncommenting the line below and defining dev.exs, test.exs and such. -# Configuration from the imported file will override the ones defined -# here (which is why it is important to import them last). -# -# import_config "#{Mix.env}.exs" diff --git a/lib/chinese_translation.ex b/lib/chinese_translation.ex index 1bf9309..4089c2d 100644 --- a/lib/chinese_translation.ex +++ b/lib/chinese_translation.ex @@ -2,47 +2,47 @@ defmodule ChineseTranslation do alias ChineseTranslation.Translation, as: Trans alias ChineseTranslation.Pinyin alias ChineseTranslation.Slugify + @moduledoc """ - this module only utilize zh2Hant to do translation from simplified chinese + this module only utilize zh2Hant to do translation from simplified chinese to traditional chinese, and vise versa. """ @doc ~S""" Public function to do Chinese translation. Example: - + iex> ChineseTranslation.translate("我是中国人", :s2t) "我是中國人" iex> ChineseTranslation.translate("我是中國人") "我是中国人" - + """ - def translate(content), do: content |> Trans.do_t2s |> IO.iodata_to_binary - def translate(content, :s2t), do: content |> Trans.do_s2t |> IO.iodata_to_binary + def translate(content), do: content |> Trans.do_t2s() |> IO.iodata_to_binary() + def translate(content, :s2t), do: content |> Trans.do_s2t() |> IO.iodata_to_binary() @doc ~S""" Public function to convert Chinese words to pinyin. Example: - + iex> ChineseTranslation.pinyin("我是中国人") "wǒ shì zhōng guó rén" iex> ChineseTranslation.pinyin("我是中國人", :trad) "wǒ shì zhōng guó rén" - + """ def pinyin(content, :trad), do: content |> translate |> pinyin def pinyin(content) do content - |> Pinyin.process - |> IO.iodata_to_binary - |> String.rstrip + |> Pinyin.process() + |> IO.iodata_to_binary() + |> String.trim_trailing() end - @doc ~S""" Public function to slugify Chinese words. Example: - + iex> ChineseTranslation.slugify("我是中国人") "wo-shi-zhong-guo-ren" @@ -51,7 +51,7 @@ defmodule ChineseTranslation do iex> ChineseTranslation.slugify(" *& 我是46 848 中 ----- 国人") "wo-shi-zhong-guo-ren" - + """ def slugify(content), do: content |> pinyin |> to_slug def slugify(content, [:pinyin]), do: content |> to_slug @@ -64,19 +64,19 @@ defmodule ChineseTranslation do defp to_slug(data, with_tone \\ false) do data - |> String.split - |> Stream.map(&(normalize_slug(&1, with_tone))) + |> String.split() + |> Stream.map(&normalize_slug(&1, with_tone)) |> Enum.join(" ") |> String.replace(~r/[^a-z1-4]+/, "-") - |> String.strip(?-) + |> String.trim("-") end defp normalize_slug(content, with_tone) do - slug = content |> Slugify.process + slug = content |> Slugify.process() + case with_tone do true -> slug false -> Regex.replace(~r/[1-4]/, slug, "") end end - end diff --git a/lib/chinese_translation/pinyin.ex b/lib/chinese_translation/pinyin.ex index a4e0ade..1d3d2f7 100644 --- a/lib/chinese_translation/pinyin.ex +++ b/lib/chinese_translation/pinyin.ex @@ -6,20 +6,21 @@ defmodule ChineseTranslation.Pinyin do alias ChineseTranslation.Pinyin.Util - IO.puts "Max word length used by compilation: #{Util.max_word_len}" - Util.get_pinyin_data - |> Stream.with_index - |> Stream.map(fn({{ch, pinyin}, index}) -> - if rem(index, 1000) == 0, do: IO.puts "processing: #{index} #{ch}" + IO.puts("Max word length used by compilation: #{Util.max_word_len()}") - def process(unquote(ch) <> rest) do - unquote(:binary.bin_to_list(pinyin <> " ")) ++ process(rest) - end - end) - |> Enum.to_list + Util.get_pinyin_data() + |> Stream.with_index() + |> Stream.map(fn {{ch, pinyin}, index} -> + if rem(index, 1000) == 0, do: IO.puts("processing: #{index} #{ch}") - def process(<>) do - [ch|process(rest)] + def process(unquote(ch) <> rest) do + unquote(:binary.bin_to_list(pinyin <> " ")) ++ process(rest) + end + end) + |> Enum.to_list() + + def process(<>) do + [ch | process(rest)] end def process("") do diff --git a/lib/chinese_translation/pinyin_util.ex b/lib/chinese_translation/pinyin_util.ex index d167edd..f7ef8fe 100644 --- a/lib/chinese_translation/pinyin_util.ex +++ b/lib/chinese_translation/pinyin_util.ex @@ -23,53 +23,55 @@ defmodule ChineseTranslation.Pinyin.Util do def max_word_len do # this is to avoid atom exceed - after all, the whole # words are > 200, 000 - (System.get_env("MAX_WORD_LEN") || "2") |> String.to_integer + (System.get_env("MAX_WORD_LEN") || "2") |> String.to_integer() end def parse("pinyin_words.txt" = filename) do + # after split, items should be 2 filename |> get_file_stream - |> Stream.map(&(split(&1, ","))) - |> Iterable.filter_by(:item_size, :eq, 2) # after split, items should be 2 - |> Iterable.filter_by(:key_len, :lte, max_word_len) + |> Stream.map(&split(&1, ",")) + |> Iterable.filter_by(:item_size, :eq, 2) + |> Iterable.filter_by(:key_len, :lte, max_word_len()) |> Iterable.sort_by(:key_len, :desc) end def parse("pinyin_characters.txt" = filename) do filename |> get_file_stream - |> Stream.map(&(normalize_character_conversion(&1))) - |> Enum.to_list + |> Stream.map(&normalize_character_conversion(&1)) + |> Enum.to_list() end def parse("pinyin_tone.txt" = filename) do filename |> get_file_stream - |> Stream.map(&(split(&1, ","))) + |> Stream.map(&split(&1, ",")) |> Iterable.sort_by(:key_len, :desc) end defp get_file_stream(filename) do - Path.join(@path, filename) - |> File.stream! + @path + |> Path.join(filename) + |> File.stream!() end defp split(line, sep \\ " ") do line - |> String.strip + |> String.trim() |> String.split(sep) - |> Enum.map(&(String.strip(&1))) - |> List.to_tuple + |> Enum.map(&String.trim(&1)) + |> List.to_tuple() end defp normalize_character_conversion(line) do {string_code, pinyin} = split(line) - char = << String.to_integer(string_code, 16) :: utf8 >> - # TODO: tchen figure out how to fix this Thu Mar 5 10:37:24 2015 + char = <> + # so far for character with multiple pinyin, if it doesn't have word context - # we don't know which pinyin to use. So we just use the first one as a + # we don't know which pinyin to use. So we just use the first one as a # workaround. - data = split(pinyin, ",") |> elem(0) + data = pinyin |> split(",") |> elem(0) {char, data} end end diff --git a/lib/chinese_translation/slugify.ex b/lib/chinese_translation/slugify.ex index dd2291b..d903574 100644 --- a/lib/chinese_translation/slugify.ex +++ b/lib/chinese_translation/slugify.ex @@ -1,21 +1,22 @@ defmodule ChineseTranslation.Slugify do @moduledoc """ - Read the pinyin tone file and generate functions to + Read the pinyin tone file and generate functions to normalize the tone """ alias ChineseTranslation.Pinyin.Util - IO.puts "Processing pinyin tones" - Util.get_tone_data - |> Stream.map(fn({pinyin, ascii, tone}) -> - defp process(unquote(pinyin) <> rest, _acc) do - unquote(:binary.bin_to_list(ascii)) ++ process(rest, unquote(tone)) - end - end) - |> Enum.to_list + IO.puts("Processing pinyin tones") - defp process(<>, acc) do - [ch|process(rest, acc)] + Util.get_tone_data() + |> Stream.map(fn {pinyin, ascii, tone} -> + defp process(unquote(pinyin) <> rest, _acc) do + unquote(:binary.bin_to_list(ascii)) ++ process(rest, unquote(tone)) + end + end) + |> Enum.to_list() + + defp process(<>, acc) do + [ch | process(rest, acc)] end defp process("", acc) do @@ -23,7 +24,6 @@ defmodule ChineseTranslation.Slugify do end def process(content) do - process(content, "") |> IO.iodata_to_binary + content |> process("") |> IO.iodata_to_binary() end - end diff --git a/lib/chinese_translation/translation.ex b/lib/chinese_translation/translation.ex index 508993f..a2736db 100644 --- a/lib/chinese_translation/translation.ex +++ b/lib/chinese_translation/translation.ex @@ -1,28 +1,33 @@ defmodule ChineseTranslation.Translation do - ChineseTranslation.Translation.Util.get_trans_data - |> Dict.get("zh2Hant", []) - |> Enum.map(fn({simp, trad}) -> - def do_t2s(unquote(trad) <> rest) do - unquote(:binary.bin_to_list(simp)) ++ do_t2s(rest) - end + @moduledoc """ + Generate a set of translation functions + """ + alias ChineseTranslation.Translation.Util - def do_s2t(unquote(simp) <> rest) do - unquote(:binary.bin_to_list(trad)) ++ do_s2t(rest) - end - end) + Util.get_trans_data() + |> Map.get("zh2Hant", []) + |> Enum.map(fn {simp, trad} -> + def do_t2s(unquote(trad) <> rest) do + unquote(:binary.bin_to_list(simp)) ++ do_t2s(rest) + end - def do_t2s(<>) do - [ch|do_t2s(rest)] - end + def do_s2t(unquote(simp) <> rest) do + unquote(:binary.bin_to_list(trad)) ++ do_s2t(rest) + end + end) - def do_s2t(<>) do - [ch|do_s2t(rest)] + def do_t2s(<>) do + [ch | do_t2s(rest)] end def do_t2s("") do [] end + def do_s2t(<>) do + [ch | do_s2t(rest)] + end + def do_s2t("") do [] end diff --git a/lib/chinese_translation/translation_util.ex b/lib/chinese_translation/translation_util.ex index 82b6731..a1fe988 100644 --- a/lib/chinese_translation/translation_util.ex +++ b/lib/chinese_translation/translation_util.ex @@ -12,49 +12,54 @@ defmodule ChineseTranslation.Translation.Util do @filename |> get_file_content |> match - |> Enum.map(fn([_whole, name, content]) -> - {name, parse(content)} - end) + |> Enum.map(fn [_whole, name, content] -> + {name, parse(content)} + end) |> Enum.into(%{}) end defp get_file_content(filename) do case File.read(filename) do - {:error, _} -> "" # silently do nothing - {:ok, content} -> content + # silently do nothing + {:error, _} -> + "" + + {:ok, content} -> + content end end defp match(content) do - Regex.scan @php_regex, content + Regex.scan(@php_regex, content) end - + defp parse(content) do - Regex.scan(@php_kv, content) - |> Enum.map(fn([_whole, key, value]) -> - {key, value} - end) + @php_kv + |> Regex.scan(content) + |> Enum.map(fn [_whole, key, value] -> + {key, value} + end) |> sort end defp sort(data) do - data |> Enum.sort(fn({k1, _}, {k2, _}) -> - String.length(k1) > String.length(k2) - end) + data + |> Enum.sort(fn {k1, _}, {k2, _} -> + String.length(k1) > String.length(k2) + end) end # for debug purpose - to see how the parsed file is - def to_files do - get_trans_data - |> Enum.map(&to_file/1) - end + def to_files, do: Enum.map(get_trans_data(), &to_file/1) defp to_file({name, data}) do - content = data - |> Enum.map(fn({k, v}) -> - "#{k}: #{v}" - end) - |> Enum.join("\n") + content = + data + |> Enum.map(fn {k, v} -> + "#{k}: #{v}" + end) + |> Enum.join("\n") + File.write!("data/#{name}.txt", content) end end diff --git a/lib/chinese_translation/util.ex b/lib/chinese_translation/util.ex index 258110e..60c7f4a 100644 --- a/lib/chinese_translation/util.ex +++ b/lib/chinese_translation/util.ex @@ -1,63 +1,52 @@ -defmodule ChineseTranslation.Iterable.Macro do - defmacro comp_fun(comp) do - c = case comp do - :gt -> :> - :gte -> :>= - :lt -> :< - :lte -> :<= - :eq -> :eq - _ -> raise @not_implemented - end - quote do - fn(x, y) -> - unquote({c, [], [{:x, [], Elixir}, {:y, [], Elixir}]}) - end - end - end -end - defmodule ChineseTranslation.Iterable do + @moduledoc """ + Utility functions + """ @not_implemented "not implemented" def filter_by(iterable, :key_len, comp, value) do k = key_fun(:key_len) c = comp_fun(comp) + iterable - |> Stream.filter(&(c.(k.(&1), value))) + |> Stream.filter(&c.(k.(&1), value)) end def filter_by(iterable, :item_size, comp, value) do - k = &(tuple_size(&1)) + k = &tuple_size(&1) c = comp_fun(comp) + iterable - |> Stream.filter(&(c.(k.(&1), value))) + |> Stream.filter(&c.(k.(&1), value)) end def sort_by(iterable, key, direction) do k = key_fun(key) - c = case direction do - :desc -> :gt - :asc -> :lt - end - |> comp_fun + + op = + case direction do + :desc -> :gt + :asc -> :lt + end + + c = comp_fun(op) iterable - |> Enum.sort(&(c.(k.(&1), k.(&2)))) + |> Enum.sort(&c.(k.(&1), k.(&2))) end - defp key_fun(:key_len), do: fn(x) -> x |> elem(0) |> String.length end - defp key_fun(:val_len), do: fn(x) -> x |> elem(1) |> String.length end - defp key_fun(_), do: raise @not_implemented + defp key_fun(:key_len), do: fn x -> x |> elem(0) |> String.length() end + defp key_fun(:val_len), do: fn x -> x |> elem(1) |> String.length() end + defp key_fun(_), do: raise(@not_implemented) defp comp_fun(comp) do case comp do - :gt -> &(&1 > &2) - :gte -> &(&1 >= &2) - :lt -> &(&1 < &2) - :lte -> &(&1 <= &2) - :eq -> &(&1 == &2) - _ -> raise "not supported: #{comp}" + :gt -> &(&1 > &2) + :gte -> &(&1 >= &2) + :lt -> &(&1 < &2) + :lte -> &(&1 <= &2) + :eq -> &(&1 == &2) + _ -> raise "not supported: #{comp}" end end - end diff --git a/lib/mix/tasks/translation.ex b/lib/mix/tasks/translation.ex index 239bf96..06f3940 100644 --- a/lib/mix/tasks/translation.ex +++ b/lib/mix/tasks/translation.ex @@ -1,18 +1,25 @@ defmodule Mix.Tasks.ChineseTranslation do + @moduledoc """ + The task for loading latest data from wikipedia. + """ use Mix.Task @shortdoc "get the latest version of the translation table and recompile myself" - @urls [{ - "http://svn.wikimedia.org/svnroot/mediawiki/trunk/phase3/includes/ZhConversion.php", - "s2t_conversion.txt" - },{ - "https://raw.githubusercontent.com/janx/ruby-pinyin/master/lib/ruby-pinyin/data/words.dat", - "pinyin_words.txt" - },{ - "https://raw.githubusercontent.com/janx/ruby-pinyin/master/lib/ruby-pinyin/data/Mandarin.dat", - "pinyin_characters.txt" - }] + @urls [ + { + "http://svn.wikimedia.org/svnroot/mediawiki/trunk/phase3/includes/ZhConversion.php", + "s2t_conversion.txt" + }, + { + "https://raw.githubusercontent.com/janx/ruby-pinyin/master/lib/ruby-pinyin/data/words.dat", + "pinyin_words.txt" + }, + { + "https://raw.githubusercontent.com/janx/ruby-pinyin/master/lib/ruby-pinyin/data/Mandarin.dat", + "pinyin_characters.txt" + } + ] @name "chinese_translation" @mod_path "data" @@ -20,7 +27,7 @@ defmodule Mix.Tasks.ChineseTranslation do @beam_path "_build/dev/lib/#{@name}" def run(_args) do - HTTPoison.start + HTTPoison.start() get_data_file(@urls) clean_beam(@beam_path) recompile() @@ -30,30 +37,31 @@ defmodule Mix.Tasks.ChineseTranslation do urls |> Stream.map(&download/1) |> Stream.map(&write_file/1) - |> Enum.to_list + |> Enum.to_list() end defp clean_beam(beam_path) do - IO.puts "Cleaning #{beam_path}..." + IO.puts("Cleaning #{beam_path}...") File.rm_rf(beam_path) end defp recompile do - IO.puts "Recompiling chinese_translation..." + IO.puts("Recompiling chinese_translation...") System.cmd("mix", ["compile"]) end defp download({url, filename}) do - IO.puts "Downloading from #{url}..." - %HTTPoison.Response{body: body} = HTTPoison.get! url + IO.puts("Downloading from #{url}...") + %HTTPoison.Response{body: body} = HTTPoison.get!(url) {filename, body} end def write_file({filename, body}) do - case File.exists? @dep_path do + path = case File.exists?(@dep_path) do true -> Path.join(@dep_path, filename) - _ -> Path.join(@mod_path, filename) + _ -> Path.join(@mod_path, filename) end - |> File.write(body) + + File.write(path, body) end end diff --git a/mix.exs b/mix.exs index 932f6df..6e3bf36 100644 --- a/mix.exs +++ b/mix.exs @@ -1,14 +1,17 @@ defmodule ChineseTranslation.Mixfile do use Mix.Project + @version File.cwd!() |> Path.join("version") |> File.read!() |> String.trim() + def project do - [app: :chinese_translation, - version: "0.1.0", - elixir: "~> 1.0", - description: description, - package: package, - deps: deps, - ] + [ + app: :chinese_translation, + version: @version, + elixir: "~> 1.5", + description: description(), + package: package(), + deps: deps() + ] end # Configuration for the OTP application @@ -21,7 +24,13 @@ defmodule ChineseTranslation.Mixfile do # Type `mix help deps` for more examples and options defp deps do [ - {:httpoison, "~> 0.6"}, + {:httpoison, "~> 0.13"}, + + # dev & test + {:benchfella, "~> 0.3.5", only: [:dev]}, + {:credo, "~> 0.8", only: [:dev, :test]}, + {:ex_doc, "~> 0.18.1", only: [:dev, :test]}, + {:pre_commit_hook, "~> 1.0.6", only: [:dev]} ] end @@ -37,6 +46,6 @@ defmodule ChineseTranslation.Mixfile do contributors: ["Tyr Chen"], licenses: ["MIT"], links: %{"GitHub" => "https://github.com/tyrchen/chinese_translation"} - ] + ] end end diff --git a/test/slugify_test.exs b/test/slugify_test.exs index b72fc97..cbf5004 100644 --- a/test/slugify_test.exs +++ b/test/slugify_test.exs @@ -9,12 +9,12 @@ defmodule ChineseTranslationTest.Slugify do assert ChineseTranslation.slugify("长大以后的长工", [:tone]) == "zhang3-da4-yi3-hou4-de-chang2-gong1" end - test "can slugify the tranditional chinese chanraters" do assert ChineseTranslation.slugify("長大以後的長工", [:trad]) == "zhang-da-yi-hou-de-chang-gong" end test "can slugify the tranditional chinese chanraters with tone" do - assert ChineseTranslation.slugify("長大以後的長工", [:trad, :tone]) == "zhang3-da4-yi3-hou4-de-chang2-gong1" + assert ChineseTranslation.slugify("長大以後的長工", [:trad, :tone]) == + "zhang3-da4-yi3-hou4-de-chang2-gong1" end end diff --git a/test/translation_test.exs b/test/translation_test.exs index c2d6214..3940dc5 100644 --- a/test/translation_test.exs +++ b/test/translation_test.exs @@ -11,11 +11,11 @@ defmodule ChineseTranslationTest.Translation do end test "can translate words t->s" do - assert ChineseTranslation.translate("幹線") == "干线" + assert ChineseTranslation.translate("幹線") == "干线" end test "can translate words s->t" do - assert ChineseTranslation.translate("干线", :s2t) == "幹線" + assert ChineseTranslation.translate("干线", :s2t) == "幹線" end test "can do maximum translation t->s" do diff --git a/version b/version new file mode 100644 index 0000000..0ea3a94 --- /dev/null +++ b/version @@ -0,0 +1 @@ +0.2.0