Bagaimana Anda akan menguraikan Markdown? [Tutup]


126

Sunting: Saya baru-baru ini belajar tentang proyek yang disebut CommonMark, yang mengidentifikasi dan menangani ambiguitas dalam spesifikasi Markdown asli dengan benar. http://commonmark.org/ Memiliki dukungan perpustakaan C # yang bagus.

Anda dapat menemukan sintaks di sini .

Sumber yang mengikuti pengunduhan ditulis dalam Perl , yang saya tidak punya niat untuk menghormati. Itu penuh dengan ekspresi reguler, dan itu bergantung pada hash MD5 untuk melarikan diri karakter tertentu. Ada yang salah tentang itu!

Saya akan membuat kode parser untuk Markdown . Apa pengalaman dengan ini?

Jika Anda tidak memiliki sesuatu yang bermakna untuk dikatakan tentang penguraian Markdown yang sebenarnya, luangkan waktu saya. (Ini mungkin terdengar kasar, tapi ya, saya mencari wawasan, bukan solusi, yaitu perpustakaan pihak ketiga).

Untuk sedikit membantu dengan jawaban, ekspresi reguler dimaksudkan untuk mengidentifikasi pola ! TIDAK untuk menguraikan seluruh tata bahasa. Yang dianggap orang adalah foobar.

  • Jika Anda berpikir tentang penurunan harga, itu pada dasarnya didasarkan pada konsep paragraf.
  • Dengan demikian, pendekatan yang masuk akal mungkin untuk membagi input menjadi paragraf.
  • Ada banyak jenis paragraf, misalnya, judul, teks, daftar, blockquote, dan kode.
  • Tantangannya adalah untuk mengidentifikasi paragraf-paragraf ini dan dalam konteks apa mereka muncul.

Saya akan kembali dengan solusi, begitu saya merasa layak untuk dibagikan.


2
@cletus sedang menulis parser penurunan harga, lihat cforcoding.com/search/label/markdown
Alex Angas

Saya akhirnya melakukan hal yang sama. Namun, saya tidak mencoba mengurai penurunan harga seolah-olah itu adalah tata bahasa formal, karena jelas tidak. Saya menerapkan ekspresi reguler yang berbeda secara rekursif. Dan dalam beberapa operan. Itu bekerja dengan sangat baik.
John Leidegren

@JohnLeidegren, ada kemungkinan pengguna lain yang ingin tahu seperti saya dapat melihat upaya Anda untuk menguraikan penurunan harga?
jmlopez

@ jmlopez Maaf, saya tidak memiliki akses ke sumber itu lagi, jika Anda memerlukan parser penurunan harga, ada paket NuGet yang dapat digunakan. Idenya cukup sederhana, cukup terapkan serangkaian ekspresi reguler dalam lintasan, mulailah dengan memisahkan masukan dalam paragraf kemudian cobalah untuk mengidentifikasi jenis paragraf apa itu, dan seterusnya. Akhirnya, parsing tautan dan gaya karakter dalam paragraf itu sendiri.
John Leidegren

2
Anda harus melihat Parsedown . Ini membagi teks menjadi beberapa baris. Kemudian terlihat bagaimana garis-garis ini mulai dan berhubungan satu sama lain.
Emanuil Rusev

Jawaban:


69

Satu-satunya penurunan harga pelaksanaan saya tahu, yang menggunakan parser yang sebenarnya, adalah Jon MacFarleane ‘s peg-penurunan harga . Parsernya didasarkan pada generator pengurai Parsing Expression Grammar yang disebut pasak .


