คุณจะแยกวิเคราะห์ Markdown อย่างไร? [ปิด]


126

แก้ไข: ฉันเพิ่งเรียนรู้เกี่ยวกับโครงการที่เรียกว่า CommonMark ซึ่งระบุและจัดการกับความคลุมเครือในข้อกำหนด Markdown ดั้งเดิมได้อย่างถูกต้อง http://commonmark.org/มีการสนับสนุนไลบรารี C # ที่ยอดเยี่ยม

คุณสามารถค้นหาไวยากรณ์ที่นี่

แหล่งที่มาที่ตามมาพร้อมกับการดาวน์โหลดนั้นเขียนในPerlซึ่งฉันไม่มีเจตนาที่จะให้เกียรติ มันเต็มไปด้วยนิพจน์ทั่วไปและอาศัยแฮชMD5เพื่อหลีกเลี่ยงอักขระบางตัว มีบางอย่างผิดปกติ!

ฉันจะยากรหัส parser สำหรับMarkdown ประสบการณ์นี้คืออะไร?

หากคุณไม่มีความหมายที่จะพูดเกี่ยวกับการแยกวิเคราะห์ Markdown ที่แท้จริงโปรดเผื่อเวลาไว้ (สิ่งนี้อาจฟังดูรุนแรง แต่ใช่ฉันกำลังมองหาข้อมูลเชิงลึกไม่ใช่วิธีแก้ปัญหานั่นคือไลบรารีของบุคคลที่สาม)

เพื่อช่วยในการตอบคำถามนิพจน์ทั่วไปมีไว้เพื่อระบุรูปแบบ ! อย่าแยกวิเคราะห์ไวยากรณ์ทั้งหมด ที่ผู้คนคิดว่าทำเช่นนั้นคือ foobar

  • หากคุณคิดเกี่ยวกับ Markdown โดยพื้นฐานแล้วจะมีพื้นฐานมาจากแนวคิดของย่อหน้า
  • ด้วยเหตุนี้วิธีการที่เหมาะสมอาจแบ่งข้อมูลที่ป้อนออกเป็นย่อหน้า
  • ย่อหน้ามีหลายประเภทเช่นส่วนหัวข้อความรายการบล็อคข้อความและโค้ด
  • ดังนั้นความท้าทายคือการระบุย่อหน้าเหล่านี้และบริบทที่เกิดขึ้น

ฉันจะกลับมาพร้อมวิธีแก้ปัญหาเมื่อฉันพบว่ามันมีค่าควรแบ่งปัน


2
@cletus กำลังเขียนตัวแยกวิเคราะห์ markdown ดูที่cforcoding.com/search/label/markdown
Alex Angas

ฉันลงเอยด้วยการทำเช่นเดียวกัน อย่างไรก็ตามฉันไม่ได้พยายามแยกวิเคราะห์ markdown ราวกับว่ามันเป็นไวยากรณ์ที่เป็นทางการเพราะมันไม่ชัดเจน ฉันใช้นิพจน์ทั่วไปที่แตกต่างกันในลักษณะวนซ้ำ และในหลายรอบ นั่นได้ผลดีมาก
John Leidegren

@JohnLeidegren มีโอกาสที่ผู้ใช้ที่อยากรู้อยากเห็นคนอื่น ๆ เช่นฉันสามารถเห็นความพยายามของคุณในการแยกวิเคราะห์ markdown หรือไม่?
jmlopez

@jmlopez ขออภัยฉันไม่สามารถเข้าถึงแหล่งข้อมูลนั้นได้อีกต่อไปหากคุณต้องการตัวแยกวิเคราะห์ markdown มีแพ็คเกจ NuGet ที่สามารถใช้ได้ แนวคิดนี้ง่ายพอเพียงแค่ใช้ชุดของนิพจน์ทั่วไปในการส่งผ่านเริ่มต้นด้วยการแบ่งพาร์ติชันอินพุตในย่อหน้าจากนั้นพยายามระบุประเภทของย่อหน้าและอื่น ๆ สุดท้ายแยกวิเคราะห์ลิงก์และลักษณะอักขระภายในย่อหน้า
John Leidegren

