ข้ามไปยังเนื้อหา

★ การสอดคล้องมาตรฐาน

หน้านี้นิยามความหมายของการสอดคล้องมาตรฐานใน ThaiMusicXML v1.0 และรวบรวมกฎที่แต่ละหน้าองค์ประกอบระบุไว้แยกกัน

คำสำคัญ ต้อง, ต้องไม่, ควร, ควรไม่, และ อาจ มีความหมายตามที่ใช้ในข้อกำหนดมาตรฐานทั่วไป:

  • ต้อง และ ต้องไม่ เป็นข้อกำหนดเบ็ดเสร็จ เอกสารที่ละเมิดไม่ถือว่าเป็นเอกสาร ThaiMusicXML
  • ควร และ ควรไม่ อธิบายพฤติกรรมที่มีเหตุผลรองรับ ละเมิดได้เฉพาะเมื่อเข้าใจผลกระทบทั้งหมดแล้ว
  • อาจ ระบุสิ่งที่เป็นทางเลือก ตัวประมวลผลที่ไม่รองรับยังคงสอดคล้องมาตรฐาน

เอกสาร ThaiMusicXML v1.0 ที่สอดคล้องมาตรฐาน:

  1. เป็นเอกสาร XML ที่มีโครงสร้างถูกต้อง
  2. มีราก <thai-score> เพียงรายการเดียว พร้อม version="1.0" และเนมสเปซ ThaiMusicXML
  3. ผ่านทุกกฎ ต้อง ในทุกหน้าองค์ประกอบ

Schema RELAX NG ระบุกฎที่ไวยากรณ์สามารถเข้าถึงได้ ส่วนที่เหลือเป็นข้อความ การตรวจสอบต้องผ่านเอกสารอีกรอบ

ตัวประมวลผล หมายถึงซอฟต์แวร์ใด ๆ ที่อ่าน ThaiMusicXML ไม่ว่าจะเป็นตัวตรวจสอบ ตัวแสดงผล ตัวเล่น หรือตัวแปลง

ตัวประมวลผลที่สอดคล้องมาตรฐานต้องปฏิเสธเอกสารที่ละเมิดกฎ ต้อง หรือรายงานการละเมิดอย่างชัดเจนหากเลือกจะทำงานต่อ ต้องไม่แก้ไขเงียบ ๆ ในกรณีที่กฎระบุว่าตัวตรวจสอบ ควรแจ้งเตือน ตัวประมวลผลควรยอมรับเอกสารและแจ้งให้ทราบ

ตัวประมวลผลอาจละเลยสิ่งที่ไม่ต้องใช้ ตัวตรวจสอบที่ไม่มีเสียงอาจข้าม <tuning> ตัวแปลงที่ไม่มีจออาจข้ามทุกอย่างในหน้า การแสดงผล

หลายกฎในข้อกำหนดนี้แก้ไขข้อขัดแย้งโดยละเลยฝ่ายหนึ่งแทนที่จะปฏิเสธเอกสาร เมื่อเกิดกรณีนี้ ตัวตรวจสอบควรแจ้งเตือน

ผู้แต่งเขียนบางสิ่งไว้ แต่ไฟล์ทำงานราวกับว่าไม่มีสิ่งนั้น ควรแจ้งไว้แม้ไม่เป็นอันตราย เพราะทางเลือกคือเอกสารที่ผ่านการตรวจสอบแต่ไม่ได้สื่อความหมายตามที่ผู้แต่งตั้งใจ octave ที่ปรากฏข้างตัวปรับ octave ของไทย, octave บนโน้ตที่ใช้ sound, และข้อความที่อยู่ข้าง <text> ล้วนเป็นกรณีนี้

นี่เป็นหลักการทั่วไป ไม่ใช่กฎแยก ในกรณีที่หน้าองค์ประกอบเฉพาะระบุการแจ้งเตือน หน้านั้นเป็นอำนาจสูงสุด

หน้าองค์ประกอบระบุประเภทให้แต่ละแอตทริบิวต์ ส่วนนี้อธิบายว่าชื่อเหล่านั้นอนุญาตค่าใด เพื่อให้ตัวแยกวิเคราะห์สองตัวที่เขียนจากข้อกำหนดเดียวกันตกลงกันว่าค่าที่ถูกต้องเป็นอย่างไร