EDIT: Mauricio Fernandez baru-baru ini merilis parser Simple Markup Markdown , yang ia tulis sebagai bagian dari OcsiBlog Weblog Engine. Karena parser ditulis dalam OCaml , itu sangat sederhana dan singkat (268 SLOC untuk parser , 43 SLOC untuk HTML emitor ), namun blazingly cepat (20% lebih cepat dari diskon (ditulis tangan-dioptimalkan C) dan sixhundred kali lebih cepat dari BlueCloth ( Ruby)), terlepas dari kenyataan bahwa itu bahkan belum dioptimalkan untuk kinerja. Karena ini hanya dimaksudkan untuk penggunaan internal oleh Mauricio sendiri untuk weblog-nya, ada beberapa penyimpangan dari spesifikasi Markdown resmi , tetapi Mauricio telah membuat cabang yang membalikkan sebagian besar perubahan tersebut .


1
menarik. mungkin saya akan mencoba mengonversinya sebagai proyek f #
ShuggyCoUk

@Benjol Kisah lama yang sama: tidak ada waktu: /
ShuggyCoUk

1
Terrence Parr (penulis bersama ANTLR) telah menulis satu untuk ANTLR 4: github.com/parrt/mini-markdown
Chris S

17

Saya merilis implementasi Markdown Java berbasis parser baru minggu lalu, yang disebut pegdown . pegdown menggunakan pengurai PEG untuk pertama membangun pohon sintaksis abstrak, yang selanjutnya ditulis ke HTML. Karena itu cukup bersih dan lebih mudah dibaca, dipelihara, dan diperluas daripada pendekatan berbasis regex. Tata bahasa PEG didasarkan pada implementasi John MacFarlanes C "peg-markdown".

Mungkin sesuatu yang menarik bagi Anda ...


1
Ini sekarang secara resmi ditinggalkan
Fabich

7

Jika saya mencoba untuk menguraikan penurunan harga (dan ekstensi penurunan harga tambahannya ) saya pikir saya akan mencoba untuk menggunakan mesin negara dan menguraikannya satu karakter pada satu waktu, menghubungkan bersama beberapa struktur internal yang mewakili potongan teks saat saya melanjutkan, sekali semua diuraikan, menghasilkan output dari objek yang semuanya bersatu.

Pada dasarnya, saya akan membangun pohon mini-DOM seperti ketika saya membaca file input.
Untuk menghasilkan output, saya hanya akan melintasi pohon dan output HTML atau apa pun (PS, LaTex, RTF, ...)

Hal-hal yang dapat meningkatkan kompleksitas:

  • Fakta bahwa Anda dapat mencampur HTML dan penurunan harga, meskipun aturannya bisa mudah diimplementasikan: abaikan saja apa pun yang ada di antara dua tag seimbang dan tampilkan dengan kata lain.

  • URL dan catatan dapat memiliki referensi mereka di bagian bawah teks. Menggunakan struktur data untuk hyperlink dapat dengan mudah merekam sesuatu seperti:

    [my text to a link][linkkey]
    results in a structure like: 
        URLStructure: 
        |  InnerText : "my text to a link"
        |  Key       : "linkkey"
        |  URL       : <null>
    
  • Header dapat didefinisikan dengan garis bawah, yang dapat memaksa kita untuk menggunakan struktur data sederhana untuk paragraf umum dan memodifikasi propertinya ketika kita membaca file:

    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.
    

Pokoknya, hanya beberapa pemikiran.

Saya yakin ada banyak detail kecil yang harus diurus dan saya cukup yakin bahwa Regex bisa berguna selama proses.
Bagaimanapun, mereka dimaksudkan untuk memproses teks.


3

Saya mungkin sudah membaca spesifikasi sintaks cukup banyak untuk mengetahuinya, dan merasakan bagaimana menguraikannya.

Membaca kode parser yang ada tentu saja brilian, baik untuk melihat apa yang tampaknya menjadi sumber utama kompleksitas, dan jika ada trik pintar khusus yang sedang digunakan. Penggunaan MD5 checksumming agak aneh, tapi saya belum cukup mempelajari kode untuk memahami mengapa ini dilakukan. Komentar dalam keadaan rutin yang disebut _EscapeSpecialChars():

Kami mengganti setiap karakter tersebut dengan nilai checksum MD5 yang sesuai; ini mungkin berlebihan, tetapi seharusnya mencegah kita bertabrakan dengan nilai pelarian secara tidak sengaja.

