utilities.ts 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. import React from "react";
  2. import MdTpl from "./MdTpl";
  3. import { WdCtl } from "./Wd";
  4. import { Divider } from "antd";
  5. import { roman_to_my, my_to_roman } from "../code/my";
  6. import { roman_to_si } from "../code/si";
  7. import { roman_to_thai } from "../code/thai";
  8. import { roman_to_taitham } from "../code/tai-tham";
  9. import ParserError from "../general/ParserError";
  10. export type TCodeConvertor =
  11. | "none"
  12. | "roman"
  13. | "roman_to_my"
  14. | "my_to_roman"
  15. | "roman_to_thai"
  16. | "roman_to_taitham"
  17. | "roman_to_si";
  18. export function XmlToReact(
  19. text: string,
  20. wordWidget: boolean = false,
  21. convertor?: TCodeConvertor
  22. ): React.ReactNode[] | undefined {
  23. //console.log("html string:", text);
  24. const parser = new DOMParser();
  25. const xmlDoc = parser.parseFromString(
  26. `<body>${text}</body>`,
  27. "application/xml"
  28. );
  29. const x = xmlDoc.documentElement;
  30. //console.log("解析成功", x);
  31. return convert(x, wordWidget, convertor);
  32. function getAttr(node: ChildNode, key: number): Object {
  33. const ele = node as Element;
  34. const attr = ele.attributes;
  35. let output: any = { key: key };
  36. for (let i = 0; i < attr.length; i++) {
  37. if (attr[i].nodeType === 2) {
  38. let key: string = attr[i].nodeName;
  39. if (key !== "style") {
  40. output[key] = attr[i].nodeValue;
  41. } else {
  42. //TODO 把css style 转换为react style
  43. }
  44. }
  45. }
  46. return output;
  47. }
  48. function convert(
  49. node: ChildNode,
  50. wordWidget: boolean = false,
  51. convertor?: TCodeConvertor
  52. ): React.ReactNode[] | undefined {
  53. let output: React.ReactNode[] = [];
  54. for (let i = 0; i < node.childNodes.length; i++) {
  55. const value = node.childNodes[i];
  56. //console.log(value.nodeName, value.nodeType, value.nodeValue);
  57. switch (value.nodeType) {
  58. case 1: //element node
  59. //console.log("tag name", value.nodeName);
  60. const tagName = value.nodeName;
  61. switch (tagName) {
  62. case "parsererror":
  63. output.push(
  64. React.createElement(
  65. ParserError,
  66. getAttr(value, i),
  67. convert(value, wordWidget, convertor)
  68. )
  69. );
  70. break;
  71. case "MdTpl":
  72. output.push(
  73. React.createElement(
  74. MdTpl,
  75. getAttr(value, i),
  76. convert(value, wordWidget, convertor)
  77. )
  78. );
  79. break;
  80. case "hr":
  81. output.push(
  82. React.createElement(
  83. Divider,
  84. getAttr(value, i),
  85. convert(value, wordWidget, convertor)
  86. )
  87. );
  88. break;
  89. case "param":
  90. output.push(
  91. React.createElement(
  92. "span",
  93. getAttr(value, i),
  94. convert(value, wordWidget, convertor)
  95. )
  96. );
  97. break;
  98. default:
  99. output.push(
  100. React.createElement(
  101. tagName,
  102. getAttr(value, i),
  103. convert(value, wordWidget, convertor)
  104. )
  105. );
  106. break;
  107. }
  108. break;
  109. case 2: //attribute node
  110. return [];
  111. case 3: //text node
  112. let textValue = value.nodeValue ? value.nodeValue : undefined;
  113. //编码转换
  114. if (typeof convertor !== "undefined" && textValue !== null) {
  115. switch (convertor) {
  116. case "roman_to_my":
  117. textValue = roman_to_my(textValue);
  118. break;
  119. case "my_to_roman":
  120. textValue = my_to_roman(textValue);
  121. break;
  122. case "roman_to_si":
  123. textValue = roman_to_si(textValue);
  124. break;
  125. case "roman_to_thai":
  126. textValue = roman_to_thai(textValue);
  127. break;
  128. case "roman_to_taitham":
  129. textValue = roman_to_taitham(textValue);
  130. break;
  131. }
  132. }
  133. if (wordWidget) {
  134. //将单词按照空格拆开。用组件包裹
  135. const wordList = textValue?.split(" ");
  136. const wordWidget = wordList?.map((word, id) => {
  137. const prop: any = { key: id, text: word };
  138. return React.createElement(WdCtl, prop);
  139. });
  140. output.push(wordWidget);
  141. } else {
  142. output.push(textValue);
  143. }
  144. break;
  145. case 8:
  146. return [];
  147. case 9:
  148. return [];
  149. }
  150. }
  151. if (output.length > 0) {
  152. return output;
  153. } else {
  154. return undefined;
  155. }
  156. }
  157. }