Skip to content

Commit

Permalink
Merge pull request #1 from tyrchen/feature/upgrade-to-elixir-1.5
Browse files Browse the repository at this point in the history
Feature/upgrade to elixir 1.5
  • Loading branch information
tyrchen committed Nov 6, 2017
2 parents 18560e0 + afc9764 commit 0a08149
Show file tree
Hide file tree
Showing 18 changed files with 351 additions and 190 deletions.
113 changes: 113 additions & 0 deletions .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 <name>`. 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`.
#
]
}
]
}
27 changes: 27 additions & 0 deletions .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: :*
]
]
2 changes: 2 additions & 0 deletions .gitignore
Expand Up @@ -6,3 +6,5 @@ bench/graphs
bench/snapshots
*.beam
*.lock
.tool-versions
doc
23 changes: 23 additions & 0 deletions 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
1 change: 0 additions & 1 deletion bench/chinese_translation_bench.exs
Expand Up @@ -34,7 +34,6 @@ defmodule ChineseTranslationBench do
ChineseTranslation.slugify(@pinyin, [:pinyin, :tone])
end


bench "slugify a short sentence" do
ChineseTranslation.slugify("长大以后变成长工")
end
Expand Down
23 changes: 0 additions & 23 deletions 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"
36 changes: 18 additions & 18 deletions lib/chinese_translation.ex
Expand Up @@ -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"
Expand All @@ -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
Expand All @@ -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
25 changes: 13 additions & 12 deletions lib/chinese_translation/pinyin.ex
Expand Up @@ -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(<<ch, rest :: binary>>) 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(<<ch, rest::binary>>) do
[ch | process(rest)]
end

def process("") do
Expand Down

0 comments on commit 0a08149

Please sign in to comment.