md2pdf

python tool that converts markdown files to pdf
git clone git://parazyd.org/md2pdf.git | https://git.parazyd.org/md2pdf
Log | Files | Refs | README | LICENSE

md2pdf (21060B)


      1 #!/usr/bin/env python3
      2 #
      3 # Copyright (c) 2018 Ivan Jelincic <parazyd@dyne.org>
      4 # md2pdf is written and maintained by Ivan Jelincic <parazyd@dyne.org>
      5 #
      6 # This file is part of md2pdf
      7 #
      8 # This program is free software: you can redistribute it and/or modify
      9 # it under the terms of the GNU General Public License as published by
     10 # the Free Software Foundation, either version 3 of the License, or
     11 # (at your option) any later version.
     12 #
     13 # This program is distributed in the hope that it will be useful,
     14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16 # GNU General Public License for more details.
     17 #
     18 # You should have received a copy of the GNU General Public License
     19 # along with this program.  If not, see <https://www.gnu.org/licenses/>.
     20 """
     21 Main md2pdf module.
     22 """
     23 
     24 from os import remove
     25 from random import randint
     26 from sys import stdin, stdout
     27 
     28 from weasyprint import HTML
     29 from markdown import markdown
     30 
     31 # {{{ github.css stylesheet
     32 STYLESHEET = """
     33 /*------------------------------------------------------------------------------
     34      Global Documentation Styles
     35 ------------------------------------------------------------------------------*/
     36 
     37 html {
     38   height:100%;
     39 }
     40 
     41 body {
     42   font: 13px helvetica,arial,freesans,clean,sans-serif;
     43   line-height: 1.4em;
     44   background-color: #fff;
     45   color: #393939;
     46   margin: 0px;
     47   padding: 0px;
     48   height: 100%;
     49 }
     50 
     51 p {
     52   margin: 1em 0;
     53 }
     54 
     55 h1 {
     56   font-size: 20px;
     57   border-bottom: 1px solid #cccccc;
     58   padding: .5em 0;
     59   margin: 2em 0 1em;
     60 }
     61 
     62 h1:first-child {
     63   margin: 0 0 1em;
     64 }
     65 
     66 h2 {
     67   font-size: 16px;
     68   color: #333;
     69   margin: 2em auto 1em;
     70 }
     71 
     72   body.api .content h2 {
     73     background: transparent url(../images/crud-sprite.png) left 2px no-repeat;
     74     padding-left: 22px;
     75   }
     76 
     77 h2 span.step {
     78   color: #666;
     79 }
     80 
     81 h3 {
     82   font-size: 14px;
     83   color: #333;
     84   margin: 1.5em 0 .5em;
     85 }
     86 
     87 h5 {
     88   font-size: 13px;
     89 }
     90 
     91 h6 {
     92   font-size: 13px;
     93   color: #666;
     94 }
     95 
     96 a {
     97   color: #4183C4;
     98   text-decoration: none;
     99 }
    100 
    101 a:hover,
    102 a:active {
    103   text-decoration:underline;
    104 }
    105 
    106 blockquote {
    107   margin:0 -5px;
    108   padding: 0px 20px;
    109 }
    110 
    111 ul,
    112 ol {
    113   margin: 0px;
    114   padding: 0px;
    115 }
    116 
    117 dt {
    118   font-weight: bold;
    119 }
    120 
    121 dd {
    122   padding-left: 1em;
    123   margin-bottom: 1em;
    124 }
    125 
    126 dd + dd {
    127   margin-bottom: 0;
    128 }
    129 
    130 span.attention,
    131 p.attention {
    132   color: #e98400;
    133   font-style: italic;
    134 }
    135 
    136 a img {
    137   border: 0px;
    138 }
    139 
    140 /*------------------------------------------------------------------------------
    141      Header Styles
    142 ------------------------------------------------------------------------------*/
    143 
    144 #header-wrapper {
    145   margin-bottom: 0;
    146   clear: both;
    147   height: 91px;
    148   background: white url(../images/background-v2.png) 0 0 repeat-x;
    149 }
    150 
    151 #header {
    152   margin: 0 auto;
    153   width: 920px;
    154 }
    155 
    156 #header a.logo {
    157   float: left;
    158   margin-top: 15px;
    159   display: inline-block;
    160 }
    161 
    162 #header ul.nav {
    163   float: right;
    164   padding: 8px 3px 8px 2px;
    165   font-weight: bold;
    166   text-shadow: white 1px 1px 0px;
    167   font-size: 12px;
    168   margin-top: 18px;
    169   background: #f5f5f5;
    170   filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#fcfcfc', endColorstr='#ececec');
    171   background:-webkit-gradient(linear, 0% 0%, 0% 100%, from(#fcfcfc), to(#e8e8e8));
    172   background:-moz-linear-gradient(270deg, #fcfcfc, #ececec);
    173   border-color:#eee;
    174   border:1px solid #e9e9e9;
    175   border-bottom-color:#f5f5f5;
    176   -webkit-border-radius:5px;
    177   -moz-border-radius:5px;
    178   border-radius:5px;
    179   -webkit-box-shadow:0 1px 1px rgba(0,0,0,0.2);
    180   -moz-box-shadow:0 1px 1px rgba(0,0,0,0.2);
    181   box-shadow:0 1px 1px rgba(0,0,0,0.2);
    182 }
    183 
    184 #header ul.nav li:first-child {
    185   background: transparent;
    186 }
    187 
    188 #header ul.nav li {
    189   float: left;
    190   margin: 0;
    191   padding: 0px 11px 0px 13px;
    192   list-style-type: none;
    193   background: url(../images/nav-rule.png) no-repeat 0px 50%;
    194   line-height: 1.4em;
    195 }
    196 
    197 #header a {
    198   outline: none;
    199   text-decoration: none;
    200 }
    201 
    202 /*------------------------------------------------------------------------------
    203      Sidebar
    204 ------------------------------------------------------------------------------*/
    205 
    206 div.sidebar-shell {
    207   position: relative;
    208   float: right;
    209   margin: 35px 0 0;
    210 }
    211 
    212 div.sidebar-module {
    213   padding: 3px;
    214   background: #EEE;
    215   -moz-border-radius: 3px;
    216   -webkit-border-radius: 3px;
    217   border-radius: 3px;
    218   display: block;
    219   width: 332px;
    220   margin-bottom: 20px;
    221   font-size: 12px;
    222 }
    223 
    224 div.sidebar-module > ul {
    225   background: #fafafb;
    226   border: solid #CACACA;
    227   border-width: 1px 1px 0px 1px;
    228   margin: 0px;
    229 }
    230 
    231 div.sidebar-module > p {
    232   background: #fafafb;
    233   border: solid #CACACA;
    234   border-width: 1px;
    235   padding: 8px 10px;
    236   margin: 0px;
    237   display: block;
    238   line-height: 1.4em;
    239 }
    240 
    241 div.sidebar-module li {
    242   list-style-type: none;
    243 }
    244 
    245 div.sidebar-module > ul > li {
    246   border-bottom: 1px solid #CACACA;
    247   text-decoration: none;
    248 }
    249 
    250 div.sidebar-module > ul > li:hover {
    251   text-decoration: none;
    252 }
    253 
    254 
    255 div.sidebar-module > ul h3 {
    256   margin: 0px;
    257   color: #666;
    258   text-shadow: 1px 1px 0px #fff;
    259   border-bottom: 1px solid #CACACA;
    260   font-size: 14px;
    261   background-color: #e1e1e1;
    262   background-image: -moz-linear-gradient(top, #f1f1f1, #e1e1e1);
    263   background-image: -ms-linear-gradient(top, #f1f1f1, #e1e1e1);
    264   background-image: -o-linear-gradient(top, #f1f1f1, #e1e1e1);
    265   background-image: -webkit-gradient(linear, left top, left bottom, from(#f1f1f1), to(#e1e1e1));
    266   background-image: -webkit-linear-gradient(top, #f1f1f1, #e1e1e1);
    267   background-image: linear-gradient(top, #f1f1f1, #e1e1e1);
    268   filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#f1f1f1', EndColorStr='#e1e1e1');
    269 }
    270 
    271 div.sidebar-module > ul li h3:hover,
    272 div.sidebar-module > ul h3.disable {
    273   background-color: #e1e1e1;
    274   background-image: -moz-linear-gradient(top, #e1e1e1, #d1d1d1);
    275   background-image: -ms-linear-gradient(top, #e1e1e1, #d1d1d1);
    276   background-image: -o-linear-gradient(top, #e1e1e1, #d1d1d1);
    277   background-image: -webkit-gradient(linear, left top, left bottom, from(#e1e1e1), to(#d1d1d1));
    278   background-image: -webkit-linear-gradient(top, #e1e1e1, #d1d1d1);
    279   background-image: linear-gradient(top, #e1e1e1, #d1d1d1);
    280   filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#e1e1e1', EndColorStr='#d1d1d1');
    281 }
    282 
    283 
    284 div.sidebar-module > ul h3 a,
    285 div.sidebar-module > ul h3.disable span {
    286   padding: 8px 0px 8px 10px;
    287   color: #666;
    288   display: block;
    289   text-decoration: none;
    290 }
    291 
    292 div.sidebar-module > ul h3.disable span {
    293   padding-left: 20px;
    294   background-image: url(../images/active-arrow.png);
    295   background-position: left center;
    296   background-repeat: no-repeat;
    297   cursor: default;
    298 }
    299 div.sidebar-module > ul h3:hover a {
    300   text-decoration: none;
    301 }
    302 
    303 div.sidebar-module ul ul,
    304 div.sidebar-module .spacer {
    305   display: block;
    306   padding-bottom: 2px;
    307   background-color: #FAFAFB;
    308 }
    309 
    310 div.sidebar-module ul ul li {
    311   border-top: 1px solid #fff;
    312   border-bottom: 1px solid #e9ecee;
    313   font-weight: bold;
    314   color: #666;
    315 }
    316 
    317 div.sidebar-module ul ul li:hover,
    318 div.sidebar-module li.disable {
    319   border-top: 1px solid #fafafb;
    320   border-bottom: 1px solid #e5e8ea;
    321   background-color: #f0f0f3;
    322 }
    323 
    324 div.sidebar-module li.disable {
    325   background-image: url(../images/active-arrow.png);
    326   background-position: left center;
    327   background-repeat: no-repeat;
    328 }
    329 
    330 div.sidebar-module ul ul li a,
    331 div.sidebar-module ul ul li span {
    332   padding: 6px 0px 6px 10px;
    333   display: block;
    334   text-decoration: none;
    335 }
    336 
    337 div.sidebar-module ul ul li span {
    338   padding-left: 20px;
    339   cursor: default;
    340 }
    341 
    342 /* @end */
    343 
    344 /*****************************************************************************/
    345 /*
    346 /* Footer
    347 /*
    348 /*****************************************************************************/
    349 
    350 
    351 
    352 #footer {
    353   position: relative;
    354   bottom:0;
    355   font-size:13px;
    356   color: #636363;
    357   margin: 45px 0 0 0;
    358 }
    359 
    360 #footer a:hover {
    361   text-decoration: underline;
    362 }
    363 
    364 #footer li {
    365   list-style: none;
    366 }
    367 
    368 .footer_inner {
    369   width:960px;
    370   position: relative;
    371   margin: 0 auto;
    372 }
    373 
    374 #footer .upper_footer {
    375   min-height: 160px;
    376   overflow: hidden;
    377   background: url(../images/bg_footer_top.png) #f8f8f8 repeat-x;
    378 }
    379 
    380 #footer #blacktocat {
    381   height:130px;
    382   width:164px;
    383   float:left;
    384   background: url(../images/blacktocat.png) top left no-repeat;
    385   text-indent: -5000px;
    386   margin: 15px 20px 0 0;
    387 }
    388 
    389 #footer #blacktocat_ie {
    390   height:130px;
    391   width:164px;
    392   float:left;
    393   background: url(../images/blacktocat.png) no-repeat;
    394   text-indent: -5000px;
    395   margin: 15px 20px 0 0;
    396 }
    397 
    398 #footer .upper_footer ul.footer_nav {
    399   position: relative;
    400   float: left;
    401   width: 164px;
    402   margin: 20px 10px;
    403 }
    404 
    405 #footer .upper_footer ul.footer_nav h4 {
    406   margin: 0 0 5px 0;
    407   padding-bottom: 5px;
    408   border-bottom: thin solid #e1e1e1;
    409 }
    410 
    411 #footer .lower_footer {
    412   position: relative;
    413   background:url(../images/bg_footer_bottom.png) #fff repeat-x;
    414   overflow: hidden;
    415   clear:both;
    416 }
    417 
    418 #footer .lower_footer .home {
    419   display: block;
    420   position: absolute;
    421   background: url(../images/footer-logo.png) top left no-repeat;
    422   width: 100px;
    423   height: 50px;
    424   text-indent: -5000px;
    425 }
    426 
    427 #footer .lower_footer .home_ie {
    428   display: block;
    429   position: absolute;
    430   background: url(../images/footer-logo.png) top left no-repeat;
    431   width: 100px;
    432   height: 50px;
    433   text-indent: -5000px;
    434 }
    435 
    436 #footer .lower_footer #legal {
    437   float: left;
    438   width: 500px;
    439   height: 50px;
    440   line-height: 8px;
    441   margin: 25px 0 0 17px;
    442 }
    443 
    444 #footer .lower_footer #legal #legal_links {
    445   margin-left: 177px;
    446 }
    447 
    448 #footer .lower_footer div ul {
    449   float: left;
    450   text-indent: none;
    451   display:inline;
    452   margin-top: 15px;
    453 
    454 }
    455 
    456 #footer .lower_footer div ul li {
    457   display:inline;
    458   float: left;
    459   margin:  0 10px 0 0;
    460 }
    461 
    462 #footer .lower_footer div p {
    463   display:inline;
    464   float:left;
    465   clear: both;
    466   margin: 10px 0 0 177px;
    467 }
    468 
    469 #footer .lower_footer .sponsor {
    470   width: 295px;
    471   float: right;
    472   margin-top: 35px;
    473   padding-bottom: 25px;
    474 }
    475 
    476 #footer .lower_footer .sponsor .logo {
    477  float:left;
    478  margin: 0 10px 0 0;
    479 }
    480 
    481 #footer .lower_footer .sponsor a {
    482   color: #000;
    483 }
    484 
    485 /* end */
    486 
    487 /*------------------------------------------------------------------------------
    488     Not Footer
    489 ------------------------------------------------------------------------------*/
    490 #wrapper {
    491   padding: 20px 25px;
    492   overflow:hidden;
    493   height: auto;
    494   width: 920px;
    495   margin: -20px auto 0;
    496   background: url(../images/background-white.png) 0 0 no-repeat;
    497 }
    498 
    499 .content {
    500   width: 560px;
    501   position: relative;
    502   float: left;
    503   color: #393939;
    504   z-index: 2;
    505 }
    506 
    507 .content dl {
    508   margin-left: 10px;
    509 }
    510 
    511 .content dt {
    512   color: #666;
    513 }
    514 
    515 .content ul,
    516 .content ol {
    517   margin-left: 1.5em;
    518 }
    519 
    520 .content ul {
    521   list-style-type: disc;
    522 }
    523 
    524 .content img {
    525   max-width: 100%;
    526   border: 1px solid #dddddd;
    527   -webkit-box-shadow: 1px 1px 3px #ddd;
    528   -moz-box-shadow: 1px 1px 3px #ddd;
    529   box-shadow: 1px 1px 3px #ddd;
    530 }
    531 
    532 
    533 .content .description {
    534   margin-left: 20px;
    535 }
    536 
    537 .content .verseblock-content {
    538   padding: 3px;
    539 }
    540 
    541 .content .verseblock-content,
    542 .content .sectionbody .dlist dt,
    543 .content p > tt,
    544 .content dl code,
    545 .content ul code,
    546 p code {
    547   font: 12px Monaco,"Courier New","DejaVu Sans Mono","Bitstream Vera Sans Mono",monospace;
    548   color: #52595d;
    549   -webkit-border-radius: 3px;
    550   -moz-border-radius: 3px;
    551   border-radius: 3px;
    552   -moz-background-clip: padding;
    553   -webkit-background-clip: padding-box;
    554   background-clip: padding-box;
    555   border: 1px solid #ccc;
    556   background-color: #f9f9f9;
    557   padding: 0px 3px;
    558   display: inline-block;
    559 }
    560 
    561 .content .sectionbody .dlist dt {
    562   margin-top: 10px;
    563 }
    564 
    565 .content .verseblock-content {
    566   padding: 3px;
    567 }
    568 
    569 .content .intro {
    570   color: #868686;
    571 }
    572 /* @end */
    573 
    574 /*------------------------------------------------------------------------------
    575      Pre/Code Styles
    576 ------------------------------------------------------------------------------*/
    577 
    578 code {white-space: nowrap;}
    579 
    580 pre {
    581   border: 1px solid #cacaca;
    582   line-height: 1.2em;
    583   font: 12px Monaco,"Courier New","DejaVu Sans Mono","Bitstream Vera Sans Mono",monospace;
    584   padding: 10px;
    585   overflow:auto;
    586   -webkit-border-radius: 3px;
    587   -moz-border-radius: 3px;
    588   border-radius: 3px;
    589   -moz-background-clip: padding;
    590   -webkit-background-clip: padding-box;
    591   background-clip: padding-box;
    592   background-color: #FAFAFB;
    593   color: #393939;
    594   margin: 0px;
    595 }
    596 
    597 ul + pre {
    598   margin-top: 1em;
    599 }
    600 
    601 pre code {white-space: pre;}
    602 
    603 pre span.comment {color: #aaa;}
    604 
    605 pre.headers {
    606   margin-bottom: 0;
    607   border-bottom-width: 0;
    608   -webkit-border-radius: 3px 3px 0 0;
    609   -moz-border-radius: 3px 3px 0 0;
    610   border-radius: 3px 3px 0 0;
    611   color: #666;
    612   background-color: #f1f1f1;
    613   background-image: -moz-linear-gradient(top, #f1f1f1, #e1e1e1);
    614   background-image: -ms-linear-gradient(top, #f1f1f1, #e1e1e1);
    615   background-image: -o-linear-gradient(top, #f1f1f1, #e1e1e1);
    616   background-image: -webkit-gradient(linear, left top, left bottom, from(#f1f1f1), to(#e1e1e1));
    617   background-image: -webkit-linear-gradient(top, #f1f1f1, #e1e1e1);
    618   background-image: linear-gradient(top, #f1f1f1, #e1e1e1);
    619   filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#f1f1f1', EndColorStr='#e1e1e1');
    620   text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7);
    621 }
    622 
    623 pre.no-response {
    624   -webkit-border-radius: 3px 3px;
    625   -moz-border-radius: 3px 3px;
    626   border-radius: 3px 3px;
    627   border-bottom: 1px solid #CACACA;
    628 }
    629 
    630 pre.headers + pre.highlight {
    631   -webkit-border-radius: 0 0 3px 3px;
    632   -moz-border-radius: 0 0 3px 3px;
    633   border-radius: 0 0 3px 3px;
    634 }
    635 
    636 pre.highlight {
    637   -webkit-border-radius:3px;
    638   -moz-border-radius:3px;
    639   border-radius:3px;
    640   background-color: #FAFAFB;
    641 }
    642 
    643 pre.terminal {
    644   background-color: #444;
    645   color: #fff;
    646   -webkit-border-radius: 3px;
    647   -moz-border-radius: 3px;
    648   border-radius: 3px;
    649   -moz-background-clip: padding;
    650   -webkit-background-clip: padding-box;
    651   background-clip: padding-box;
    652   border: 2px solid #DEDEDE;
    653   position: relative;
    654   padding: 10px;
    655   text-shadow: none;
    656   background-image: none;
    657   filter: none;
    658 }
    659 
    660 pre.terminal em {
    661   color: #f9fe64;
    662 }
    663 
    664 span.codeline {
    665   display: block;
    666   position: relative;
    667 }
    668 
    669 span.codeline:hover {
    670   background-color: #292929;
    671   margin: 0px;
    672   padding-left: 3px;
    673   margin-left: -3px;
    674   -webkit-border-radius: 3px;
    675   -moz-border-radius: 3px;
    676   border-radius: 3px;
    677   color: #666666;
    678 }
    679 
    680 span.codeline span {
    681   display: inline-block;
    682   font-size: 10px;
    683   color: #fff;
    684   padding: 0 0.3em 0.05em;
    685   position: absolute;
    686   right: 0px;
    687   top: 0px;
    688   text-indent: -9999px;
    689   background-image: url(../images/qmark.png);
    690   background-repeat: no-repeat;
    691   background-position: 1px 3px;
    692   max-width: 8px;
    693   min-width: 8px;
    694   -moz-user-select: none;
    695   -khtml-user-select: none;
    696   user-select: none;
    697   cursor: default;
    698 }
    699 
    700 span.codeline span:hover {
    701   display: inline-block;
    702   text-indent: 0px;
    703   -webkit-border-radius: 3px;
    704   -moz-border-radius: 3px;
    705   border-radius: 3px;
    706   background: #000;
    707   border: 1px solid #292929;
    708   max-width: 1000px;
    709 }
    710 
    711 span.codeline:hover em {
    712   color: #666666;
    713 }
    714 
    715 pre.bootcamp {
    716   white-space: normal;
    717   margin-left: -10px;
    718   background-image: none;
    719 }
    720 
    721 span.bash-output {
    722   color: #63e463;
    723   display: block;
    724   position: relative;
    725   -moz-user-select: none;
    726   -khtml-user-select: none;
    727   user-select: none;
    728 }
    729 
    730 /* end */
    731 
    732 /*------------------------------------------------------------------------------
    733     More Info Expander
    734 ------------------------------------------------------------------------------*/
    735 
    736 .more-info {
    737   margin: 10px 0;
    738   position: relative;
    739 }
    740 .more-info > h4 {
    741   background-image: url('../images/dropdown_sprites.jpg');
    742   background-repeat: no-repeat;
    743   padding: .25em 0 .25em 25px;
    744   cursor: pointer;
    745   color: #4183C4;
    746   font-weight: normal;
    747 }
    748 .more-info h4.compressed {
    749   background-position: 0 0;
    750 }
    751 .more-info:hover h4.compressed {
    752   background-position: 0 -23px;
    753 }
    754 .more-info h4.expanded {
    755   background-position: 0 -46px;
    756 }
    757 .more-info:hover h4.expanded {
    758   background-position: 0 -69px;
    759 }
    760 
    761 .more-info .more-content {
    762   display: none;
    763   -webkit-border-radius: 3px;
    764   -moz-border-radius: 3px;
    765   border-radius: 3px;
    766   background-color: #FFFFFF;
    767   border: 3px solid #DDDDDD;
    768   padding: 1em 2em;
    769   -webkit-box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.3);
    770   -moz-box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.3);
    771   box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.3);
    772   margin: 15px 0 30px;
    773 }
    774 
    775 .more-info .more-content h4 {
    776   margin-top: 1em;
    777 }
    778 
    779 .more-info .more-content pre {
    780   margin-left: 0px;
    781 }
    782 
    783 /****************************/
    784 /*       List Module        */
    785 /****************************/
    786 
    787 .list-module h2 {
    788   border: solid #cacaca;
    789   border-width: 1px;
    790   border-radius: 3px 3px 0px 0px;
    791   -moz-border-radius: 3px 3px 0px 0px;
    792   -webkit-border-bottom-right-radius: 0px;
    793   -webkit-border-bottom-left-radius: 0px;
    794   -moz-background-clip: padding;
    795   -webkit-background-clip: padding-box;
    796   background-clip: padding-box;
    797   padding: 6px 10px;
    798   background-color: #f1f1f1;
    799   background-image: -moz-linear-gradient(top, #f1f1f1, #e1e1e1);
    800   background-image: -ms-linear-gradient(top, #f1f1f1, #e1e1e1);
    801   background-image: -o-linear-gradient(top, #f1f1f1, #e1e1e1);
    802   background-image: -webkit-gradient(linear, left top, left bottom, from(#f1f1f1), to(#e1e1e1));
    803   background-image: -webkit-linear-gradient(top, #f1f1f1, #e1e1e1);
    804   background-image: linear-gradient(top, #f1f1f1, #e1e1e1);
    805   filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#f1f1f1', EndColorStr='#e1e1e1');
    806   color: #666;
    807   text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7);
    808   font-size: 16px;
    809   line-height: 22px;
    810   margin: 0px;
    811 }
    812 
    813 .list-module .list-body {
    814   border: solid #cacaca;
    815   border-width: 0px 1px 1px 1px;
    816   border-radius: 0px 0px 3px 3px;
    817   -moz-border-radius: 0px 0px 3px 3px;
    818   -webkit-border-bottom-right-radius: 3px;
    819   -webkit-border-bottom-left-radius: 3px;
    820   -moz-background-clip: padding;
    821   -webkit-background-clip: padding-box;
    822   background-clip: padding-box;
    823   background-color: #fafafb;
    824   color: #666;
    825   text-shadow: 0 1px 0 rgba(255, 255, 255, 0.7);
    826 }
    827 
    828 .list-module .list-body .icon {
    829   display: block;
    830   height: 28px;
    831   width: 28px;
    832   position: absolute;
    833   top: 10px;
    834   left: 10px;
    835   background: transparent url(images/popular_guide_sprites.png) 0 0 no-repeat;
    836 }
    837 
    838 .list-module a {
    839   border-top: 1px solid #fff;
    840   border-bottom: 1px solid #e9ecee;
    841   padding: 6px 10px;
    842   position: relative;
    843   display: block;
    844 }
    845 
    846 .list-module a:hover {
    847   border-top: 1px solid #fafafb;
    848   border-bottom: 1px solid #e5e8ea;
    849   background-color: #f0f0f3;
    850   text-decoration: none;
    851 }
    852 
    853 .list-module a h3 {
    854   color: #4183C4;
    855 }
    856 
    857 .list-module a:hover h3 {
    858   text-decoration: underline;
    859 }
    860 
    861 .list-module ul {
    862   list-style-type: none;
    863   margin: 0px;
    864 }
    865 
    866 .list-module h3 {
    867   margin: 0px;
    868   font-size: 13px;
    869 }
    870 
    871 .list-module .list-body a p {
    872   color: #666;
    873   margin: 0px;
    874 }
    875 
    876 /* @end */
    877 
    878 /****************************/
    879 /*  Expandable List Module  */
    880 /****************************/
    881 
    882 div.expandable > ul h3 {
    883   display: table;
    884   width: 100%;
    885 }
    886 
    887 div.expandable > ul h3 > a {
    888   display: table-cell;
    889   background-color: #e1e1e1;
    890   background-image: -moz-linear-gradient(top, #f1f1f1, #e1e1e1);
    891   background-image: -ms-linear-gradient(top, #f1f1f1, #e1e1e1);
    892   background-image: -o-linear-gradient(top, #f1f1f1, #e1e1e1);
    893   background-image: -webkit-gradient(linear, left top, left bottom, from(#f1f1f1), to(#e1e1e1));
    894   background-image: -webkit-linear-gradient(top, #f1f1f1, #e1e1e1);
    895   background-image: linear-gradient(top, #f1f1f1, #e1e1e1);
    896   filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#f1f1f1', EndColorStr='#e1e1e1');
    897 }
    898 
    899 div.expandable > ul h3 > a:hover {
    900   background-color: #e1e1e1;
    901   background-image: -moz-linear-gradient(top, #e1e1e1, #d1d1d1);
    902   background-image: -ms-linear-gradient(top, #e1e1e1, #d1d1d1);
    903   background-image: -o-linear-gradient(top, #e1e1e1, #d1d1d1);
    904   background-image: -webkit-gradient(linear, left top, left bottom, from(#e1e1e1), to(#d1d1d1));
    905   background-image: -webkit-linear-gradient(top, #e1e1e1, #d1d1d1);
    906   background-image: linear-gradient(top, #e1e1e1, #d1d1d1);
    907   filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#e1e1e1', EndColorStr='#d1d1d1');
    908 }
    909 
    910 div.expandable > ul h3 > a.collapsed,
    911 div.expandable > ul h3 > a.expanded {
    912   background-image: url(/shared/images/expand-arrows.png);
    913   background-position: 0px -3px;
    914   background-repeat: no-repeat;
    915   width: 13px;
    916   border-right: 1px solid #cacaca;
    917   padding: 8px 11px;
    918 }
    919 
    920 div.expandable > ul h3 > a.expanded {
    921   background-position: -38px -3px;
    922 }
    923 
    924 div.expandable > ul h3 > a.collapsed:hover {
    925   background-image: url(/shared/images/expand-arrows.png);
    926   background-position: 0px -43px;
    927   background-repeat: no-repeat;
    928   width: 13px;
    929   border-right: 1px solid #cacaca;
    930   padding: 8px 11px;
    931 }
    932 
    933 div.expandable > ul h3 > a.expanded:hover {
    934   background-position: -38px -43px;
    935 }
    936 
    937 /* @end */
    938 """
    939 # }}}
    940 
    941 def main():
    942     """
    943     Main routine.
    944     """
    945     html = markdown(stdin.read())
    946 
    947     if stdout.isatty():
    948         print("Output is a tty. Redirect it to a file.")
    949         return
    950 
    951     css_file = '/tmp/md2pdf-%d.css' % randint(9999, 99999)
    952     with open(css_file, 'w') as file:
    953         file.write(STYLESHEET)
    954 
    955     pdf = HTML(string=html).write_pdf(target=None, stylesheets=[css_file])
    956     stdout.buffer.write(pdf)
    957 
    958     remove(css_file)
    959 
    960 
    961 if __name__ == '__main__':
    962     main()