08 декември 2008

reStructuredText към html. Скрипт.

Днес написах един доста прост скрипт който конвертира .rst(reStructuredText) файлове в html. Може и да съм блогвал за ResT преди, но ако не съм, този пост ще е малко по подробен от всичко което може би съм споменавал.

Какво е Rest? Това е markup език, но доста по прост от html, в повечето случаи се използва за писане на документация, която после се конвертира в html,pdf,LaTeX и др. формати. Основното предимство на този език е че е мнооого прост. Мога да ви науча на повечето от важните неща на няколко реда, ето един .rst файл, да речем test.rst:


  1. ========  
  2.   
  3. Заглавие  
  4.   
  5. ========  
  6.   
  7.   
  8.   
  9. 1. Първа точка  
  10.   
  11.   
  12.   
  13. Това е параграф, той е просто текст,Това е параграф, той е просто текст,  
  14.   
  15. Това е параграф, той е просто текст,Това е параграф, той е просто текст,  
  16.   
  17. Това е параграф, той е просто текст,Това е параграф, той е просто текст,  
  18.   
  19. Това е параграф, той е просто текст,Това е параграф, той е просто текст,  
  20.   
  21. Това е параграф, той е просто текст,Това е параграф, той е просто текст,  
  22.   
  23. Това е параграф, той е просто текст,Това е параграф, той е просто текст::  
  24.   
  25.   
  26.   
  27.   
  28.   
  29.     def some_code(param):  
  30.   
  31.         for x in param:  
  32.   
  33.             do_someshit()  
  34.   
  35.   
  36.   
  37.   
  38.   
  39. a) това е под хараграф  
  40.   
  41.   
  42.   
  43. Това е параграф, той е просто текст,Това е параграф, той е просто текст,  
  44.   
  45. Това е параграф, той е просто текст,Това е параграф, той е просто текст,  
  46.   
  47. Това е параграф, той е просто текст,Това е параграф, той е просто текст,  
  48.   
  49. Това е параграф, той е просто текст,Това е параграф, той е просто текст,  
  50.   
  51. Това е параграф, той е просто текст,Това е параграф, той е просто текст,  
  52.   
  53.   
  54.   
  55. b) това е друг под параграф:  
  56.   
  57.   
  58.   
  59. Това е параграф, той е просто текст,Това е параграф, той е просто текст,  
  60.   
  61. Това е параграф, той е просто текст,Това е параграф, той е просто текст,  
  62.   
  63. Това е параграф, той е просто текст,Това е параграф, той е просто текст,  
  64.   
  65. Това е параграф, той е просто текст,Това е параграф, той е просто текст,  
  66.   
  67. Това е параграф, той е просто текст,Това е параграф, той е просто текст,  
  68.   
  69.   
  70.   
  71. 2. Втора точка  
  72.   
  73.   
  74.   
  75. Това е параграф, той е просто текст,Това е параграф, той е просто текст,  
  76.   
  77. Това е параграф, той е просто текст,Това е параграф, той е просто текст,  
  78.   
  79. Това е параграф, той е просто текст,Това е параграф, той е просто текст,  
  80.   
  81. Това е параграф, той е просто текст,Това е параграф, той е просто текст,  
  82.   
  83. Това е параграф, той е просто текст,Това е параграф, той е просто текст,  


този файл дори има и грешка при подточка а) :D
Както виждате заглавието е обградено от горе и от долу със '=', което го прави голямо заглавие, подзаглавията, макар и че няма такива в този пример, са само подчертани. За заглавия и подзаглавия може да се използват всякакви знаци('#','@','=','$','-' и др.) Важното е заглавието да е покрито от началото си до края със еднаквите знаци от горе и от долу(няма да работи ако са по къси от заглавието, или ако имат различна дължина), а подзаглавията трябва да са подчертани.

Както може би предполагате, точките и подточките са си част от Markup-а на езика и те дефинират подпараграфи и списъци. А самите параграфи са просто блокове от текст със празни пространства от горе и от долу. Блоковете с код са отместени на дясно, и на предния параграф има двойни двоеточия(::) които по късно стават на единична двоеточие(:). Сега вече знаете достатъчно reStructuredText за да пишете добри документи, за повече подробности посетете сайта им.

