|
@@ -1,261 +1,256 @@
|
|
|
// import { isSpecialMark, isSpeedKeyword, isGradientWords, GRADIENT_SPEED_RESET_TAG } from "./speed-tag"
|
|
|
|
|
|
-
|
|
|
// import { isSpecialMark, isSpeedKeyword, isGradientWords, GRADIENT_SPEED_RESET_TAG } from "./speed-tag"
|
|
|
|
|
|
export class StringUtil {
|
|
|
- public static StringContainsSeparatedWord(str: string, wordRegExString: string, ignoreCase = false): boolean {
|
|
|
- const regExp = new RegExp("( |^)" + wordRegExString + "([ .]|$)", ignoreCase ? "i" : undefined)
|
|
|
- return regExp.test(str)
|
|
|
- }
|
|
|
+ public static StringContainsSeparatedWord(str: string, wordRegExString: string, ignoreCase = false): boolean {
|
|
|
+ const regExp = new RegExp("( |^)" + wordRegExString + "([ .]|$)", ignoreCase ? "i" : undefined)
|
|
|
+ return regExp.test(str)
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
export const formatXML = (xml: string): string => {
|
|
|
- if (!xml) return ""
|
|
|
- const xmlParse = new DOMParser().parseFromString(xml, "text/xml")
|
|
|
- const measures: any = xmlParse.getElementsByTagName("measure")
|
|
|
- // const repeats: any = Array.from(xmlParse.querySelectorAll('repeat'))
|
|
|
- // 处理重复小节信息
|
|
|
- // let speed = -1
|
|
|
- let beats = -1
|
|
|
- let beatType = -1
|
|
|
- // 小节中如果没有节点默认为休止符
|
|
|
- for (const measure of measures) {
|
|
|
- if (beats === -1 && measure.getElementsByTagName("beats").length) {
|
|
|
- beats = parseInt(measure.getElementsByTagName("beats")[0].textContent || "4")
|
|
|
- }
|
|
|
- if (beatType === -1 && measure.getElementsByTagName("beat-type").length) {
|
|
|
- beatType = parseInt(measure.getElementsByTagName("beat-type")[0].textContent || "4")
|
|
|
- }
|
|
|
- // if (speed === -1 && measure.getElementsByTagName('per-minute').length) {
|
|
|
- // speed = parseInt(measure.getElementsByTagName('per-minute')[0].textContent || this.firstLib?.speed)
|
|
|
- // }
|
|
|
- const divisions = parseInt(measure.getElementsByTagName("divisions")[0]?.textContent || "256")
|
|
|
- if (measure.getElementsByTagName("note").length === 0) {
|
|
|
- const forwardTimeElement = measure.getElementsByTagName("forward")[0]?.getElementsByTagName("duration")[0]
|
|
|
- if (forwardTimeElement) {
|
|
|
- forwardTimeElement.textContent = "0"
|
|
|
+ if (!xml) return ""
|
|
|
+ const xmlParse = new DOMParser().parseFromString(xml, "text/xml")
|
|
|
+ const measures: any = xmlParse.getElementsByTagName("measure")
|
|
|
+ // const repeats: any = Array.from(xmlParse.querySelectorAll('repeat'))
|
|
|
+ // 处理重复小节信息
|
|
|
+ // let speed = -1
|
|
|
+ let beats = -1
|
|
|
+ let beatType = -1
|
|
|
+ // 小节中如果没有节点默认为休止符
|
|
|
+ for (const measure of measures) {
|
|
|
+ if (beats === -1 && measure.getElementsByTagName("beats").length) {
|
|
|
+ beats = parseInt(measure.getElementsByTagName("beats")[0].textContent || "4")
|
|
|
+ }
|
|
|
+ if (beatType === -1 && measure.getElementsByTagName("beat-type").length) {
|
|
|
+ beatType = parseInt(measure.getElementsByTagName("beat-type")[0].textContent || "4")
|
|
|
}
|
|
|
- measure.innerHTML =
|
|
|
- measure.innerHTML +
|
|
|
- `
|
|
|
+ // if (speed === -1 && measure.getElementsByTagName('per-minute').length) {
|
|
|
+ // speed = parseInt(measure.getElementsByTagName('per-minute')[0].textContent || this.firstLib?.speed)
|
|
|
+ // }
|
|
|
+ const divisions = parseInt(measure.getElementsByTagName("divisions")[0]?.textContent || "256")
|
|
|
+ if (measure.getElementsByTagName("note").length === 0) {
|
|
|
+ const forwardTimeElement = measure.getElementsByTagName("forward")[0]?.getElementsByTagName("duration")[0]
|
|
|
+ if (forwardTimeElement) {
|
|
|
+ forwardTimeElement.textContent = "0"
|
|
|
+ }
|
|
|
+ measure.innerHTML =
|
|
|
+ measure.innerHTML +
|
|
|
+ `
|
|
|
<note>
|
|
|
<rest measure="yes"/>
|
|
|
<duration>${divisions * beats}</duration>
|
|
|
<voice>1</voice>
|
|
|
<type>whole</type>
|
|
|
</note>`
|
|
|
- }
|
|
|
- }
|
|
|
- return new XMLSerializer().serializeToString(xmlParse)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return new XMLSerializer().serializeToString(xmlParse)
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-
|
|
|
export const onlyVisible = (xml: string, partIndex: number): string => {
|
|
|
- if (!xml) return ""
|
|
|
- const xmlParse = new DOMParser().parseFromString(xml, "text/xml")
|
|
|
- const partList = xmlParse.getElementsByTagName("part-list")?.[0]?.getElementsByTagName("score-part") || []
|
|
|
- const partListNames = Array.from(partList).map((item) => item.getElementsByTagName("part-name")?.[0].textContent || "")
|
|
|
- const parts: any = xmlParse.getElementsByTagName("part")
|
|
|
- // const firstTimeInfo = parts[0]?.getElementsByTagName('metronome')[0]?.parentElement?.parentElement?.cloneNode(true)
|
|
|
- const part: any = parts[0]
|
|
|
- const firstMeasures = [...part.getElementsByTagName("measure")]
|
|
|
- const metronomes = [...part.getElementsByTagName("metronome")]
|
|
|
- const words = [...part.getElementsByTagName("words")]
|
|
|
- const codas = [...part.getElementsByTagName("coda")]
|
|
|
- const rehearsals = [...part.getElementsByTagName("rehearsal")]
|
|
|
+ if (!xml) return ""
|
|
|
+ const xmlParse = new DOMParser().parseFromString(xml, "text/xml")
|
|
|
+ const partList = xmlParse.getElementsByTagName("part-list")?.[0]?.getElementsByTagName("score-part") || []
|
|
|
+ const partListNames = Array.from(partList).map(item => item.getElementsByTagName("part-name")?.[0].textContent || "")
|
|
|
+ const parts: any = xmlParse.getElementsByTagName("part")
|
|
|
+ // const firstTimeInfo = parts[0]?.getElementsByTagName('metronome')[0]?.parentElement?.parentElement?.cloneNode(true)
|
|
|
+ const part: any = parts[0]
|
|
|
+ const firstMeasures = [...part.getElementsByTagName("measure")]
|
|
|
+ const metronomes = [...part.getElementsByTagName("metronome")]
|
|
|
+ // const words = [...part.getElementsByTagName("words")]
|
|
|
+ // const codas = [...part.getElementsByTagName("coda")]
|
|
|
+ // const rehearsals = [...part.getElementsByTagName("rehearsal")]
|
|
|
|
|
|
- /** 第一分谱如果是约定的配置分谱则跳过 */
|
|
|
- if (partListNames[0]?.toLocaleUpperCase?.() === "COMMON") {
|
|
|
- partIndex++
|
|
|
- partListNames.shift()
|
|
|
- }
|
|
|
- const visiblePartInfo = partList[partIndex]
|
|
|
- // console.log(visiblePartInfo, partIndex)
|
|
|
- if (visiblePartInfo) {
|
|
|
- const id = visiblePartInfo.getAttribute("id")
|
|
|
- Array.from(parts).forEach((part: any) => {
|
|
|
- if (part && part.getAttribute("id") !== id) {
|
|
|
- part.parentNode?.removeChild(part)
|
|
|
- // 不等于第一行才添加避免重复添加
|
|
|
- } else if (part && part.getAttribute("id") !== "P1") {
|
|
|
- // 速度标记仅保留最后一个
|
|
|
- const metronomeData: {
|
|
|
- [key in string]: Element
|
|
|
- } = {}
|
|
|
- for (let i = 0; i < metronomes.length; i++) {
|
|
|
- const metronome = metronomes[i]
|
|
|
- const metronomeContainer = metronome.parentElement?.parentElement?.parentElement
|
|
|
- if (metronomeContainer) {
|
|
|
- const index = firstMeasures.indexOf(metronomeContainer)
|
|
|
- metronomeData[index] = metronome
|
|
|
- }
|
|
|
- }
|
|
|
- Object.values(metronomeData).forEach((metronome) => {
|
|
|
- const metronomeContainer: any = metronome.parentElement?.parentElement
|
|
|
- const parentMeasure: any = metronomeContainer?.parentElement
|
|
|
- const measureMetronomes = [...(parentMeasure?.childNodes || [])]
|
|
|
- const metronomesIndex = metronomeContainer ? measureMetronomes.indexOf(metronomeContainer) : -1
|
|
|
- // console.log(parentMeasure)
|
|
|
- if (parentMeasure && metronomesIndex > -1) {
|
|
|
- const index = firstMeasures.indexOf(parentMeasure)
|
|
|
- const activeMeasure = part.getElementsByTagName("measure")[index]
|
|
|
- setElementNoteBefore(metronomeContainer, parentMeasure, activeMeasure)
|
|
|
- // console.log(measureMetronomes, metronomesIndex, activeMeasure?.childNodes, activeMeasure?.childNodes[metronomesIndex])
|
|
|
- // activeMeasure?.insertBefore(metronomeContainer.cloneNode(true), activeMeasure?.childNodes[metronomesIndex])
|
|
|
- // // part.getElementsByTagName('measure')[index]?.appendChild(metronomeContainer.cloneNode(true))
|
|
|
- // // console.log(index, parentMeasure, firstMeasures.indexOf(parentMeasure))
|
|
|
- }
|
|
|
- })
|
|
|
- /** word比较特殊需要精确到note位置 */
|
|
|
- // words.forEach((word) => {
|
|
|
- // let text = word.textContent || ""
|
|
|
- // text = ["cresc."].includes(text) ? "" : text
|
|
|
- // if ((isSpecialMark(text) || isSpeedKeyword(text) || isGradientWords(text) || isRepeatWord(text) || GRADIENT_SPEED_RESET_TAG) && text) {
|
|
|
- // const wordContainer = word.parentElement?.parentElement
|
|
|
- // const parentMeasure = wordContainer?.parentElement
|
|
|
- // const measureWords = [...(parentMeasure?.childNodes || [])]
|
|
|
- // const wordIndex = wordContainer ? measureWords.indexOf(wordContainer) : -1
|
|
|
- // if (wordContainer && parentMeasure && wordIndex > -1) {
|
|
|
- // const index = firstMeasures.indexOf(parentMeasure)
|
|
|
- // const activeMeasure = part.getElementsByTagName("measure")[index]
|
|
|
- // // 找当前小节是否包含word标签
|
|
|
- // const _words: any = Array.from(activeMeasure?.getElementsByTagName("words") || [])
|
|
|
- // // 遍历word标签,检查是否和第一小节重复,如果有重复则不平移word
|
|
|
- // const total = _words.reduce((total: any, _word) => {
|
|
|
- // if (_word.textContent?.includes(text)) {
|
|
|
- // total++
|
|
|
- // }
|
|
|
- // return total
|
|
|
- // }, 0)
|
|
|
- // if (total === 0) {
|
|
|
- // setElementNoteBefore(wordContainer, parentMeasure, activeMeasure)
|
|
|
+ /** 第一分谱如果是约定的配置分谱则跳过 */
|
|
|
+ if (partListNames[0]?.toLocaleUpperCase?.() === "COMMON") {
|
|
|
+ partIndex++
|
|
|
+ partListNames.shift()
|
|
|
+ }
|
|
|
+ const visiblePartInfo = partList[partIndex]
|
|
|
+ // console.log(visiblePartInfo, partIndex)
|
|
|
+ if (visiblePartInfo) {
|
|
|
+ const id = visiblePartInfo.getAttribute("id")
|
|
|
+ Array.from(parts).forEach((part: any) => {
|
|
|
+ if (part && part.getAttribute("id") !== id) {
|
|
|
+ part.parentNode?.removeChild(part)
|
|
|
+ // 不等于第一行才添加避免重复添加
|
|
|
+ } else if (part && part.getAttribute("id") !== "P1") {
|
|
|
+ // 速度标记仅保留最后一个
|
|
|
+ const metronomeData: {
|
|
|
+ [key in string]: Element
|
|
|
+ } = {}
|
|
|
+ for (let i = 0; i < metronomes.length; i++) {
|
|
|
+ const metronome = metronomes[i]
|
|
|
+ const metronomeContainer = metronome.parentElement?.parentElement?.parentElement
|
|
|
+ if (metronomeContainer) {
|
|
|
+ const index = firstMeasures.indexOf(metronomeContainer)
|
|
|
+ metronomeData[index] = metronome
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Object.values(metronomeData).forEach(metronome => {
|
|
|
+ const metronomeContainer: any = metronome.parentElement?.parentElement
|
|
|
+ const parentMeasure: any = metronomeContainer?.parentElement
|
|
|
+ const measureMetronomes = [...(parentMeasure?.childNodes || [])]
|
|
|
+ const metronomesIndex = metronomeContainer ? measureMetronomes.indexOf(metronomeContainer) : -1
|
|
|
+ // console.log(parentMeasure)
|
|
|
+ if (parentMeasure && metronomesIndex > -1) {
|
|
|
+ const index = firstMeasures.indexOf(parentMeasure)
|
|
|
+ const activeMeasure = part.getElementsByTagName("measure")[index]
|
|
|
+ setElementNoteBefore(metronomeContainer, parentMeasure, activeMeasure)
|
|
|
+ // console.log(measureMetronomes, metronomesIndex, activeMeasure?.childNodes, activeMeasure?.childNodes[metronomesIndex])
|
|
|
+ // activeMeasure?.insertBefore(metronomeContainer.cloneNode(true), activeMeasure?.childNodes[metronomesIndex])
|
|
|
+ // // part.getElementsByTagName('measure')[index]?.appendChild(metronomeContainer.cloneNode(true))
|
|
|
+ // // console.log(index, parentMeasure, firstMeasures.indexOf(parentMeasure))
|
|
|
+ }
|
|
|
+ })
|
|
|
+ /** word比较特殊需要精确到note位置 */
|
|
|
+ // words.forEach((word) => {
|
|
|
+ // let text = word.textContent || ""
|
|
|
+ // text = ["cresc."].includes(text) ? "" : text
|
|
|
+ // if ((isSpecialMark(text) || isSpeedKeyword(text) || isGradientWords(text) || isRepeatWord(text) || GRADIENT_SPEED_RESET_TAG) && text) {
|
|
|
+ // const wordContainer = word.parentElement?.parentElement
|
|
|
+ // const parentMeasure = wordContainer?.parentElement
|
|
|
+ // const measureWords = [...(parentMeasure?.childNodes || [])]
|
|
|
+ // const wordIndex = wordContainer ? measureWords.indexOf(wordContainer) : -1
|
|
|
+ // if (wordContainer && parentMeasure && wordIndex > -1) {
|
|
|
+ // const index = firstMeasures.indexOf(parentMeasure)
|
|
|
+ // const activeMeasure = part.getElementsByTagName("measure")[index]
|
|
|
+ // // 找当前小节是否包含word标签
|
|
|
+ // const _words: any = Array.from(activeMeasure?.getElementsByTagName("words") || [])
|
|
|
+ // // 遍历word标签,检查是否和第一小节重复,如果有重复则不平移word
|
|
|
+ // const total = _words.reduce((total: any, _word) => {
|
|
|
+ // if (_word.textContent?.includes(text)) {
|
|
|
+ // total++
|
|
|
+ // }
|
|
|
+ // return total
|
|
|
+ // }, 0)
|
|
|
+ // if (total === 0) {
|
|
|
+ // setElementNoteBefore(wordContainer, parentMeasure, activeMeasure)
|
|
|
|
|
|
- // }
|
|
|
- // }
|
|
|
- // }
|
|
|
- // })
|
|
|
- /** word比较特殊需要精确到note位置 */
|
|
|
- // codas.forEach((coda) => {
|
|
|
- // const wordContainer = coda.parentElement?.parentElement
|
|
|
- // const parentMeasure = wordContainer?.parentElement
|
|
|
- // const measureWords = [...(parentMeasure?.childNodes || [])]
|
|
|
- // const wordIndex = wordContainer ? measureWords.indexOf(wordContainer) : -1
|
|
|
- // if (wordContainer && parentMeasure && wordIndex > -1) {
|
|
|
- // const index = firstMeasures.indexOf(parentMeasure)
|
|
|
- // const activeMeasure = part.getElementsByTagName("measure")[index]
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // })
|
|
|
+ /** word比较特殊需要精确到note位置 */
|
|
|
+ // codas.forEach((coda) => {
|
|
|
+ // const wordContainer = coda.parentElement?.parentElement
|
|
|
+ // const parentMeasure = wordContainer?.parentElement
|
|
|
+ // const measureWords = [...(parentMeasure?.childNodes || [])]
|
|
|
+ // const wordIndex = wordContainer ? measureWords.indexOf(wordContainer) : -1
|
|
|
+ // if (wordContainer && parentMeasure && wordIndex > -1) {
|
|
|
+ // const index = firstMeasures.indexOf(parentMeasure)
|
|
|
+ // const activeMeasure = part.getElementsByTagName("measure")[index]
|
|
|
|
|
|
- // setElementNoteBefore(wordContainer, parentMeasure, activeMeasure)
|
|
|
+ // setElementNoteBefore(wordContainer, parentMeasure, activeMeasure)
|
|
|
|
|
|
- // }
|
|
|
- // })
|
|
|
- // rehearsals.forEach((rehearsal) => {
|
|
|
- // const container = rehearsal.parentElement?.parentElement
|
|
|
- // const parentMeasure = container?.parentElement
|
|
|
- // // console.log(rehearsal)
|
|
|
- // if (parentMeasure) {
|
|
|
- // const index = firstMeasures.indexOf(parentMeasure)
|
|
|
- // part.getElementsByTagName("measure")[index]?.appendChild(container.cloneNode(true))
|
|
|
- // // console.log(index, parentMeasure, firstMeasures.indexOf(parentMeasure))
|
|
|
- // }
|
|
|
- // })
|
|
|
- } else {
|
|
|
- // words.forEach((word) => {
|
|
|
- // const text = word.textContent || ""
|
|
|
- // if (isSpeedKeyword(text) && text) {
|
|
|
- // const wordContainer = word.parentElement?.parentElement?.parentElement
|
|
|
- // if (wordContainer && wordContainer.firstElementChild && wordContainer.firstElementChild !== word) {
|
|
|
- // const wordParent = word.parentElement?.parentElement
|
|
|
- // const fisrt = wordContainer.firstElementChild
|
|
|
- // wordContainer.insertBefore(wordParent, fisrt)
|
|
|
- // }
|
|
|
- // }
|
|
|
- // })
|
|
|
- }
|
|
|
+ // }
|
|
|
+ // })
|
|
|
+ // rehearsals.forEach((rehearsal) => {
|
|
|
+ // const container = rehearsal.parentElement?.parentElement
|
|
|
+ // const parentMeasure = container?.parentElement
|
|
|
+ // // console.log(rehearsal)
|
|
|
+ // if (parentMeasure) {
|
|
|
+ // const index = firstMeasures.indexOf(parentMeasure)
|
|
|
+ // part.getElementsByTagName("measure")[index]?.appendChild(container.cloneNode(true))
|
|
|
+ // // console.log(index, parentMeasure, firstMeasures.indexOf(parentMeasure))
|
|
|
+ // }
|
|
|
+ // })
|
|
|
+ } else {
|
|
|
+ // words.forEach((word) => {
|
|
|
+ // const text = word.textContent || ""
|
|
|
+ // if (isSpeedKeyword(text) && text) {
|
|
|
+ // const wordContainer = word.parentElement?.parentElement?.parentElement
|
|
|
+ // if (wordContainer && wordContainer.firstElementChild && wordContainer.firstElementChild !== word) {
|
|
|
+ // const wordParent = word.parentElement?.parentElement
|
|
|
+ // const fisrt = wordContainer.firstElementChild
|
|
|
+ // wordContainer.insertBefore(wordParent, fisrt)
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // })
|
|
|
+ }
|
|
|
|
|
|
- // 最后一个小节的结束线元素不在最后 调整
|
|
|
- if (part && part.getAttribute("id") === id) {
|
|
|
- const barlines = part.getElementsByTagName("barline")
|
|
|
- const lastParent = barlines[barlines.length - 1]?.parentElement
|
|
|
- if (lastParent?.lastElementChild?.tagName !== "barline") {
|
|
|
- const children: any = lastParent?.children || []
|
|
|
- for (const el of children) {
|
|
|
- if (el.tagName === "barline") {
|
|
|
- // 将结束线元素放到最后
|
|
|
- lastParent?.appendChild(el)
|
|
|
- break
|
|
|
+ // 最后一个小节的结束线元素不在最后 调整
|
|
|
+ if (part && part.getAttribute("id") === id) {
|
|
|
+ const barlines = part.getElementsByTagName("barline")
|
|
|
+ const lastParent = barlines[barlines.length - 1]?.parentElement
|
|
|
+ if (lastParent?.lastElementChild?.tagName !== "barline") {
|
|
|
+ const children: any = lastParent?.children || []
|
|
|
+ for (const el of children) {
|
|
|
+ if (el.tagName === "barline") {
|
|
|
+ // 将结束线元素放到最后
|
|
|
+ lastParent?.appendChild(el)
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- })
|
|
|
- Array.from(partList).forEach((part) => {
|
|
|
- if (part && part.getAttribute("id") !== id) {
|
|
|
- part.parentNode?.removeChild(part)
|
|
|
- }
|
|
|
- })
|
|
|
- // 处理装饰音问题
|
|
|
- // const notes = xmlParse.getElementsByTagName("note")
|
|
|
- // const getNextvNoteDuration = (i: number) => {
|
|
|
- // let nextNote = notes[i + 1]
|
|
|
- // // 可能存在多个装饰音问题,取下一个非装饰音时值
|
|
|
- // for (let index = i index < notes.length index++) {
|
|
|
- // const note = notes[index]
|
|
|
- // if (!note.getElementsByTagName("grace")?.length) {
|
|
|
- // nextNote = note
|
|
|
- // break
|
|
|
- // }
|
|
|
- // }
|
|
|
- // const nextNoteDuration = nextNote?.getElementsByTagName("duration")[0]
|
|
|
- // return nextNoteDuration
|
|
|
- // }
|
|
|
- // Array.from(notes).forEach((note, i) => {
|
|
|
- // const graces = note.getElementsByTagName("grace")
|
|
|
- // if (graces && graces.length) {
|
|
|
- // // if (i !== 0) {
|
|
|
- // // note.appendChild(getNextvNoteDuration(i)?.cloneNode(true))
|
|
|
- // // }
|
|
|
- // }
|
|
|
- // })
|
|
|
- }
|
|
|
- // console.log(xmlParse)
|
|
|
- return new XMLSerializer().serializeToString(appoggianceFormate(xmlParse))
|
|
|
+ }
|
|
|
+ })
|
|
|
+ Array.from(partList).forEach(part => {
|
|
|
+ if (part && part.getAttribute("id") !== id) {
|
|
|
+ part.parentNode?.removeChild(part)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ // 处理装饰音问题
|
|
|
+ // const notes = xmlParse.getElementsByTagName("note")
|
|
|
+ // const getNextvNoteDuration = (i: number) => {
|
|
|
+ // let nextNote = notes[i + 1]
|
|
|
+ // // 可能存在多个装饰音问题,取下一个非装饰音时值
|
|
|
+ // for (let index = i index < notes.length index++) {
|
|
|
+ // const note = notes[index]
|
|
|
+ // if (!note.getElementsByTagName("grace")?.length) {
|
|
|
+ // nextNote = note
|
|
|
+ // break
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ // const nextNoteDuration = nextNote?.getElementsByTagName("duration")[0]
|
|
|
+ // return nextNoteDuration
|
|
|
+ // }
|
|
|
+ // Array.from(notes).forEach((note, i) => {
|
|
|
+ // const graces = note.getElementsByTagName("grace")
|
|
|
+ // if (graces && graces.length) {
|
|
|
+ // // if (i !== 0) {
|
|
|
+ // // note.appendChild(getNextvNoteDuration(i)?.cloneNode(true))
|
|
|
+ // // }
|
|
|
+ // }
|
|
|
+ // })
|
|
|
+ }
|
|
|
+ // console.log(xmlParse)
|
|
|
+ return new XMLSerializer().serializeToString(appoggianceFormate(xmlParse))
|
|
|
}
|
|
|
|
|
|
-
|
|
|
// 倚音后连音线
|
|
|
export const appoggianceFormate = (xmlParse: Document): Document => {
|
|
|
- if (!xmlParse) return xmlParse
|
|
|
- const graces: any = xmlParse.querySelectorAll("grace")
|
|
|
- if (!graces.length) return xmlParse
|
|
|
- const getNextElement = (el: HTMLElement): HTMLElement => {
|
|
|
- if (el.querySelector("grace")) {
|
|
|
- return getNextElement(el?.nextElementSibling as HTMLElement)
|
|
|
- }
|
|
|
- return el
|
|
|
- }
|
|
|
- for (const grace of graces) {
|
|
|
- const notations = grace.parentElement?.querySelector("notations")
|
|
|
- if (notations && notations.querySelectorAll("slur").length > 1) {
|
|
|
- const nextEle: Element = getNextElement(grace.parentElement?.nextElementSibling as HTMLElement)
|
|
|
- if (nextEle && nextEle.querySelectorAll("slur").length > 0) {
|
|
|
- const slurNumber = Array.from(nextEle.querySelector("notations")?.children || []).map((el: Element) => {
|
|
|
- return el.getAttribute("number")
|
|
|
- })
|
|
|
- const slurs = notations.querySelectorAll("slur")
|
|
|
- for (const nota of slurs) {
|
|
|
- if (!slurNumber.includes(nota.getAttribute("number"))) {
|
|
|
- nextEle.querySelector("notations")?.appendChild(nota)
|
|
|
- }
|
|
|
- }
|
|
|
+ if (!xmlParse) return xmlParse
|
|
|
+ const graces: any = xmlParse.querySelectorAll("grace")
|
|
|
+ if (!graces.length) return xmlParse
|
|
|
+ const getNextElement = (el: HTMLElement): HTMLElement => {
|
|
|
+ if (el.querySelector("grace")) {
|
|
|
+ return getNextElement(el?.nextElementSibling as HTMLElement)
|
|
|
}
|
|
|
- }
|
|
|
- }
|
|
|
- return xmlParse
|
|
|
+ return el
|
|
|
+ }
|
|
|
+ for (const grace of graces) {
|
|
|
+ const notations = grace.parentElement?.querySelector("notations")
|
|
|
+ if (notations && notations.querySelectorAll("slur").length > 1) {
|
|
|
+ const nextEle: Element = getNextElement(grace.parentElement?.nextElementSibling as HTMLElement)
|
|
|
+ if (nextEle && nextEle.querySelectorAll("slur").length > 0) {
|
|
|
+ const slurNumber = Array.from(nextEle.querySelector("notations")?.children || []).map((el: Element) => {
|
|
|
+ return el.getAttribute("number")
|
|
|
+ })
|
|
|
+ const slurs = notations.querySelectorAll("slur")
|
|
|
+ for (const nota of slurs) {
|
|
|
+ if (!slurNumber.includes(nota.getAttribute("number"))) {
|
|
|
+ nextEle.querySelector("notations")?.appendChild(nota)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return xmlParse
|
|
|
}
|
|
|
|
|
|
-
|
|
|
/**
|
|
|
* 添加第一分谱信息至当前分谱
|
|
|
* @param ele 需要插入的元素
|
|
@@ -263,43 +258,43 @@ export const appoggianceFormate = (xmlParse: Document): Document => {
|
|
|
* @param parent 需要添加的分谱
|
|
|
*/
|
|
|
const setElementNoteBefore = (ele: Element, fitstParent: Element, parent?: Element | null) => {
|
|
|
- let noteIndex = 0
|
|
|
- if (!fitstParent) {
|
|
|
- return
|
|
|
- }
|
|
|
- for (let index = 0; index < fitstParent.childNodes.length; index++) {
|
|
|
- const element = fitstParent.childNodes[index]
|
|
|
- if (element.nodeName === "note") {
|
|
|
- noteIndex++
|
|
|
- }
|
|
|
- if (element === ele) {
|
|
|
- break
|
|
|
- }
|
|
|
- }
|
|
|
- if (noteIndex === 0 && parent) {
|
|
|
- parent.insertBefore(ele, parent.childNodes[0])
|
|
|
- return
|
|
|
- }
|
|
|
- if (parent && parent.childNodes.length > 0) {
|
|
|
- let noteIndex2 = 0
|
|
|
- const notes = Array.from(parent.childNodes).filter((child) => child.nodeName === "note")
|
|
|
- const lastNote = notes[notes.length - 1]
|
|
|
- if (noteIndex >= notes.length && lastNote) {
|
|
|
- parent.insertBefore(ele, parent.childNodes[Array.from(parent.childNodes).indexOf(lastNote)])
|
|
|
+ let noteIndex = 0
|
|
|
+ if (!fitstParent) {
|
|
|
return
|
|
|
- }
|
|
|
- for (let index = 0; index < notes.length; index++) {
|
|
|
- const element = notes[index]
|
|
|
+ }
|
|
|
+ for (let index = 0; index < fitstParent.childNodes.length; index++) {
|
|
|
+ const element = fitstParent.childNodes[index]
|
|
|
if (element.nodeName === "note") {
|
|
|
- noteIndex2 = noteIndex2 + 1
|
|
|
- if (noteIndex2 === noteIndex) {
|
|
|
- parent.insertBefore(ele, element)
|
|
|
- break
|
|
|
- }
|
|
|
+ noteIndex++
|
|
|
+ }
|
|
|
+ if (element === ele) {
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (noteIndex === 0 && parent) {
|
|
|
+ parent.insertBefore(ele, parent.childNodes[0])
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (parent && parent.childNodes.length > 0) {
|
|
|
+ let noteIndex2 = 0
|
|
|
+ const notes = Array.from(parent.childNodes).filter(child => child.nodeName === "note")
|
|
|
+ const lastNote = notes[notes.length - 1]
|
|
|
+ if (noteIndex >= notes.length && lastNote) {
|
|
|
+ parent.insertBefore(ele, parent.childNodes[Array.from(parent.childNodes).indexOf(lastNote)])
|
|
|
+ return
|
|
|
+ }
|
|
|
+ for (let index = 0; index < notes.length; index++) {
|
|
|
+ const element = notes[index]
|
|
|
+ if (element.nodeName === "note") {
|
|
|
+ noteIndex2 = noteIndex2 + 1
|
|
|
+ if (noteIndex2 === noteIndex) {
|
|
|
+ parent.insertBefore(ele, element)
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
- }
|
|
|
- // console.log(noteIndex, parent)
|
|
|
+ }
|
|
|
+ // console.log(noteIndex, parent)
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -308,49 +303,49 @@ const setElementNoteBefore = (ele: Element, fitstParent: Element, parent?: Eleme
|
|
|
* @returns 是否是重复关键词
|
|
|
*/
|
|
|
export const isRepeatWord = (text: string): boolean => {
|
|
|
- if (text) {
|
|
|
- const innerText = text.toLocaleLowerCase()
|
|
|
- const dsRegEx = "d\\s?\\.s\\."
|
|
|
- const dcRegEx = "d\\.\\s?c\\."
|
|
|
+ if (text) {
|
|
|
+ const innerText = text.toLocaleLowerCase()
|
|
|
+ const dsRegEx = "d\\s?\\.s\\."
|
|
|
+ const dcRegEx = "d\\.\\s?c\\."
|
|
|
|
|
|
- return (
|
|
|
- innerText === "@" ||
|
|
|
- StringUtil.StringContainsSeparatedWord(innerText, dsRegEx + " al fine", true) ||
|
|
|
- StringUtil.StringContainsSeparatedWord(innerText, dsRegEx + " al coda", true) ||
|
|
|
- StringUtil.StringContainsSeparatedWord(innerText, dcRegEx + " al fine", true) ||
|
|
|
- StringUtil.StringContainsSeparatedWord(innerText, dcRegEx + " al coda", true) ||
|
|
|
- StringUtil.StringContainsSeparatedWord(innerText, dcRegEx) ||
|
|
|
- StringUtil.StringContainsSeparatedWord(innerText, "da\\s?capo", true) ||
|
|
|
- StringUtil.StringContainsSeparatedWord(innerText, dsRegEx, true) ||
|
|
|
- StringUtil.StringContainsSeparatedWord(innerText, "dal\\s?segno", true) ||
|
|
|
- StringUtil.StringContainsSeparatedWord(innerText, "al\\s?coda", true) ||
|
|
|
- StringUtil.StringContainsSeparatedWord(innerText, "to\\s?coda", true) ||
|
|
|
- StringUtil.StringContainsSeparatedWord(innerText, "a (la )?coda", true) ||
|
|
|
- StringUtil.StringContainsSeparatedWord(innerText, "fine", true) ||
|
|
|
- StringUtil.StringContainsSeparatedWord(innerText, "coda", true) ||
|
|
|
- StringUtil.StringContainsSeparatedWord(innerText, "segno", true)
|
|
|
- )
|
|
|
- }
|
|
|
- return false
|
|
|
+ return (
|
|
|
+ innerText === "@" ||
|
|
|
+ StringUtil.StringContainsSeparatedWord(innerText, dsRegEx + " al fine", true) ||
|
|
|
+ StringUtil.StringContainsSeparatedWord(innerText, dsRegEx + " al coda", true) ||
|
|
|
+ StringUtil.StringContainsSeparatedWord(innerText, dcRegEx + " al fine", true) ||
|
|
|
+ StringUtil.StringContainsSeparatedWord(innerText, dcRegEx + " al coda", true) ||
|
|
|
+ StringUtil.StringContainsSeparatedWord(innerText, dcRegEx) ||
|
|
|
+ StringUtil.StringContainsSeparatedWord(innerText, "da\\s?capo", true) ||
|
|
|
+ StringUtil.StringContainsSeparatedWord(innerText, dsRegEx, true) ||
|
|
|
+ StringUtil.StringContainsSeparatedWord(innerText, "dal\\s?segno", true) ||
|
|
|
+ StringUtil.StringContainsSeparatedWord(innerText, "al\\s?coda", true) ||
|
|
|
+ StringUtil.StringContainsSeparatedWord(innerText, "to\\s?coda", true) ||
|
|
|
+ StringUtil.StringContainsSeparatedWord(innerText, "a (la )?coda", true) ||
|
|
|
+ StringUtil.StringContainsSeparatedWord(innerText, "fine", true) ||
|
|
|
+ StringUtil.StringContainsSeparatedWord(innerText, "coda", true) ||
|
|
|
+ StringUtil.StringContainsSeparatedWord(innerText, "segno", true)
|
|
|
+ )
|
|
|
+ }
|
|
|
+ return false
|
|
|
}
|
|
|
|
|
|
/** 从xml中获取自定义信息,并删除多余的字符串 */
|
|
|
export const getCustomInfo = (xml: string): any => {
|
|
|
- const data = {
|
|
|
- showSpeed: true,
|
|
|
- parsedXML: xml,
|
|
|
- }
|
|
|
- const xmlParse = new DOMParser().parseFromString(xml, "text/xml")
|
|
|
- const words: any = xmlParse.getElementsByTagName("words")
|
|
|
- for (const word of words) {
|
|
|
- if (word && word.textContent?.trim() === "隐藏速度") {
|
|
|
- data.showSpeed = false
|
|
|
- word.textContent = ""
|
|
|
- }
|
|
|
- if (word && word.textContent?.trim() === "@") {
|
|
|
- word.textContent = "segno"
|
|
|
- }
|
|
|
- }
|
|
|
- data.parsedXML = new XMLSerializer().serializeToString(xmlParse)
|
|
|
- return data
|
|
|
+ const data = {
|
|
|
+ showSpeed: true,
|
|
|
+ parsedXML: xml
|
|
|
+ }
|
|
|
+ const xmlParse = new DOMParser().parseFromString(xml, "text/xml")
|
|
|
+ const words: any = xmlParse.getElementsByTagName("words")
|
|
|
+ for (const word of words) {
|
|
|
+ if (word && word.textContent?.trim() === "隐藏速度") {
|
|
|
+ data.showSpeed = false
|
|
|
+ word.textContent = ""
|
|
|
+ }
|
|
|
+ if (word && word.textContent?.trim() === "@") {
|
|
|
+ word.textContent = "segno"
|
|
|
+ }
|
|
|
+ }
|
|
|
+ data.parsedXML = new XMLSerializer().serializeToString(xmlParse)
|
|
|
+ return data
|
|
|
}
|