true, false, 1, และ 0 จับคู่ตามค่า dim="1" และ dim="true" เหมือนกัน ไม่รับค่าอื่น

เครื่องหมายบวก/ลบนำหน้า (ไม่บังคับ) ตามด้วยตัวเลข octave รับจำนวนเต็มใด ๆ times, first, last, number, row, และเนื้อหาของ <bpm> รับจำนวนเต็มบวก โดยมีขอบเขตตามที่แต่ละหน้าองค์ประกอบกำหนด times เป็นตัวเดียวที่มีขอบล่างสูงกว่า 1 คือต้องเป็น 2 ขึ้นไป

value ของ <chan> เป็นค่าอีนัมแบบปิด จับคู่ตรงตามที่เขียน: 0.5, 1, 2, 3, 4 ไม่รับ 0.50 หรือ .5 ทั้งห้าระดับเป็นชุดทั้งหมด ค่าอื่นจึงเป็นข้อผิดพลาด

value ของ <nathap> และ reference ของ <tuning> เป็นแบบเปิด ทั้งคู่รับสตริงที่ไม่ว่าง และทั้งคู่เผยแพร่รายการแนะนำ ตัวตรวจสอบแจ้งเตือนเมื่อค่าอยู่นอกรายการและต้องไม่ปฏิเสธ ซึ่งจับการสะกดผิดของชื่อที่รู้จักได้โดยไม่ทำให้ชื่อที่ไม่ปกติกลายเป็นเอกสารที่ไม่ถูกต้อง

อักขระโน้ตตัวฐานหนึ่งตัว ตามด้วยตัวปรับ octave ของไทยได้ไม่เกินหนึ่งตัว

ดีกรี ตัวเลข ไทย โค้ดพอยต์ โรมัน
1 1 U+0E14 D หรือ d
2 2 U+0E23 R หรือ r
3 3 U+0E21 M หรือ m
4 4 U+0E1F F หรือ f
5 5 U+0E0B S หรือ s
6 6 U+0E25 L หรือ l
7 7 U+0E17 T หรือ t

ตัวปรับสองตัวคือ นิคหิต U+0E4D สำหรับยกขึ้นหนึ่ง octave และ พินทุ U+0E3A สำหรับลดลงหนึ่ง octave ใช้กับการสะกดแบบใดก็ได้ทั้งสาม

จับคู่ตามโค้ดพอยต์ ตัวปรับทั้งสองเป็น combining characters ในการแสดงผลจึงลอยอยู่เหนือตัวอักษรก่อนหน้า แยกด้วยสายตาจากตัวอักษรที่คล้ายกันไม่ได้ และไม่สามารถคัดลอกออกจากหน้าเว็บได้อย่างน่าเชื่อถือ

การปรับรูปแบบไม่เป็นปัญหา ภาษาไทยไม่มี canonical compositions ค่า pitch จึงเป็นลำดับโค้ดพอยต์เดียวกันภายใต้ NFC, NFD, และตามที่เขียน ไม่ต้องปรับรูปแบบก่อนจับคู่

จำนวนเต็มคั่นด้วยจุลภาค เรียงจากน้อยไปมาก ไม่ซ้ำ: 2 และ 2,4 ถูกต้อง, 4,2 และ 2,2 ไม่ถูกต้อง ดู <ending> สำหรับขอบเขต

id เป็นชุดอักขระที่ไม่มีช่องว่างคั่น และ id สองตัวเหมือนกันเมื่อตรงกันทุกตัวอักษร id="s1" กับ id="S1" เป็นคนละ id ส่วน id="s 1" ไม่ใช่ id เลย เพราะค่าที่ต้องตัดหรือยุบช่องว่างก่อนเทียบจะให้ผลอย่างหนึ่งในโปรแกรมที่ทำแบบนั้น และอีกอย่างในโปรแกรมที่ไม่ทำ

id ต้องไม่ซ้ำกันในองค์ประกอบประเภทเดียวกัน ค่า <part id="…"> ต้องไม่ซ้ำกันในทุกพาร์ต และค่า <section id="…"> ต้องไม่ซ้ำกันในทุกท่อน แต่ชุดทั้งสองเป็นอิสระต่อกัน <part id="1"> และ <section id="1"> จึงอยู่ร่วมกันได้และอ้างถึงคนละสิ่ง IDREF แก้ไขภายในประเภทที่แอตทริบิวต์ระบุ: part บน <part-data> หา <part>, section บน <section-ref> หา <section>

