mirror of
https://github.com/mii443/AzooKeyKanaKanjiConverter.git
synced 2025-08-22 15:05:26 +00:00
Add comma separated number special candidate
This commit is contained in:
@ -0,0 +1,46 @@
|
||||
import Foundation
|
||||
|
||||
extension KanaKanjiConverter {
|
||||
func commaSeparatedNumberCandidates(_ inputData: ComposingText) -> [Candidate] {
|
||||
var text = inputData.convertTarget
|
||||
guard !text.isEmpty else { return [] }
|
||||
|
||||
var negative = false
|
||||
if text.first == "-" {
|
||||
negative = true
|
||||
text.removeFirst()
|
||||
}
|
||||
let parts = text.split(separator: ".", omittingEmptySubsequences: false)
|
||||
guard parts.count <= 2,
|
||||
parts.allSatisfy({ !$0.isEmpty && $0.allSatisfy({ $0.isNumber && $0.isASCII }) }) else {
|
||||
return []
|
||||
}
|
||||
let integerPart = parts[0]
|
||||
guard integerPart.count > 3 else { return [] }
|
||||
|
||||
var reversed = Array(integerPart.reversed())
|
||||
var formatted = ""
|
||||
for (i, ch) in reversed.enumerated() {
|
||||
if i > 0 && i % 3 == 0 {
|
||||
formatted.append(",")
|
||||
}
|
||||
formatted.append(ch)
|
||||
}
|
||||
let integerString = String(formatted.reversed())
|
||||
var result = (negative ? "-" : "") + integerString
|
||||
if parts.count == 2 {
|
||||
let fractional = parts[1]
|
||||
result += "." + fractional
|
||||
}
|
||||
|
||||
let ruby = inputData.convertTarget.toKatakana()
|
||||
let candidate = Candidate(
|
||||
text: result,
|
||||
value: -10,
|
||||
correspondingCount: inputData.input.count,
|
||||
lastMid: MIDData.一般.mid,
|
||||
data: [DicdataElement(word: result, ruby: ruby, cid: CIDData.固有名詞.cid, mid: MIDData.一般.mid, value: -10)]
|
||||
)
|
||||
return [candidate]
|
||||
}
|
||||
}
|
@ -83,6 +83,7 @@ public struct ConvertRequestOptions: Sendable {
|
||||
specialCandidateProviders.append(.timeExpression)
|
||||
specialCandidateProviders.append(.calendar)
|
||||
specialCandidateProviders.append(.version)
|
||||
specialCandidateProviders.append(.commaSeparatedNumber)
|
||||
|
||||
self.N_best = N_best
|
||||
self.requireJapanesePrediction = requireJapanesePrediction
|
||||
|
@ -23,7 +23,8 @@ import EfficientNGram
|
||||
EmailAddressSpecialCandidateProvider(),
|
||||
UnicodeSpecialCandidateProvider(),
|
||||
VersionSpecialCandidateProvider(),
|
||||
TimeExpressionSpecialCandidateProvider()
|
||||
TimeExpressionSpecialCandidateProvider(),
|
||||
CommaSeparatedNumberSpecialCandidateProvider()
|
||||
]
|
||||
@MainActor private var checker = SpellChecker()
|
||||
private var checkerInitialized: [KeyboardLanguage: Bool] = [.none: true, .ja_JP: true]
|
||||
|
@ -45,6 +45,13 @@ public struct TimeExpressionSpecialCandidateProvider: SpecialCandidateProvider {
|
||||
}
|
||||
}
|
||||
|
||||
public struct CommaSeparatedNumberSpecialCandidateProvider: SpecialCandidateProvider {
|
||||
public init() {}
|
||||
@MainActor public func provideCandidates(converter: KanaKanjiConverter, inputData: ComposingText, options _: ConvertRequestOptions) -> [Candidate] {
|
||||
converter.commaSeparatedNumberCandidates(inputData)
|
||||
}
|
||||
}
|
||||
|
||||
public extension SpecialCandidateProvider where Self == CalendarSpecialCandidateProvider {
|
||||
static var calendar: Self { .init() }
|
||||
}
|
||||
@ -68,3 +75,7 @@ public extension SpecialCandidateProvider where Self == VersionSpecialCandidateP
|
||||
public extension SpecialCandidateProvider where Self == TimeExpressionSpecialCandidateProvider {
|
||||
static var timeExpression: Self { .init() }
|
||||
}
|
||||
|
||||
public extension SpecialCandidateProvider where Self == CommaSeparatedNumberSpecialCandidateProvider {
|
||||
static var commaSeparatedNumber: Self { .init() }
|
||||
}
|
||||
|
@ -0,0 +1,41 @@
|
||||
import XCTest
|
||||
@testable import KanaKanjiConverterModule
|
||||
|
||||
final class CommaSeparatedNumberTests: XCTestCase {
|
||||
private func makeDirectInput(direct input: String) -> ComposingText {
|
||||
ComposingText(
|
||||
convertTargetCursorPosition: input.count,
|
||||
input: input.map { .init(character: $0, inputStyle: .direct) },
|
||||
convertTarget: input
|
||||
)
|
||||
}
|
||||
|
||||
func testCommaSeparatedNumberCandidates() async throws {
|
||||
let converter = await KanaKanjiConverter()
|
||||
|
||||
func result(_ text: String) async -> [Candidate] {
|
||||
await converter.commaSeparatedNumberCandidates(makeDirectInput(direct: text))
|
||||
}
|
||||
|
||||
let r1 = await result("49000")
|
||||
XCTAssertEqual(r1.first?.text, "49,000")
|
||||
|
||||
let r2 = await result("109428081")
|
||||
XCTAssertEqual(r2.first?.text, "109,428,081")
|
||||
|
||||
let r3 = await result("2129.49")
|
||||
XCTAssertEqual(r3.first?.text, "2,129.49")
|
||||
|
||||
let r4 = await result("-13932")
|
||||
XCTAssertEqual(r4.first?.text, "-13,932")
|
||||
|
||||
let r5 = await result("12")
|
||||
XCTAssertTrue(r5.isEmpty)
|
||||
|
||||
let r6 = await result("1A9B")
|
||||
XCTAssertTrue(r6.isEmpty)
|
||||
|
||||
let r7 = await result("123")
|
||||
XCTAssertTrue(r7.isEmpty)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user