2
คุณควรดูที่Parsedown มันแบ่งข้อความออกเป็นบรรทัด จากนั้นจะดูว่าเส้นเหล่านี้เริ่มต้นและเกี่ยวข้องกันอย่างไร
Emanuil Rusev

คำตอบ:


69

เพียงการดำเนินการ markdown ฉันรู้ที่ใช้ parser ที่เกิดขึ้นจริงคือจอน MacFarleane ‘s PEG-markdown parser มันจะขึ้นอยู่กับการแยกวิเคราะห์การแสดงออกไวยากรณ์กำเนิด parser เรียกว่าหมุด


แก้ไข: Mauricio Fernandezเพิ่งเปิดตัวโปรแกรมแยกวิเคราะห์ Simple Markup Markdownซึ่งเขาเขียนเป็นส่วนหนึ่งของOcsiBlog Weblog Engine ของเขา เพราะตัวแยกวิเคราะห์ที่ถูกเขียนในOCamlมันเป็นอย่างมากที่ง่ายและสั้น (268 SLOC สำหรับparser 43 SLOC สำหรับHTML อีซีแอล ) ยังเห็นได้ชัดอย่างรวดเร็ว (20% เร็วกว่าส่วนลด (เขียนในมือที่ดีที่สุด C) และsixhundredครั้งเร็ว กว่าBlueCloth ( Ruby)) แม้ว่าจะยังไม่ได้รับการปรับให้เหมาะสมกับประสิทธิภาพก็ตาม เพราะมันมีจุดมุ่งหมายเพียงสำหรับการใช้งานภายในโดยเมาริซิโอตัวเองสำหรับเว็บบล็อกของเขามีการเบี่ยงเบนไม่กี่จากสเปคอย่างเป็นทางการ Markdownแต่เมาริซิโอได้สร้างสาขาซึ่งย้อนกลับมากที่สุดของการเปลี่ยนแปลงเหล่านั้น


1
น่าสนใจ บางทีฉันอาจจะลองแปลงเป็นโครงการ f #
ShuggyCoUk

@Benjol เรื่องเก่าเหมือนกัน: ไม่มีเวลา: /
ShuggyCoUk

1
Terrence Parr (ผู้เขียนร่วมของ ANTLR) ได้เขียนบทความสำหรับ ANTLR 4: github.com/parrt/mini-markdown
Chris S

17

ฉันปล่อยให้แยกวิเคราะห์ตามการดำเนินงานใหม่ Markdown Java สัปดาห์ที่ผ่านมาเรียกว่าpegdown Pegdown ใช้ตัวแยกวิเคราะห์ PEG เพื่อสร้างโครงสร้างไวยากรณ์แบบนามธรรมก่อนซึ่งจะเขียนเป็น HTML ในภายหลัง ด้วยเหตุนี้จึงค่อนข้างสะอาดและง่ายต่อการอ่านดูแลรักษาและขยายเวลามากกว่าวิธีการตาม regex ไวยากรณ์ PEG ขึ้นอยู่กับการใช้งาน "peg-markdown" ของ John MacFarlanes C

บางทีสิ่งที่คุณสนใจ ...


1
ตอนนี้เลิกใช้งานอย่างเป็นทางการแล้ว
Fabich

7

ถ้าฉันพยายามแยกวิเคราะห์ markdown (และส่วนขยายของMarkdown พิเศษ ) ฉันคิดว่าฉันจะลองใช้เครื่องสถานะและแยกวิเคราะห์ทีละอักขระโดยเชื่อมโยงโครงสร้างภายในบางส่วนที่แสดงถึงบิตของข้อความในขณะที่ฉันไปด้วยครั้งหนึ่ง ทั้งหมดถูกแยกวิเคราะห์โดยสร้างเอาต์พุตจากอ็อบเจ็กต์ทั้งหมดที่ต่อเข้าด้วยกัน

โดยทั่วไปฉันจะสร้างต้นไม้ที่มีลักษณะคล้าย DOM ขนาดเล็กเมื่อฉันอ่านไฟล์อินพุต
ในการสร้างผลลัพธ์ฉันจะสำรวจต้นไม้และส่งออก HTML หรืออย่างอื่น (PS, LaTex, RTF, ... )