<line>, <measure>, <note>, <rest>, และ <group> ก็รับ id ได้เช่นกัน แต่ละประเภทเป็นชุดอิสระของตัวเอง เหมือนที่ part กับ section เป็น

ThaiMusicXML จะไม่ใช้ id เหล่านี้ ไม่มีแอตทริบิวต์ IDREF ใดระบุประเภทเหล่านี้ เพราะเอกสารไม่มีเหตุผลต้องชี้ไปที่โน้ตของตัวเอง id พวกนี้มีไว้ให้ส่วนขยายเนมสเปซภายนอกหรือเครื่องมืออื่นนอกเอกสารมีจุดยึดที่แน่นอนไว้แนบข้อมูล ซึ่งเป็นเหตุผลเดียวกับที่ไม่มีสิ่งใดบังคับให้ต้องมี: ไฟล์ที่ไม่มี id เหล่านี้เลยก็สอดคล้องมาตรฐานเท่ากับไฟล์ที่ติด id ทุกโน้ต

<thai-score> รับองค์ประกอบเนมสเปซภายนอกได้หลัง <part-data> ตัวสุดท้าย เป็นช่องทางให้เครื่องมือของบุคคลที่สามแนบสถานะของตัวเองไปกับโน้ตได้ เช่น โปรแกรมแก้ไขที่บันทึก <nts:editor version="1"> แต่ละองค์ประกอบต้องประกาศเนมสเปซจริงของตัวเอง องค์ประกอบที่ไม่มีเนมสเปซจะถูกปฏิเสธ เพราะจะทำให้เนื้อหาของเครื่องมือนั้นปลอมเป็นข้อมูลดั้งเดิมได้

กฎนี้ใช้ทุกระดับความลึก ไม่ใช่เฉพาะองค์ประกอบที่อยู่ใต้ <thai-score> โดยตรง ตัวประมวลผลที่ไล่ทั้งเอกสารตามเนมสเปซและชื่อต้องไม่มีวันเจอสิ่งที่หน้าตาเหมือนองค์ประกอบ ThaiMusicXML อยู่ภายในส่วนขยาย องค์ประกอบหลานที่ไม่มีคำนำหน้าและสืบทอดเนมสเปซเริ่มต้นของ ThaiMusicXML เองจึงถูกปฏิเสธเหมือนส่วนขยายระดับบนสุดที่ไม่มีคำนำหน้า การประกาศเนมสเปซเริ่มต้นเพียงครั้งเดียวที่รากของส่วนขยายครอบคลุมองค์ประกอบลูกหลานที่ไม่มีคำนำหน้าทั้งหมด ไม่จำเป็นต้องใส่คำนำหน้าทีละตัว

ตัวประมวลผลต้องรักษาองค์ประกอบส่วนขยายที่ตนไม่รู้จักไว้โดยไม่เปลี่ยนแปลงตลอด round trip และส่วนขยายต้องไม่กระทบวิธีที่เอกสารแสดงผลหรือเล่น สองกฎนี้ทำให้ส่วนขยายจากหลายเครื่องมืออยู่ร่วมกันได้โดยไม่ต้องเข้าใจกันเอง และป้องกันไม่ให้ส่วนขยายกลายเป็นสิ่งจำเป็นจนแยกฟอร์แมตออกไปเอง