Сега, за да ги конвертирате в html или друг формат ви трябва някакъв инструмент, един от най добрите инструменти е Sphinx. Това е изключително мощен инструмент, с чиято помощ е генерирана документацията на python. За моя скрипт аз използвах модула docutils. Ето скриптът:

  1. #!/usr/bin/env python  
  2.   
  3. # -*- coding: utf-8 -*-  
  4.   
  5.   
  6.   
  7. #convert a bunch of RestructuredText files to html  
  8.   
  9. #version 0.3.14  
  10.   
  11.   
  12.   
  13. from docutils.core import publish_string  
  14.   
  15. import sys  
  16.   
  17.   
  18.   
  19. def read_file(f):  
  20.   
  21.     """reads the file, returns a string"""  
  22.   
  23.     i=open(f,'r')  
  24.   
  25.     z=i.read()  
  26.   
  27.     i.close()  
  28.   
  29.     return z  
  30.   
  31.   
  32.   
  33. def converter(rst):  
  34.   
  35.     """turns the rst formated string in to html and returns is as a str"""  
  36.   
  37.     return publish_string(source=rst,writer_name='html')  
  38.   
  39.   
  40.   
  41. def write_to_file(name,content):  
  42.   
  43.     """writes the html string to a file"""  
  44.   
  45.     name=name[:-4]+'.html'  #turn .rst into .html  
  46.   
  47.     o=open(name,'w')  
  48.   
  49.     o.write(content)  
  50.   
  51.     o.close()  
  52.   
  53.   
  54.   
  55. if __name__=='__main__':  
  56.   
  57.     for f in sys.argv[1:]:  
  58.   
  59.         i=read_file(f)  
  60.   
  61.         i=converter(i)  
  62.   
  63.         write_to_file(name=f,content=i)  


ако искате да го използвате, просто го запишете в някакъв файл и му дайте права за изпълнение, и го стартирайте:


$./фяйл списък с файлове за конвертиране