สิ่งที่สามารถเพิ่มความซับซ้อน:

  • ความจริงที่ว่าคุณสามารถผสม HTML และ markdown ได้แม้ว่ากฎจะใช้งานได้ง่ายเพียงแค่ละเว้นสิ่งที่อยู่ระหว่างแท็กที่สมดุลสองแท็กและส่งออกเป็นคำต่อคำ

  • URL และบันทึกย่อสามารถอ้างอิงได้ที่ด้านล่างของข้อความ การใช้โครงสร้างข้อมูลสำหรับการเชื่อมโยงหลายมิติสามารถบันทึกสิ่งต่างๆเช่น:

    [my text to a link][linkkey]
    results in a structure like: 
        URLStructure: 
        |  InnerText : "my text to a link"
        |  Key       : "linkkey"
        |  URL       : <null>
    
  • ส่วนหัวสามารถกำหนดได้ด้วยการขีดเส้นใต้ซึ่งอาจบังคับให้เราใช้โครงสร้างข้อมูลอย่างง่ายสำหรับย่อหน้าทั่วไปและแก้ไขคุณสมบัติเมื่อเราอ่านไฟล์:

    ParagraphStructure:
    |  InnerText    : the current paragraph text 
    |                 (beginning of line until end of line).
    |  HeadingLevel : <null> or 1-4 when we can assess 
    |                 that paragraph heading level, if any.
    

ยังไงก็แค่บางความคิด

ฉันแน่ใจว่ามีรายละเอียดเล็ก ๆ มากมายที่ต้องดูแลและฉันค่อนข้างมั่นใจว่า Regexes อาจมีประโยชน์ในระหว่างกระบวนการนี้
ท้ายที่สุดพวกเขาตั้งใจจะประมวลผลข้อความ


3

ฉันอาจจะอ่านข้อกำหนดทางไวยากรณ์มากพอที่จะรู้และเข้าใจวิธีการแยกวิเคราะห์

แน่นอนว่าการอ่านรหัสตัวแยกวิเคราะห์ที่มีอยู่นั้นยอดเยี่ยมทั้งเพื่อดูว่าอะไรเป็นที่มาหลักของความซับซ้อนและหากมีการใช้กลเม็ดที่ชาญฉลาดพิเศษใด ๆ การใช้การตรวจสอบ MD5 ดูเหมือนจะแปลก ๆ แต่ฉันยังไม่ได้ศึกษาโค้ดมากพอที่จะเข้าใจว่าทำไมถึงทำ ความคิดเห็นในกิจวัตรที่เรียกว่า_EscapeSpecialChars()สถานะ:

เรากำลังแทนที่อักขระดังกล่าวแต่ละตัวด้วยค่าการตรวจสอบ MD5 ที่สอดคล้องกัน ซึ่งอาจจะมากเกินไป แต่ควรป้องกันไม่ให้เราชนกับค่า Escape โดยไม่ได้ตั้งใจ

การแทนที่อักขระเดี่ยวด้วย MD5 แบบเต็มดูเหมือนจะฟุ่มเฟือย แต่บางทีมันก็สมเหตุสมผลจริงๆ

แน่นอนว่าควรพิจารณาสร้างไวยากรณ์ "จริง" สำหรับเครื่องมือเช่นFlexเพื่อออกจาก regex bog


สิ่งนั้นของ MD5 ยังคงรบกวนฉันอยู่เช่นกันการจัดการสตริงที่มากเกินไปจะต้องช้ากว่าตัวแยกวิเคราะห์ที่เหมาะสมจริง ๆ ที่คุณสามารถเขียนเองได้
John Leidegren

2
Flex เป็นเพียงครึ่งหนึ่งของตัวแยกวิเคราะห์ เมื่อคุณสร้างโทเค็นอินพุตแล้วคุณต้องกำหนดความหมายของโทเค็น นี่คือสิ่งที่ตัวสร้างตัวแยกวิเคราะห์มีไว้สำหรับ มีจำนวนมาก ("Parser combinator", "recursive-โคตร" และ "LALR (1)" เป็นคำสำคัญสำหรับ Google)
jrockway

1
@jrockway: แน่นอนฉันคิดว่าฉันยักไหล่และคิดว่า "แต่ถ้าเขาอ่าน Flex เขาจะพบ Bison โดยอัตโนมัติ" :) ขอบคุณ
ผ่อนคลาย