เมื่อองค์ประกอบรับข้อความธรรมดาหรือลูก <text> ได้ เช่น <annotation>, <composer>, <lyricist>, <arranger> ลูก <text> มีผลเหนือกว่า ข้อความอื่นข้าง ๆ จะถูกละเลย ซึ่งทำให้องค์ประกอบเยื้องหลายบรรทัดได้โดยไม่ทำให้ช่องว่างกลายเป็นเนื้อหา ข้อความที่ถูกละเลยซึ่งไม่ใช่ช่องว่างล้วนจะได้รับการแจ้งเตือน

  • <thai-score> ต้องเป็นรากเดียว พร้อม version และเนมสเปซ
  • ตัวประมวลผลต้องปฏิเสธเอกสารที่รากอยู่ในเนมสเปซที่ไม่รองรับ URI ของเนมสเปซเป็นขอบเขตความเข้ากันได้: ในช่วง 0.x ทุกรุ่นมี URI เฉพาะ จาก 1.0 URI จะมีเฉพาะเลขรุ่นหลัก version แยกแยะรุ่นภายในขอบเขตและเป็นข้อมูลสำหรับตัวประมวลผลที่เข้าใจเนมสเปซอยู่แล้ว ไม่ตรงกันจึงแจ้งเตือนแทนปฏิเสธ
  • ลูกปรากฏตามลำดับ: <header>, <structure>, <ensemble>, <part-data> หนึ่งรายการขึ้นไป แล้วองค์ประกอบส่วนขยายเนมสเปซภายนอกศูนย์รายการขึ้นไป
  • <header> ต้องมี <title> หนึ่งรายการ ส่วนที่เหลือเป็นทางเลือก <tuning> และ <license> ปรากฏได้ไม่เกินรายการละหนึ่ง
  • <nathap>, <chan>, และ <bpm> เป็นทางเลือกใน <direction> ปรากฏได้ไม่เกินรายการละหนึ่ง ลำดับใดก็ได้
  • <part> ทุกตัวต้องมี <part-data> หนึ่งรายการอ้างถึงผ่าน part
  • <section-ref> ทุกตัวต้องอ้างถึง <section> ที่มีอยู่ใน <structure> ผ่าน section
  • <play> ทุกตัวต้องอ้างถึง <section> ที่มีอยู่ใน <structure> <play> เพิ่มการเล่นท่อนนั้นเข้าในลำดับของโน้ตโดยไม่ได้ประกาศท่อน ท่อนหนึ่งจึงยังประกาศด้วย <section> เพียงตัวเดียว
  • <part-data> ปรากฏลำดับใดก็ได้ <part-data> ต้องไม่อ้างถึงท่อนเดิมซ้ำ และไม่จำเป็นต้องอ้างถึงทุกท่อน
  • ลูก <section-ref> ของ <part-data> ก็ปรากฏลำดับใดก็ได้ และลำดับนั้นไม่มีความหมาย ลำดับที่ท่อนเล่นเป็นเรื่องของ <structure> ส่วน <section-ref> เพียงบอกว่าบรรทัดชุดนั้นเป็นของท่อนใด
  • <section> ที่ไม่มี <part-data> อ้างถึงไม่มีดนตรี ไม่เล่น ไม่สร้างแถวในหน้า และกฎที่นับบรรทัดและห้องไม่ใช้กับท่อนนั้น
  • <part> ที่มี stack ต้องมี row ด้วย และในทางกลับกัน ค่า stack ต้องใช้ร่วมกันอย่างน้อยสองพาร์ต ค่า row ต้องเริ่มจาก 1 ไม่มีช่องว่างหรือซ้ำ และต้องอยู่ติดกันใน <ensemble> ตามลำดับ row
  • พาร์ต type="lyric" ต้องไม่มี stack หรือ row stack คือแถวของเครื่องดนตรีชิ้นเดียว และคำร้องไม่ใช่พื้นที่ส่วนหนึ่งของเครื่องดนตรี
  • <section-ref> ที่อ้างถึง <section> เดียวกันต้องตรงกันเรื่องจำนวนบรรทัด จำนวนห้องต่อบรรทัด และจำนวนจังหวะต่อห้อง ตัวตรวจสอบต้องปฏิเสธเอกสารที่ละเมิด
  • พาร์ต type="lyric" ผูกกับจำนวนบรรทัดและจำนวนห้องต่อบรรทัด แต่ได้รับการยกเว้นเรื่องจำนวนจังหวะต่อห้อง ห้องของพาร์ตเนื้อเพลงรองรับจำนวนรายการเท่าใดก็ได้ และถูกแยกออกจากการเปรียบเทียบที่พาร์ตอื่นต้องทำ
  • <line> ต้องมี <measure> หนึ่งถึงแปด
  • number บน <line> และ <measure> ต้องตรงกับตำแหน่ง นับจาก 1 เรียงจากน้อยไปมาก
  • ห้องในพาร์ตที่มีระดับเสียงหรือไม่มีระดับเสียงต้องมี <note>, <rest>, หรือ <group> อย่างน้อยหนึ่ง ห้องเนื้อเพลงอาจว่างได้
  • <group> ต้องมีลูก <note> หรือ <rest> อย่างน้อยสอง และต้องไม่มี <group> ซ้อน
  • จังหวะเกิดในช่องโน้ตสุดท้าย ลูกสุดท้ายของ <group> จึงตกบนจังหวะ ส่วนตัวก่อนหน้าถอยหลังจากจุดนั้นภายในช่วงจังหวะ กลุ่มไม่เคยข้ามจังหวะของตัวเอง จึงไม่เคยข้าม <measure> หรือ <line> ดู <group>
  • times บน <repeat> และ <line-repeat> ต้องเป็นจำนวนเต็ม 2 ขึ้นไป และเป็น 2 เมื่อไม่ระบุ นับจำนวนครั้งทั้งหมด ไม่ใช่จำนวนครั้งที่เพิ่มจากครั้งแรก องค์ประกอบที่เล่นเนื้อหาครั้งเดียวไม่ได้ซ้ำอะไร times="1" จึงถูกปฏิเสธแทนที่จะถือว่าไม่มีผล
  • <repeat> ต้องมี <section> อย่างน้อยหนึ่ง ไม่ว่าโดยตรงหรือซ้อน
  • <line-repeat> ต้องมีทั้ง first และ last โดย first ไม่มากกว่า last และ last ไม่มากกว่าจำนวนบรรทัดของท่อน
  • ช่วง <line-repeat> สองช่วงในท่อนเดียวกันต้องซ้อนกันอย่างถูกต้องหรือแยกกันทั้งหมด
  • <ending> ใช้ได้เมื่อจำนวนรอบทั้งหมดของท่อนเกิน 1 ค่า pass ทุกค่าต้องอยู่ในจำนวนนั้น <line number="N"> ทุกตัวต้องแทนที่บรรทัดที่มีอยู่ และต้องมีจำนวนห้องและจังหวะเท่ากับต้นฉบับ
  • บรรทัดของ <ending> ต้องเรียงต่อกันจนถึงบรรทัดสุดท้ายของท่อน ท่อนที่ครอบเฉพาะบรรทัดกลางไม่ถูกต้อง เพราะท่อนจะดำเนินต่อตามปกติหลังจากนั้น
  • <ending> ทุกตัวต้องมี <annotation> อย่างน้อยหนึ่งรายการอธิบายความแปรผัน
  • type บน <part> ต้องเป็น "pitched", "unpitched", หรือ "lyric" ตัวตรวจสอบต้องปฏิเสธค่าอื่น
  • ลูกของห้องต้องตรงกับ type ของพาร์ต: <note>, <rest>, และ <group> ในพาร์ตที่มีหรือไม่มีระดับเสียง <syllable> และ <rest> ในพาร์ตเนื้อเพลง <note>, <group>, <bow>, <parenthesis>, และ <link> ไม่ถูกต้องในพาร์ตเนื้อเพลง และ <syllable> ไม่ถูกต้องนอกพาร์ตเนื้อเพลง
  • โน้ตในพาร์ต pitched ใช้ pitch ในพาร์ต unpitched ใช้ sound ทั้งสองใช้แทนกันไม่ได้
  • pitch ต้องเป็นหนึ่งในเจ็ดอักขระโน้ตตัวฐานในการสะกดแบบใดก็ได้ ตามด้วยตัวปรับ octave ของไทยได้ไม่เกินหนึ่ง ตัวตรวจสอบต้องปฏิเสธค่าอื่น ดู ประเภทข้อมูลเชิงอรรถาลักษณ์
  • โน้ตตัวฐานแบบโรมันเขียนตัวพิมพ์ใหญ่หรือเล็กก็ได้ ตัวพิมพ์ไม่มีความหมาย ตัวแสดงผลตัดสินว่าตัวพิมพ์ใดปรากฏบนหน้า
  • เมื่อ pitch มีตัวปรับ octave ของไทย ตัวปรับนั้นมีผลเหนือกว่าและ octave จะไม่ได้ถูกใช้ ตัวตรวจสอบควรแจ้งเตือนแทนปฏิเสธ
  • value ของ <chan> ต้องเป็นหนึ่งในห้าระดับที่ระบุ จับคู่ตรงตามที่เขียน ตัวตรวจสอบต้องปฏิเสธค่าอื่น
  • value ของ <nathap> และ reference ของ <tuning> รับสตริงที่ไม่ว่างใดก็ได้ ตัวตรวจสอบควรแจ้งเตือนเมื่อค่าอยู่นอกรายการแนะนำในหน้าองค์ประกอบ และต้องไม่ปฏิเสธ
  • เนื้อหาของ <bpm> ต้องเป็นจำนวนเต็มบวก
  • ช่วง <link> ใช้ได้ในพาร์ตที่มีโน้ตใดก็ได้ เมื่อ <part> ที่ครอบมี stack เส้นโค้งเข้าถึงแถวอื่นของเครื่องดนตรีนั้น เมื่อไม่มี stack เส้นโค้งทำเครื่องหมายโน้ตของช่วงเอง ทั้งสองกรณีมีแถวให้เข้าถึงเสมอ เพราะทุกแถวของ stack เป็นพาร์ตที่มีโน้ต
  • <bow>, <parenthesis>, และ <link> จับคู่ตามลำดับเอกสารภายในรอบที่แก้ไขแล้ว ทั้งสามชนิดจับคู่แยกจากกัน ช่วงชนิดหนึ่งจึงเปิดภายในช่วงอีกชนิดได้ แก้ไขการแทนที่ <ending> ของท่อนก่อน แล้วจับคู่ภายในบรรทัดที่รอบนั้นเล่นจริง ดู ช่วงที่ข้ามบรรทัดที่ถูกแทนที่
  • <line-repeat> ไม่มีผลต่อการจับคู่ บรรทัดถูกอ่านครั้งเดียวตามลำดับที่เขียน ไม่ว่าจะเล่นกี่ครั้ง
  • ในทุกรอบที่แก้ไขแล้ว type="start" ต้องถูกปิดด้วย type="stop" ที่ตรงกันก่อนที่ start อื่นจะปรากฏ ช่วงไม่สามารถซ้อนหรือทับซ้อนกัน
  • ในทุกรอบที่แก้ไขแล้ว start ทุกตัวต้องมี stop ที่ตรงกันภายใน <section-ref> เดียวกัน ช่วงที่เปิดค้างไว้เมื่อจบรอบไม่ถูกต้อง แม้อีกจะปิดก็ตาม ช่วงไม่สามารถข้ามขอบเขตท่อน
  • direction จำเป็นบน <bow type="start"> และต้องไม่ปรากฏบน type="stop"
  • dim และ mute ใช้ได้เฉพาะบน <parenthesis type="start">
  • <link> ไม่มีแอตทริบิวต์อื่นนอกจาก type ทั้งบนตัวเปิดและตัวปิด
  • ตัวกำกับ <link>, <bow>, หรือ <parenthesis> ภายใน <group> ไม่มีความยาวและไม่นับรวมการแบ่งเท่าของจังหวะกลุ่มนั้น
  • ตัวกำกับทั้งสองของช่วงต้องอยู่ในพาร์ตเดียวกัน type="start" ในแถวหนึ่งของ stack ปิดด้วย type="stop" ในอีกแถวไม่ได้
  • align จำเป็นบน <text> ทุกตัว ต้องเป็น "left", "center", หรือ "right" <text> ต้องมีเฉพาะข้อความ ไม่มีลูก
  • <annotation> อาจมี <text> ไม่เกินหนึ่งตัวต่อค่า align เมื่อมีลูก <text> ลูกเหล่านั้นเป็นเนื้อหา ข้อความอื่นข้าง ๆ จะถูกละเลยพร้อมแจ้งเตือน
  • <composer>, <lyricist>, และ <arranger> ใช้กฎเดียวกัน ข้อความธรรมดาขององค์ประกอบเหล่านี้จัดกลางแทนจัดซ้าย
  • <annotation> หรือ <br> ภายใน <repeat> พิมพ์ครั้งเดียว ณ ตำแหน่งในเอกสาร ไม่ซ้ำตามรอบ <direction> จะถูกอ่านใหม่ทุกรอบ
  • ลูก <annotation> ของ <line> ต้องอยู่ก่อนห้องของบรรทัดนั้น หมายเหตุที่คั่นระหว่างสองห้องไม่ถูกต้อง