всеки файл ще бъде конвертиран във съответния html файл със същото име(но различно разширение, от .rst на .html) Ето изходът от горния rest файл:

  1. <!--xml version="1.0" encoding="utf-8" ?-->  
  2.   
  3. <!--DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"-->  
  4.   
  5.   
  6.   
  7.   
  8.   
  9. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">  
  10.   
  11. <meta name="generator" content="Docutils 0.5: http://docutils.sourceforge.net/">  
  12.   
  13. <title>Заглавие</title>  
  14.   
  15. <style type="text/css">  
  16.   
  17.   
  18.   
  19. /*  
  20.   
  21. :Author: David Goodger (goodger@python.org)  
  22.   
  23. :Id: $Id: html4css1.css 5196 2007-06-03 20:25:28Z wiemann $  
  24.   
  25. :Copyright: This stylesheet has been placed in the public domain.  
  26.   
  27.   
  28.   
  29. Default cascading style sheet for the HTML output of Docutils.  
  30.   
  31.   
  32.   
  33. See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to  
  34.   
  35. customize this style sheet.  
  36.   
  37. */  
  38.   
  39.   
  40.   
  41. /* used to remove borders from tables and images */  
  42.   
  43. .borderless, table.borderless td, table.borderless th {  
  44.   
  45.   border: 0 }  
  46.   
  47.   
  48.   
  49. table.borderless td, table.borderless th {  
  50.   
  51.   /* Override padding for "table.docutils td" with "! important".  
  52.   
  53.      The right padding separates the table cells. */  
  54.   
  55.   padding: 0 0.5em 0 0 ! important }  
  56.   
  57.   
  58.   
  59. .first {  
  60.   
  61.   /* Override more specific margin styles with "! important". */  
  62.   
  63.   margin-top: 0 ! important }  
  64.   
  65.   
  66.   
  67. .last, .with-subtitle {  
  68.   
  69.   margin-bottom: 0 ! important }  
  70.   
  71.   
  72.   
  73. .hidden {  
  74.   
  75.   display: none }  
  76.   
  77.   
  78.   
  79. a.toc-backref {  
  80.   
  81.   text-decoration: none ;  
  82.   
  83.   color: black }  
  84.   
  85.   
  86.   
  87. blockquote.epigraph {  
  88.   
  89.   margin: 2em 5em ; }  
  90.   
  91.   
  92.   
  93. dl.docutils dd {  
  94.   
  95.   margin-bottom: 0.5em }  
  96.   
  97.   
  98.   
  99. /* Uncomment (and remove this text!) to get bold-faced definition list terms  
  100.   
  101. dl.docutils dt {  
  102.   
  103.   font-weight: bold }  
  104.   
  105. */  
  106.   
  107.   
  108.   
  109. div.abstract {  
  110.   
  111.   margin: 2em 5em }  
  112.   
  113.   
  114.   
  115. div.abstract p.topic-title {  
  116.   
  117.   font-weight: bold ;  
  118.   
  119.   text-align: center }  
  120.   
  121.   
  122.   
  123. div.admonition, div.attention, div.caution, div.danger, div.error,  
  124.   
  125. div.hint, div.important, div.note, div.tip, div.warning {  
  126.   
  127.   margin: 2em ;  
  128.   
  129.   border: medium outset ;  
  130.   
  131.   padding: 1em }  
  132.   
  133.   
  134.   
  135. div.admonition p.admonition-title, div.hint p.admonition-title,  
  136.   
  137. div.important p.admonition-title, div.note p.admonition-title,  
  138.   
  139. div.tip p.admonition-title {  
  140.   
  141.   font-weight: bold ;  
  142.   
  143.   font-family: sans-serif }  
  144.   
  145.   
  146.   
  147. div.attention p.admonition-title, div.caution p.admonition-title,  
  148.   
  149. div.danger p.admonition-title, div.error p.admonition-title,  
  150.   
  151. div.warning p.admonition-title {  
  152.   
  153.   color: red ;  
  154.   
  155.   font-weight: bold ;  
  156.   
  157.   font-family: sans-serif }  
  158.   
  159.   
  160.   
  161. /* Uncomment (and remove this text!) to get reduced vertical space in  
  162.   
  163.    compound paragraphs.  
  164.   
  165. div.compound .compound-first, div.compound .compound-middle {  
  166.   
  167.   margin-bottom: 0.5em }  
  168.   
  169.   
  170.   
  171. div.compound .compound-last, div.compound .compound-middle {  
  172.   
  173.   margin-top: 0.5em }  
  174.   
  175. */  
  176.   
  177.   
  178.   
  179. div.dedication {  
  180.   
  181.   margin: 2em 5em ;  
  182.   
  183.   text-align: center ;  
  184.   
  185.   font-style: italic }  
  186.   
  187.   
  188.   
  189. div.dedication p.topic-title {  
  190.   
  191.   font-weight: bold ;  
  192.   
  193.   font-style: normal }  
  194.   
  195.   
  196.   
  197. div.figure {  
  198.   
  199.   margin-left: 2em ;  
  200.   
  201.   margin-right: 2em }  
  202.   
  203.   
  204.   
  205. div.footer, div.header {  
  206.   
  207.   clear: both;  
  208.   
  209.   font-size: smaller }  
  210.   
  211.   
  212.   
  213. div.line-block {  
  214.   
  215.   display: block ;  
  216.   
  217.   margin-top: 1em ;  
  218.   
  219.   margin-bottom: 1em }  
  220.   
  221.   
  222.   
  223. div.line-block div.line-block {  
  224.   
  225.   margin-top: 0 ;  
  226.   
  227.   margin-bottom: 0 ;  
  228.   
  229.   margin-left: 1.5em }  
  230.   
  231.   
  232.   
  233. div.sidebar {  
  234.   
  235.   margin: 0 0 0.5em 1em ;  
  236.   
  237.   border: medium outset ;  
  238.   
  239.   padding: 1em ;  
  240.   
  241.   background-color: #ffffee ;  
  242.   
  243.   width: 40% ;  
  244.   
  245.   float: right ;  
  246.   
  247.   clear: right }  
  248.   
  249.   
  250.   
  251. div.sidebar p.rubric {  
  252.   
  253.   font-family: sans-serif ;  
  254.   
  255.   font-size: medium }  
  256.   
  257.   
  258.   
  259. div.system-messages {  
  260.   
  261.   margin: 5em }  
  262.   
  263.   
  264.   
  265. div.system-messages h1 {  
  266.   
  267.   color: red }  
  268.   
  269.   
  270.   
  271. div.system-message {  
  272.   
  273.   border: medium outset ;  
  274.   
  275.   padding: 1em }  
  276.   
  277.   
  278.   
  279. div.system-message p.system-message-title {  
  280.   
  281.   color: red ;  
  282.   
  283.   font-weight: bold }  
  284.   
  285.   
  286.   
  287. div.topic {  
  288.   
  289.   margin: 2em }  
  290.   
  291.   
  292.   
  293. h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,  
  294.   
  295. h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {  
  296.   
  297.   margin-top: 0.4em }  
  298.   
  299.   
  300.   
  301. h1.title {  
  302.   
  303.   text-align: center }  
  304.   
  305.   
  306.   
  307. h2.subtitle {  
  308.   
  309.   text-align: center }  
  310.   
  311.   
  312.   
  313. hr.docutils {  
  314.   
  315.   width: 75% }  
  316.   
  317.   
  318.   
  319. img.align-left {  
  320.   
  321.   clear: left }  
  322.   
  323.   
  324.   
  325. img.align-right {  
  326.   
  327.   clear: right }  
  328.   
  329.   
  330.   
  331. ol.simple, ul.simple {  
  332.   
  333.   margin-bottom: 1em }  
  334.   
  335.   
  336.   
  337. ol.arabic {  
  338.   
  339.   list-style: decimal }  
  340.   
  341.   
  342.   
  343. ol.loweralpha {  
  344.   
  345.   list-style: lower-alpha }  
  346.   
  347.   
  348.   
  349. ol.upperalpha {  
  350.   
  351.   list-style: upper-alpha }  
  352.   
  353.   
  354.   
  355. ol.lowerroman {  
  356.   
  357.   list-style: lower-roman }  
  358.   
  359.   
  360.   
  361. ol.upperroman {  
  362.   
  363.   list-style: upper-roman }  
  364.   
  365.   
  366.   
  367. p.attribution {  
  368.   
  369.   text-align: right ;  
  370.   
  371.   margin-left: 50% }  
  372.   
  373.   
  374.   
  375. p.caption {  
  376.   
  377.   font-style: italic }  
  378.   
  379.   
  380.   
  381. p.credits {  
  382.   
  383.   font-style: italic ;  
  384.   
  385.   font-size: smaller }  
  386.   
  387.   
  388.   
  389. p.label {  
  390.   
  391.   white-space: nowrap }  
  392.   
  393.   
  394.   
  395. p.rubric {  
  396.   
  397.   font-weight: bold ;  
  398.   
  399.   font-size: larger ;  
  400.   
  401.   color: maroon ;  
  402.   
  403.   text-align: center }  
  404.   
  405.   
  406.   
  407. p.sidebar-title {  
  408.   
  409.   font-family: sans-serif ;  
  410.   
  411.   font-weight: bold ;  
  412.   
  413.   font-size: larger }  
  414.   
  415.   
  416.   
  417. p.sidebar-subtitle {  
  418.   
  419.   font-family: sans-serif ;  
  420.   
  421.   font-weight: bold }  
  422.   
  423.   
  424.   
  425. p.topic-title {  
  426.   
  427.   font-weight: bold }  
  428.   
  429.   
  430.   
  431. pre.address {  
  432.   
  433.   margin-bottom: 0 ;  
  434.   
  435.   margin-top: 0 ;  
  436.   
  437.   font-family: serif ;  
  438.   
  439.   font-size: 100% }  
  440.   
  441.   
  442.   
  443. pre.literal-block, pre.doctest-block {  
  444.   
  445.   margin-left: 2em ;  
  446.   
  447.   margin-right: 2em }  
  448.   
  449.   
  450.   
  451. span.classifier {  
  452.   
  453.   font-family: sans-serif ;  
  454.   
  455.   font-style: oblique }  
  456.   
  457.   
  458.   
  459. span.classifier-delimiter {  
  460.   
  461.   font-family: sans-serif ;  
  462.   
  463.   font-weight: bold }  
  464.   
  465.   
  466.   
  467. span.interpreted {  
  468.   
  469.   font-family: sans-serif }  
  470.   
  471.   
  472.   
  473. span.option {  
  474.   
  475.   white-space: nowrap }  
  476.   
  477.   
  478.   
  479. span.pre {  
  480.   
  481.   white-space: pre }  
  482.   
  483.   
  484.   
  485. span.problematic {  
  486.   
  487.   color: red }  
  488.   
  489.   
  490.   
  491. span.section-subtitle {  
  492.   
  493.   /* font-size relative to parent (h1..h6 element) */  
  494.   
  495.   font-size: 80% }  
  496.   
  497.   
  498.   
  499. table.citation {  
  500.   
  501.   border-left: solid 1px gray;  
  502.   
  503.   margin-left: 1px }  
  504.   
  505.   
  506.   
  507. table.docinfo {  
  508.   
  509.   margin: 2em 4em }  
  510.   
  511.   
  512.   
  513. table.docutils {  
  514.   
  515.   margin-top: 0.5em ;  
  516.   
  517.   margin-bottom: 0.5em }  
  518.   
  519.   
  520.   
  521. table.footnote {  
  522.   
  523.   border-left: solid 1px black;  
  524.   
  525.   margin-left: 1px }  
  526.   
  527.   
  528.   
  529. table.docutils td, table.docutils th,  
  530.   
  531. table.docinfo td, table.docinfo th {  
  532.   
  533.   padding-left: 0.5em ;  
  534.   
  535.   padding-right: 0.5em ;  
  536.   
  537.   vertical-align: top }  
  538.   
  539.   
  540.   
  541. table.docutils th.field-name, table.docinfo th.docinfo-name {  
  542.   
  543.   font-weight: bold ;  
  544.   
  545.   text-align: left ;  
  546.   
  547.   white-space: nowrap ;  
  548.   
  549.   padding-left: 0 }  
  550.   
  551.   
  552.   
  553. h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,  
  554.   
  555. h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {  
  556.   
  557.   font-size: 100% }  
  558.   
  559.   
  560.   
  561. ul.auto-toc {  
  562.   
  563.   list-style-type: none }  
  564.   
  565.   
  566.   
  567. </style>  
  568.   
  569.   
  570.   
  571.   
  572.   
  573. <div class="document" id="id1">  
  574.   
  575. <h1 class="title">Заглавие</h1>  
  576.   
  577.   
  578.   
  579. <ol class="arabic simple">  
  580.   
  581. <li>Първа точка</li>  
  582.   
  583. </ol>  
  584.   
  585. <p>Това е параграф, той е просто текст,Това е параграф, той е просто текст,  
  586.   
  587. Това е параграф, той е просто текст,Това е параграф, той е просто текст,  
  588.   
  589. Това е параграф, той е просто текст,Това е параграф, той е просто текст,  
  590.   
  591. Това е параграф, той е просто текст,Това е параграф, той е просто текст,  
  592.   
  593. Това е параграф, той е просто текст,Това е параграф, той е просто текст,  
  594.   
  595. Това е параграф, той е просто текст,Това е параграф, той е просто текст:</p>  
  596.   
  597. <pre class="literal-block">  
  598. def some_code(param):  
  599.   
  600.     for x in param:  
  601.   
  602.         do_someshit()  
  603.   
  604. </pre>  
  605.   
  606. <ol class="loweralpha simple">  
  607.   
  608. <li>това е под хараграф</li>  
  609.   
  610. </ol>  
  611.   
  612. <p>Това е параграф, той е просто текст,Това е параграф, той е просто текст,  
  613.   
  614. Това е параграф, той е просто текст,Това е параграф, той е просто текст,  
  615.   
  616. Това е параграф, той е просто текст,Това е параграф, той е просто текст,  
  617.   
  618. Това е параграф, той е просто текст,Това е параграф, той е просто текст,  
  619.   
  620. Това е параграф, той е просто текст,Това е параграф, той е просто текст,</p>  
  621.   
  622. <ol class="loweralpha simple" start="2">  
  623.   
  624. <li>това е друг под параграф:</li>  
  625.   
  626. </ol>  
  627.   
  628. <p>Това е параграф, той е просто текст,Това е параграф, той е просто текст,  
  629.   
  630. Това е параграф, той е просто текст,Това е параграф, той е просто текст,  
  631.   
  632. Това е параграф, той е просто текст,Това е параграф, той е просто текст,  
  633.   
  634. Това е параграф, той е просто текст,Това е параграф, той е просто текст,  
  635.   
  636. Това е параграф, той е просто текст,Това е параграф, той е просто текст,</p>  
  637.   
  638. <ol class="arabic simple" start="2">  
  639.   
  640. <li>Втора точка</li>  
  641.   
  642. </ol>  
  643.   
  644. <p>Това е параграф, той е просто текст,Това е параграф, той е просто текст,  
  645.   
  646. Това е параграф, той е просто текст,Това е параграф, той е просто текст,  
  647.   
  648. Това е параграф, той е просто текст,Това е параграф, той е просто текст,  
  649.   
  650. Това е параграф, той е просто текст,Това е параграф, той е просто текст,  
  651.   
  652. Това е параграф, той е просто текст,Това е параграф, той е просто текст,</p>  
  653.   
  654. </div>  


Надявам се този пост да е бил полезен до някъде :D

1 коментар:

vvv каза...
Този коментар бе премахнат от администратор на блога.