2

หาก Perl ไม่ได้เป็นสิ่งที่คุณมีการใช้งานใน Markdown อย่างน้อย 10 ภาษาอื่น อาจไม่ได้เข้ากันได้ 100% แต่มีแนวโน้มที่จะใกล้เคียงกัน



1

หากคุณใช้ภาษาโปรแกรมที่มีผู้ใช้อื่นมากกว่าสามคนคุณควรจะหาไลบรารีเพื่อแยกวิเคราะห์ให้คุณได้ Google-ing อย่างรวดเร็วเผยให้เห็นไลบรารีสำหรับ CL, Haskell, Python, JavaScript, Ruby และอื่น ๆ ไม่น่าเป็นไปได้มากที่คุณจะต้องสร้างล้อนี้ขึ้นมาใหม่

ถ้าคุณต้องเขียนตั้งแต่ต้นจริงๆขอแนะนำให้เขียนโปรแกรมแยกวิเคราะห์ที่เหมาะสม ด้วยเทคนิคนี้คุณจะไม่ต้องหนีสิ่งต่างๆด้วยแฮช MD5 (ฉันยอมรับว่าถ้าคุณต้องทำอะไรแบบนี้ถึงเวลาที่ต้องพิจารณาการออกแบบของคุณใหม่


ฉันพร้อมสำหรับความท้าทาย ฉันดูห้องสมุด แต่มันแย่มาก น่าเกลียดและโง่ ฉันกำลังพิจารณาที่จะเขียน parser ใน F # เพราะฉันต้องการโปรเจ็กต์ F # แต่ฉันอาจจะทำมันใน C #
John Leidegren

หวังว่า F # จะมีห้องสมุดเหมือนพาร์เซก ถ้าเป็นเช่นนั้นนี่จะเป็นโครงการที่สนุก;)
jrockway

0

มีไลบรารีให้บริการในหลายภาษา ได้แก่ php, ruby, java, c #, javascript ฉันขอแนะนำให้ดูแนวคิดเหล่านี้บางส่วน

ขึ้นอยู่กับว่าคุณต้องการใช้ภาษาใดสำหรับวิธีที่ดีที่สุดในการนำไปใช้จะมีวิธีการใช้สำนวนและไม่ใช้สำนวน

Regexes ทำงานใน perl เพราะ perl และ regex เป็นเพื่อนที่ดีที่สุด


1
Regex และ Perl เป็นเพื่อนที่ดีที่สุดเพราะมีคนพูดอย่างนั้น ไม่มีความจริงอะไรมากไปกว่าความเป็นมาทางประวัติศาสตร์ที่มีการใช้เช่นนั้น ฉันไม่มีประโยชน์อะไรเช่น perl
John Leidegren

7
แล้วไม่ใช้.. เรียนประชดด้วย.
garrow

0

Markdown เป็น JAWL (เป็นภาษาวิกิอื่น)

มีวิกิโอเพนซอร์สมากมายที่คุณสามารถตรวจสอบโค้ดของโปรแกรมแยกวิเคราะห์ได้ ส่วนใหญ่ใช้ REGEX

ลองดูวิกิพีเดียสกรูมีท่อส่งฟอร์แมตเตอร์หลายพาสที่น่าสนใจซึ่งเป็นเทคนิคที่ดีมาก - ดู /core/Formatter.cs และ /core/FormatterPipeline.cs

ดีที่สุดคือใช้ / เข้าร่วมโครงการที่มีอยู่สิ่งเหล่านี้มักจะยากกว่าที่ปรากฏเสมอ


0

ที่นี่คุณสามารถค้นหาการใช้งาน JavaScript ของ Markdown นอกจากนี้ยังต้องอาศัยนิพจน์ทั่วไปเป็นอย่างมากเนื่องจากเป็นวิธีที่เร็วและง่ายที่สุดในการแยกวิเคราะห์ข้อความ

แต่อะไหล่ MD5

ฉันไม่สามารถช่วยในการเข้ารหัสการแยกวิเคราะห์ได้โดยตรง แต่ลิงก์นี้อาจช่วยคุณได้ไม่ทางใดก็ทางหนึ่ง

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.