StringAutoTest.swift 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644
  1. //
  2. // CharacterAutoTest.swift
  3. // KdanAuto
  4. //
  5. // Created by 朱东勇 on 2022/11/22.
  6. //
  7. import Foundation
  8. import Cocoa
  9. class StringAutoTest : AutoTest {
  10. // override func type() -> String {
  11. // return "PDFConvert_China_Auto_Test"
  12. // }
  13. override func name() -> String {
  14. return _name
  15. }
  16. override func keys() -> NSArray {
  17. return ["字符"]
  18. }
  19. override func needTest() -> Bool {
  20. return self.selectedKeys().count > 0
  21. }
  22. override class func shared() -> AutoTest? {
  23. return StringAutoTest()
  24. }
  25. // Auto Test refrence Check File
  26. override func autoTest(_ complention:@escaping (_ object:AutoTest, _ report:NSAttributedString?) -> ()) {
  27. self.compareFinishedFiles.removeAllObjects();
  28. self.convertFiles.removeAllObjects()
  29. clearCacheFiles()
  30. let needCheckString = self.selectedKeys().contains("字符")
  31. if !needCheckString {
  32. _status = .Finished
  33. complention(self, self.reportString)
  34. return
  35. }
  36. _status = .Process
  37. reportString = NSMutableAttributedString.init(string: "\n【\(String(self.fileType())) - \(self.name())】字符比对开始!\n",
  38. attributes:[.foregroundColor : NSColor.blue])
  39. let files = DataModel.shared.originFilesFor(_fileType, type: _type)
  40. self.testFiles = NSArray(array: files);
  41. let checkDirectory = self.checkFileDirectory()
  42. let originDirectory = self.originFileDirectory()
  43. let resultDirectory = self.resultFileDirectory()
  44. if (files.count > 0) {
  45. try? FileManager.default.createDirectory(atPath: checkDirectory, withIntermediateDirectories: true);
  46. try? FileManager.default.createDirectory(atPath: resultDirectory, withIntermediateDirectories: true);
  47. }
  48. var tDegree = Double(0);
  49. var tCount = Int(0)
  50. var fileIndex = 0;
  51. var convertFileBlock = { (files:[String]) in }
  52. convertFileBlock = { (files:[String]) in
  53. if (fileIndex >= files.count) {
  54. TestDegreeManager.shared().set(((tCount != 0) ? tDegree/Double(tCount) : 0.0),
  55. fileType: self.fileType(),
  56. type: self.type())
  57. self._status = .Finished
  58. DispatchQueue.main.async {
  59. autoreleasepool {
  60. complention(self, self.reportString);
  61. }
  62. }
  63. return
  64. }
  65. let fileName = files[fileIndex]
  66. let fName = NSString(string: fileName).deletingPathExtension
  67. let originPath = NSString(string: originDirectory).appendingPathComponent(fName+".pdf")
  68. let resultPath = NSString(string: resultDirectory).appendingPathComponent(fName+"."+self.extention())
  69. let checkPath = NSString(string: checkDirectory).appendingPathComponent(fName+"."+self.extention())
  70. self.reportString?.append(NSMutableAttributedString.init(string: "\n【\(String(self.fileType())) - \(self.name())】开始转换文件 \"\(fName)\"\n",
  71. attributes:[.foregroundColor : NSColor.black]))
  72. // ...
  73. // 执行转换过程
  74. let index = self.testFiles.index(of: fileName);
  75. if (index != NSNotFound) {
  76. self.convertProgress = Double(index) / Double(self.testFiles.count)
  77. }
  78. self.convertFiles.add(fileName);
  79. self.testlog("开始转换:"+fileName, (self.compareProgress + self.convertProgress)/2.0)
  80. self.process(originPath, resultPath: resultPath) { status in
  81. if FileManager.default.fileExists(atPath: resultPath) && status == 1 {
  82. if needCheckString && FileManager.default.fileExists(atPath: checkPath) {
  83. DispatchQueue.global().async {
  84. let checkString = self.readTextFile(checkPath as NSString)
  85. let resultStr = self.readTextFile(resultPath as NSString)
  86. if (checkString != nil && resultStr != nil) {
  87. let maxSize = checkString!.count
  88. let report = NSMutableAttributedString(string: "")
  89. let degree = self.compareString(checkString as! NSString, result: resultStr as! NSString) { appAttr in
  90. report.append(appAttr)
  91. }
  92. // let degree = self.compareString(checkString as! NSString, result: resultStr as! NSString) { skipString, failString in
  93. // self.appendErrorInfo(skipString, failString: failString)
  94. // }
  95. var color = NSColor.black
  96. if fabs(degree-100.0) >= 0.01 {
  97. color = NSColor.red
  98. }
  99. tDegree += degree;
  100. tCount += 1
  101. TestDegreeManager.shared().set(degree,
  102. fileType: self.fileType(),
  103. type: self.type(),
  104. fileName: fileName)
  105. let successCount = Int(maxSize * Int(degree)/100)
  106. report.append(NSAttributedString.init(string: "\n【\(String(self.fileType())) - \(self.name())】文件 \"\(fName)\"比对完成,准确率\(degree)%(\(successCount)/\(maxSize))\n",
  107. attributes:[.foregroundColor : color]))
  108. if (report != nil) {
  109. do {
  110. let rtfData = try? report.data(from: .init(location: 0, length: report.length),
  111. documentAttributes: [.documentType: NSAttributedString.DocumentType.rtf])
  112. let path = NSString(string: resultPath).appendingPathExtension("rtf")
  113. try? FileManager.default.removeItem(atPath: path!);
  114. try? rtfData?.write(to: NSURL.fileURL(withPath: path!))
  115. } catch {
  116. }
  117. self.reportString?.append(report)
  118. }
  119. }
  120. let index = self.testFiles.index(of: fileName);
  121. if (index != NSNotFound) {
  122. self.compareProgress = Double(index) / Double(self.testFiles.count)
  123. }
  124. self.compareFinishedFiles.add(fileName);
  125. self.testlog("对比完成:"+fileName, (self.compareProgress + self.convertProgress)/2.0)
  126. fileIndex += 1
  127. convertFileBlock(files);
  128. }
  129. }else {
  130. self.reportString?.append(NSMutableAttributedString.init(string: "【\(String(self.fileType())) - \(self.name())】对照文件 \"\(fName)\"不存在!\n",
  131. attributes:[.foregroundColor : NSColor.red]))
  132. let index = self.testFiles.index(of: fileName);
  133. if (index != NSNotFound) {
  134. self.compareProgress = Double(index) / Double(self.testFiles.count)
  135. }
  136. self.compareFinishedFiles.add(fileName);
  137. self.testlog("对比完成:"+fileName, (self.compareProgress + self.convertProgress)/2.0)
  138. fileIndex += 1
  139. convertFileBlock(files);
  140. }
  141. }else {
  142. if (status == 0) {
  143. self.reportString?.append(NSMutableAttributedString.init(string: "【\(String(self.fileType())) - \(self.name())】文件 \"\(fName)\"转档失败!\n",
  144. attributes:[.foregroundColor : NSColor.red]))
  145. }else if (status == -1 || status == -2) {
  146. self.reportString?.append(NSMutableAttributedString.init(string: "【\(String(self.fileType())) - \(self.name())】文件 \"\(fName)\"文档无法打开!\n",
  147. attributes:[.foregroundColor : NSColor.red]))
  148. }else if (status == -3) {
  149. self.reportString?.append(NSMutableAttributedString.init(string: "【\(String(self.fileType())) - \(self.name())】文件 \"\(fName)\"转档中 Crash!\n",
  150. attributes:[.foregroundColor : NSColor.red]))
  151. }
  152. let index = self.testFiles.index(of: fileName);
  153. if (index != NSNotFound) {
  154. self.compareProgress = Double(index) / Double(self.testFiles.count)
  155. }
  156. self.compareFinishedFiles.add(fileName);
  157. self.testlog("对比完成:"+fileName, (self.compareProgress + self.convertProgress)/2.0)
  158. fileIndex += 1
  159. convertFileBlock(files);
  160. }
  161. }
  162. }
  163. convertFileBlock(files);
  164. }
  165. ///Compare
  166. /// Tools
  167. func appendErrorInfo(_ skipString:NSString, failString: NSString) {
  168. if skipString.length > 0 && failString.length > 0 {
  169. reportString?.append(NSMutableAttributedString.init(string: "对比字符串【\(skipString)】错识别为【\(failString)】\n",
  170. attributes:[.foregroundColor : NSColor.red]))
  171. }else if (skipString.length > 0) {
  172. reportString?.append(NSMutableAttributedString.init(string: "对比字符串【\(skipString)】未识别到\n",
  173. attributes:[.foregroundColor : NSColor.red]))
  174. }else if failString.length > 0 {
  175. reportString?.append(NSMutableAttributedString.init(string: "字符串【\(failString)】识别出错\n",
  176. attributes:[.foregroundColor : NSColor.red]))
  177. }
  178. }
  179. func attributeStringWith(_ skipString:NSString, failString: NSString) -> NSAttributedString {
  180. if skipString.length > 0 && failString.length > 0 {
  181. let strikethroughStyle = NSParagraphStyle.init()
  182. let attString = NSMutableAttributedString.init(string: skipString as String,
  183. attributes:[.foregroundColor : NSColor.red,
  184. .strikethroughStyle:NSNumber(integerLiteral: NSUnderlineStyle.single.rawValue),
  185. ])
  186. attString.append(NSMutableAttributedString.init(string: failString as String,
  187. attributes:[.foregroundColor : NSColor.blue,
  188. ]))
  189. return attString
  190. }else if (skipString.length > 0) {
  191. let strikethroughStyle = NSParagraphStyle.init()
  192. let attString = NSMutableAttributedString.init(string: skipString as String,
  193. attributes:[.foregroundColor : NSColor.red,
  194. .strikethroughStyle:NSNumber(integerLiteral: NSUnderlineStyle.single.rawValue),
  195. ])
  196. return attString
  197. }else if failString.length > 0 {
  198. let strikethroughStyle = NSParagraphStyle.init()
  199. let attString = NSMutableAttributedString.init(string: failString as String,
  200. attributes:[.foregroundColor : NSColor.blue,
  201. ])
  202. return attString
  203. }
  204. return NSAttributedString()
  205. }
  206. func replaceUnicodeString(_ string:NSString) -> NSString {//中
  207. let items = string.components(separatedBy: "\\u") as [NSString]
  208. var resultString = NSString()
  209. for item in items {
  210. if (item.contains("?")) {
  211. let unicodeValue = item.intValue
  212. let skipRange = item.range(of: "?")
  213. let nextString = item.substring(from: Int(skipRange.location + skipRange.length)) as NSString
  214. let bytes : [UInt8] = [UInt8(unicodeValue/256),UInt8(unicodeValue%256)]
  215. let data = NSData.init(bytes: bytes, length: 2)
  216. let unicodeString = NSString.init(data: data as Data, encoding: NSUnicodeStringEncoding)! as NSString
  217. resultString = resultString.appending(String("\(unicodeString)\(nextString)")) as NSString
  218. }else {
  219. resultString = resultString.appending(String(item)) as NSString
  220. }
  221. }
  222. return resultString
  223. }
  224. /// Compare
  225. func compareString(_ check:NSString, result:NSString, callback:@escaping (_ appAttr:NSAttributedString)->()) -> Double {
  226. // func compareString(_ check:NSString, result:NSString, failure:@escaping (_ skipString:NSString, _ failString:NSString)->()) -> Double {
  227. return autoreleasepool {
  228. var checkString = check
  229. var resultStr = result
  230. var maxSize = checkString.length
  231. var successCount = 0;
  232. resultStr = resultStr.replacingOccurrences(of: "\n", with: "") as NSString
  233. resultStr = resultStr.replacingOccurrences(of: " ", with: "") as NSString
  234. /**
  235. (A0 = B0)
  236. - A-1 & B-1
  237. (A0 != B0) & (A0 in B) & (B0 in A)
  238. - 取 A0,B0最小 Range 值(裁剪区域比较小时)
  239. - 字符串裁剪对齐
  240. - 取 A0,B0最小 Range 值中字符顺序出现大的值(裁剪区域比较大时,先找出顺序最大序列,删除最小序列首字符)
  241. - 字符串裁剪首字符
  242. (A0 != B0) & (A0 in B)
  243. - 存储B0到识别错误缓存
  244. (A0 != B0) & (B0 in A)
  245. - 存储 A0到识别遗漏字符串
  246. (A0 != B0)
  247. - 分别存储 A0、B0到遗漏及错误字串
  248. */
  249. var skipString = NSString()
  250. var failString = NSString()
  251. while (checkString.length > 0 && resultStr.length > 0) {
  252. let subc = checkString.substring(to: 1) as NSString
  253. let subr = resultStr.substring(to: 1) as NSString
  254. let cRange = checkString.range(of: subr as String)
  255. let rRange = resultStr.range(of: subc as String)
  256. if subc.isEqual(to: subr) { // (A0 = B0)
  257. // Check Success
  258. // 两个字符相同
  259. callback(attributeStringWith(skipString, failString: failString))
  260. // failure(skipString, failString)
  261. // self.appendErrorInfo(skipString, failString: failString)
  262. skipString = NSString()
  263. failString = NSString()
  264. checkString = checkString.substring(from:1) as NSString
  265. resultStr = resultStr.substring(from:1) as NSString
  266. successCount = successCount + 1
  267. callback(NSAttributedString(string: subc as String))
  268. }else if (["\n", "\r", " "].contains(subc)) {
  269. // 两个字符不相同,但 CheckString 首字符 为 空格或回车
  270. callback(NSAttributedString(string: subc as String))
  271. maxSize -= 1;
  272. checkString = checkString.substring(from:1) as NSString
  273. }else if (cRange.location != NSNotFound &&
  274. rRange.location != NSNotFound) {
  275. // 两个字符均出现在另外一个字符 串中
  276. if min(cRange.location, rRange.location) >= 10 {
  277. // let pc = checkString.substring(with: NSMakeRange(0, min(checkString.length, cRange.location)))
  278. // let pr = resultStr.substring(with: NSMakeRange(0, min(resultStr.length, rRange.location)))
  279. // NSLog("C(\(cCount)):%.2f%%:\(pc)", cdegree)
  280. // NSLog("R(\(rCount)):%.2f%%:\(pr)", rdegree)
  281. if (cRange.location > rRange.location*3) {
  282. //‘subc' 字符串有在‘resultStr’中,但'subr'不在’checkString‘中,resultStr 往后推一
  283. failString = failString.appending(subr as String) as NSString
  284. resultStr = resultStr.substring(from:1) as NSString
  285. }else if (cRange.location*3 < rRange.location) {
  286. //‘subc' 字符串有在‘resultStr’中,但'subr'不在’checkString‘中,resultStr 往后推一
  287. skipString = skipString.appending(subc as String) as NSString
  288. checkString = checkString.substring(from:1) as NSString
  289. }else {
  290. let checkSubString = checkString.substring(with: NSMakeRange(0, cRange.location))
  291. let cCount = checkCountIn(checkSubString as NSString, inStr: resultStr);
  292. let rCount = checkCountIn(resultStr.substring(with: NSMakeRange(0, rRange.location)) as NSString, inStr: checkString)
  293. let cdegree = Float(cCount) / Float(cRange.location)
  294. let rdegree = Float(rCount) / Float(rRange.location)
  295. if (cdegree > 0.2) {
  296. //‘subc' 字符串有在‘resultStr’中,但'subr'不在’checkString‘中,resultStr 往后推一
  297. failString = failString.appending(subr as String) as NSString
  298. resultStr = resultStr.substring(from:1) as NSString
  299. }else if (rdegree > 0.2) {
  300. //‘subr' 字符串有在‘checkString’中,但'subc'不在’checkString‘中,checkString 往后推一
  301. skipString = skipString.appending(subc as String) as NSString
  302. checkString = checkString.substring(from:1) as NSString
  303. } else if (cdegree > rdegree * 2.0) {
  304. //‘subc' 字符串有在‘resultStr’中,但'subr'不在’checkString‘中,resultStr 往后推一
  305. failString = failString.appending(subr as String) as NSString
  306. resultStr = resultStr.substring(from:1) as NSString
  307. }else if (cdegree * 2.0 < rdegree) {
  308. //‘subr' 字符串有在‘checkString’中,但'subc'不在’checkString‘中,checkString 往后推一
  309. skipString = skipString.appending(subc as String) as NSString
  310. checkString = checkString.substring(from:1) as NSString
  311. }else if (cCount < rCount) {
  312. //‘subc' 字符串有在‘resultStr’中,但'subr'不在’checkString‘中,resultStr 往后推一
  313. failString = failString.appending(subr as String) as NSString
  314. resultStr = resultStr.substring(from:1) as NSString
  315. }else {
  316. //‘subr' 字符串有在‘checkString’中,但'subc'不在’checkString‘中,checkString 往后推一
  317. skipString = skipString.appending(subc as String) as NSString
  318. checkString = checkString.substring(from:1) as NSString
  319. }
  320. }
  321. }else if min(cRange.location, rRange.location) >= 2 {
  322. // 首部字符在对方字串中位置偏移最小值 大于 2
  323. var scale = (resultStr.length > 0) ? (Float(checkString.length) / Float(resultStr.length)) : Float(1.0)//, Float(1.0))
  324. let nextc = checkString.substring(with: NSRange(location: 1, length: 1)) as NSString
  325. let nextr = resultStr.substring(with: NSRange(location: 1, length: 1)) as NSString
  326. var ncRange = checkString.range(of: nextr as String)
  327. var nrRange = resultStr.range(of: nextc as String)
  328. if nrRange.location == NSNotFound {
  329. nrRange.location = 100000;
  330. }
  331. if ncRange.location == NSNotFound {
  332. ncRange.location = 100000;
  333. }
  334. if (min(nrRange.location, ncRange.location) < min(cRange.location, rRange.location)) {
  335. // 第二位字符,在对方字串中位置偏移最小值小于 首字符偏移
  336. if ncRange.location < Int(Float(nrRange.location) * scale) {
  337. //‘subr' 字符串有在‘checkString’ 偏移 小于'subc'在’checkString‘中 的偏移,优先移除checkString第一位
  338. skipString = skipString.appending(subc as String) as NSString
  339. checkString = checkString.substring(from:1) as NSString
  340. }else {
  341. //‘subr' 字符串有在‘checkString’ 偏移 不小于'subc'在’checkString‘中 的偏移,优先移除resultStr第一位
  342. failString = failString.appending(subr as String) as NSString
  343. resultStr = resultStr.substring(from:1) as NSString
  344. }
  345. }else if (cRange.location < Int(Float(rRange.location) * scale)) {
  346. //‘subr' 字符串有在‘checkString’ 偏移 小于'subc'在’checkString‘中 的偏移,优先移除checkString第一位
  347. skipString = skipString.appending(subc as String) as NSString
  348. checkString = checkString.substring(from:1) as NSString
  349. }else {
  350. //‘subr' 字符串有在‘checkString’ 偏移 不小于'subc'在’checkString‘中 的偏移,优先移除resultStr第一位
  351. failString = failString.appending(subr as String) as NSString
  352. resultStr = resultStr.substring(from:1) as NSString
  353. }
  354. }else {
  355. // var scale = (skipString.length > 0) ? (Float(checkString.length) / Float(skipString.length)) : Float(1.0)
  356. // if (checkString.length > skipString.length && cRange.location <= Int(Float(rRange.location)*scale)) {
  357. // //‘subc' 字符串有在‘resultStr’中,但'subr'不在’checkString‘中,resultStr 往后推一
  358. // skipString = skipString.appending(subc as String) as NSString
  359. // checkString = checkString.substring(from:1) as NSString
  360. // }else if (checkString.length <= skipString.length && cRange.location > Int(Float(rRange.location)*scale)) {
  361. // failString = failString.appending(subr as String) as NSString
  362. // resultStr = resultStr.substring(from:1) as NSString
  363. // }else
  364. if (cRange.location < rRange.location) {
  365. //‘subr' 字符串有在‘checkString’ 偏移 小于'subc'在’checkString‘中 的偏移,优先移除checkString第一位
  366. skipString = skipString.appending(subc as String) as NSString
  367. checkString = checkString.substring(from:1) as NSString
  368. }else {
  369. //‘subr' 字符串有在‘checkString’ 偏移 不小于'subc'在’checkString‘中 的偏移,优先移除resultStr第一位
  370. failString = failString.appending(subr as String) as NSString
  371. resultStr = resultStr.substring(from:1) as NSString
  372. }
  373. }
  374. }else if (cRange.location != NSNotFound) {
  375. // let checkSubString = checkString.substring(with: cRange)
  376. // if (checkCountIn(checkSubString as NSString, inStr: resultStr) < Int(Float(cRange.location) * 0.6)) {
  377. //‘subc' 字符串有在‘resultStr’中,但'subr'不在’checkString‘中,resultStr 往后推一
  378. skipString = skipString.appending(subc as String) as NSString
  379. checkString = checkString.substring(from:1) as NSString
  380. // }else {
  381. // failString = failString.appending(subr as String) as NSString
  382. // resultStr = resultStr.substring(from:1) as NSString
  383. // }
  384. }else if (rRange.location != NSNotFound) {
  385. // let resultSubString = resultStr.substring(with: rRange)
  386. // if (checkCountIn(resultSubString as NSString, inStr: checkString) < Int(Float(rRange.location) * 0.5)) {
  387. //‘subc' 字符串有在‘resultStr’中,但'subr'不在’checkString‘中,resultStr 往后推一
  388. failString = failString.appending(subr as String) as NSString
  389. resultStr = resultStr.substring(from:1) as NSString
  390. // }else {
  391. // skipString = skipString.appending(subc as String) as NSString
  392. // checkString = checkString.substring(from:1) as NSString
  393. // }
  394. }else {
  395. // 两个子字串均未找到
  396. skipString = skipString.appending(subc as String) as NSString
  397. failString = failString.appending(subr as String) as NSString
  398. checkString = checkString.substring(from:1) as NSString
  399. resultStr = resultStr.substring(from:1) as NSString
  400. }
  401. }
  402. skipString = skipString.appending(checkString as String) as NSString
  403. failString = failString.appending(resultStr as String) as NSString
  404. // failure(skipString, failString)
  405. callback(attributeStringWith(skipString, failString: failString))
  406. callback(NSAttributedString(string: "\n"))
  407. let degree = (maxSize>1) ? Double(Float(successCount)/Float(maxSize) * 100) : 0
  408. return degree
  409. }
  410. }
  411. func checkCountIn(_ subStr:NSString, inStr:NSString) -> Int {
  412. let countInfo = NSMutableArray()
  413. for i in 0...(subStr.length - 3) {
  414. let tStr = subStr.substring(with: NSMakeRange(i, 3))
  415. let range = inStr.range(of: tStr)
  416. if (range.location != NSNotFound) {
  417. countInfo.add(range.location)
  418. }
  419. }
  420. return findLISLength(countInfo as! [Int]);
  421. }
  422. func findLISLength(_ nums: [Int]) -> Int {
  423. let n = nums.count
  424. if n == 0 {
  425. return 0
  426. }
  427. var dp = Array(repeating: 1, count: n)
  428. var maxLen = 1
  429. for i in 1 ..< n {
  430. for j in 0 ..< i {
  431. if nums[i] > nums[j] {
  432. dp[i] = max(dp[i], dp[j] + 1)
  433. }
  434. }
  435. maxLen = max(maxLen, dp[i])
  436. }
  437. return maxLen
  438. }
  439. // Read File
  440. func readTextFile(_ filePath:NSString) -> String? {
  441. if NSArray(array: ["TXT", "txt"]).contains(filePath.pathExtension) {
  442. var checkString = try? NSString.init(contentsOfFile: filePath as String, encoding: NSUTF8StringEncoding)
  443. if (checkString != nil) {
  444. // checkString = checkString!.replacingOccurrences(of: "\n", with: "") as NSString
  445. // checkString = checkString!.replacingOccurrences(of: " ", with: "") as NSString
  446. return checkString! as String
  447. }
  448. return nil
  449. }else if NSArray(array: ["rtf", "RTF"]).contains(filePath.pathExtension) {
  450. // Load check file
  451. let checkData = NSData.init(contentsOfFile: filePath as String) as! Data
  452. var documentAttributes:NSDictionary!
  453. let checkAttString = NSAttributedString.init(rtf: checkData, documentAttributes: &documentAttributes)
  454. var checkString = NSString(string: checkAttString!.string) as NSString
  455. var pureString = checkString.replacingOccurrences(of: "\n", with: "") as NSString
  456. pureString = pureString.replacingOccurrences(of: " ", with: "") as NSString
  457. // 常规 rtf 读取失败
  458. //使用框排进行读取
  459. if (pureString.length > 0) {
  460. return checkString as String?
  461. }
  462. var resultString = try? NSString.init(contentsOfFile: filePath as String, encoding: NSUTF8StringEncoding)
  463. if (nil != resultString && !resultString!.contains("\\shptxt\\shptxt")) {
  464. resultString = resultString!.replacingOccurrences(of: "\n", with: "") as NSString
  465. resultString = resultString!.replacingOccurrences(of: " ", with: "") as NSString
  466. return resultString! as String
  467. }
  468. //识别字符串 \shptxt\shptxt ... }
  469. let pageInfoStrings = resultString!.components(separatedBy: "\\shptxt\\shptxt") as NSArray
  470. var finalString = ""
  471. if pageInfoStrings.count > 0 {
  472. let subStrings = pageInfoStrings.subarray(with: NSMakeRange(1, Int(pageInfoStrings.count - 1))) as! [String]
  473. for pageInfoString in subStrings {
  474. let endRange = NSString(string: pageInfoString).range(of: "}")
  475. finalString = finalString.appending(NSString(string: pageInfoString).substring(to: endRange.location))
  476. }
  477. }
  478. //识别所有 【空格 ~ \】 之间的值,并进行缝合
  479. // Detect all strings between Spaces and \ and stitch
  480. let strings = finalString.components(separatedBy: " ")
  481. var resultStr = "" as NSString
  482. for str in strings {
  483. let markStr = str as NSString
  484. if (markStr.contains("\\f")) {
  485. let fRange = markStr.range(of: "\\f")
  486. let cRange = markStr.range(of: "\\c")
  487. let bRange = markStr.range(of: "\\b")
  488. let iRange = markStr.range(of: "\\i")
  489. let eRange = markStr.range(of: "\\e")
  490. let pRange = markStr.range(of: "\\p")
  491. let minPos = min(Int(fRange.location),
  492. Int(cRange.location),
  493. Int(bRange.location),
  494. Int(iRange.location),
  495. Int(eRange.location),
  496. Int(pRange.location))
  497. resultStr = resultStr.appending(markStr.substring(to: minPos)) as NSString
  498. }else {
  499. resultStr = resultStr.appending(markStr as String) as NSString
  500. }
  501. }
  502. resultStr = self.replaceUnicodeString(resultStr)
  503. resultStr = resultStr.replacingOccurrences(of: "\n", with: "") as NSString
  504. resultStr = resultStr.replacingOccurrences(of: " ", with: "") as NSString
  505. resultStr = resultStr.replacingOccurrences(of: "\\pard", with: "") as NSString
  506. resultStr = resultStr.replacingOccurrences(of: "\\par", with: "") as NSString
  507. return resultStr as String?
  508. }
  509. return nil
  510. }
  511. override func compareFiles() -> NSArray? {
  512. let items = NSMutableArray()
  513. let files = DataModel.shared.originFilesFor(_fileType, type: _type) as [String]
  514. for fileName in files {
  515. let sItems = compareFiles(fileName)
  516. if sItems != nil && sItems!.count != 0 {
  517. items.addObjects(from: sItems as! [Any])
  518. }
  519. }
  520. return items
  521. }
  522. override func compareFiles(_ fileName: String) -> NSArray? {
  523. let files = NSMutableArray()
  524. let checkDirectory = self.checkFileDirectory()
  525. let resultDirectory = self.resultFileDirectory()
  526. let nName = NSString(string: fileName).deletingPathExtension.appending(".\(self.extention())")
  527. let rComparePath = NSString(string: resultDirectory).appendingPathComponent(nName)
  528. let cComparePath = NSString(string: checkDirectory).appendingPathComponent(nName)
  529. if (FileManager.default.fileExists(atPath: rComparePath) &&
  530. FileManager.default.fileExists(atPath: rComparePath+".rtf")) {
  531. let fileInfo = NSMutableDictionary.fileInfoWith(fileName,
  532. refFilePath: nil,
  533. resultPath: rComparePath,
  534. comparePath: cComparePath,
  535. objc: self)
  536. files.add(fileInfo)
  537. }
  538. return files
  539. }
  540. /**
  541. Replace the refrence image for next image check test
  542. */
  543. override func canUpdateRefImage() -> Bool {
  544. return false
  545. }
  546. override func updateRefImage() {
  547. }
  548. override func canUpdateRefImage(_ fileName:String) -> Bool {
  549. return false
  550. }
  551. override func updateRefImage(_ fileName:String) {
  552. }
  553. }