Mengganti satu karakter dengan MD5 penuh memang tampak mewah, tapi mungkin itu benar-benar masuk akal.

Tentu saja, akan pintar untuk mempertimbangkan membuat sintaks "benar", untuk alat seperti Flex untuk keluar dari bog regex.


Hal MD5 itu masih mengganggu saya, juga manipulasi string yang berlebihan harus lebih lambat daripada parser yang sebenarnya Anda bisa menulis sendiri.
John Leidegren

2
Flex benar-benar hanya setengah pengurai; setelah Anda tokenized input, Anda perlu menentukan apa arti token. Inilah gunanya generator parser. Ada banyak dari mereka. ("Parser combinator", "recursive-descent" dan "LALR (1)" adalah kata kunci untuk google.)
jrockway

1
@jrockway: itu benar tentu saja, saya kira saya mengangkat bahu dan berpikir "tetapi jika dia membaca di Flex, dia akan menemukan Bison secara otomatis". :) Terima kasih.
bersantai



1

Jika Anda menggunakan bahasa pemrograman yang memiliki lebih dari tiga pengguna lain, Anda harus dapat menemukan perpustakaan untuk menguraikannya untuk Anda. Google-ing cepat mengungkapkan perpustakaan untuk CL, Haskell, Python, JavaScript, Ruby, dan sebagainya. Sangat tidak mungkin Anda perlu menemukan kembali roda ini.

Jika Anda benar-benar harus menulisnya dari awal, saya sarankan menulis parser yang tepat. Dengan teknik ini, Anda tidak perlu melarikan diri dengan hash MD5. (Saya setuju bahwa jika Anda harus melakukan sesuatu seperti ini, saatnya untuk mempertimbangkan kembali desain Anda.)


Saya siap menghadapi tantangan. Saya melihat perpustakaan tetapi mereka hanya mengerikan. Jelek dan bodoh. Saya sedang mempertimbangkan untuk menulis parser di F # karena saya memerlukan proyek F # tetapi saya mungkin akhirnya akan melakukannya dalam C #.
John Leidegren

Semoga F # memiliki perpustakaan seperti Parsec; jika demikian, ini akan menjadi proyek yang menyenangkan;)
jrockway

0

Ada pustaka yang tersedia dalam sejumlah bahasa, termasuk php, ruby, java, c #, javascript. Saya sarankan mencari beberapa ide ini.

Itu tergantung pada bahasa yang ingin Anda gunakan, untuk cara terbaik untuk mengimplementasikannya, akan ada cara idiomatis dan non idiomatik untuk melakukannya.

Regex bekerja di perl, karena perl dan regex adalah teman terbaik.


1
Regex dan perl adalah teman baik karena seseorang mengatakannya. Tidak ada kebenaran yang lebih dari fakta itu daripada nenek moyang sejarahnya, bahwa itu telah digunakan seperti itu. Saya tidak menggunakan sesuatu seperti perl.
John Leidegren

7
Maka jangan gunakan itu .. Juga, pelajari ironi.
garrow

0

Penurunan harga adalah JAWL (hanya bahasa wiki lainnya)

Ada banyak wiki open source di luar sana yang bisa Anda periksa kode pengurai. Kebanyakan menggunakan REGEX

Lihat wiki screwturn, memiliki pipa formatter multi pass yang menarik, teknik yang sangat bagus - lihat /core/Formatter.cs dan /core/FormatterPipeline.cs

Yang terbaik adalah menggunakan / bergabung dengan proyek yang ada, hal-hal semacam ini selalu jauh lebih sulit daripada yang terlihat


0

Di sini Anda dapat menemukan implementasi JavaScript Markdown. Ini juga sangat bergantung pada ekspresi reguler, karena ini hanya cara tercepat dan termudah untuk mem-parsing teks.

Tetapi suku cadang MD5.

Saya tidak dapat membantu secara langsung dengan pengkodean penguraian, tetapi mungkin tautan ini dapat membantu Anda.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.