MdParse.pm 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. package Gsg::MdParse;
  2. use strict;
  3. use warnings;
  4. use Log::Log4perl qw(:easy);
  5. use Exporter qw(import);
  6. our @EXPORT_OK = qw(render_readme);
  7. sub link_line($) {
  8. my $line = shift;
  9. if ( $line =~ m/(<(http.*)>)/ ) {
  10. my $markup_link = $1;
  11. my $link = $2;
  12. my $link_replace = "<a href=\"$link\">$link</a>";
  13. $line =~ s/\Q$1\E/$link_replace/g;
  14. return $line;
  15. }
  16. return $line;
  17. }
  18. sub strike_line($) {
  19. my $line = shift;
  20. #if ( $line =~ m/~~(.*)~~/ ) {
  21. if ( $line =~ m/^(.*)~~(.*)~~(.*)/ ) {
  22. $line = "$1<s>$2</s>$3";
  23. return $line;
  24. }
  25. return $line;
  26. }
  27. # README content is passed in as a var, sub returned an HTML version of the parsed markdown
  28. sub render_readme($$) {
  29. my $readme_content = shift;
  30. my $logger = shift;
  31. my $html_readme;
  32. # Might be a better way to do this? TODO
  33. open my $fh, '>>', \$html_readme or die "Can't open variable: $!";
  34. # Main parsing logic, doing it line by line
  35. # I have some ideas on how to make this more robust/efficient,
  36. # but starting with below for POC
  37. # TODO:
  38. # Headers parsing can be one concise subroutine
  39. # Started building a suite of simple subs to handle everything else,
  40. # each line should be run through the 'sub suite' to handle all parsing
  41. my @readme_lines = split("\n", $readme_content);
  42. my $inside_code = 0;
  43. foreach my $line ( @readme_lines ) {
  44. # HEADERS
  45. if ( $line =~ m/^#{1}(?!#)(.*)#$|^#{1}(?!#)(.*)$/ && $inside_code == 0 ) {
  46. my $parsed_line;
  47. if ( ! defined $1 || $1 eq "" ) {
  48. $parsed_line = "<h1>$2</h1>";
  49. } else {
  50. $parsed_line = "<h1>$1</h1>";
  51. }
  52. print $fh "$parsed_line";
  53. } elsif ( $line =~ m/^#{2}(?!#)(.*)#{2}$|^#{2}(?!#)(.*)$/ && $inside_code == 0) {
  54. my $parsed_line;
  55. if ( ! defined $1 || $1 eq "" ) {
  56. $parsed_line = "<h2>$2</h2>";
  57. } else {
  58. $parsed_line = "<h2>$1</h2>";
  59. }
  60. print $fh "$parsed_line";
  61. } elsif ( $line =~ m/^#{3}(?!#)(.*)#{3}$|^#{3}(?!#)(.*)$/ && $inside_code == 0) {
  62. my $parsed_line;
  63. if ( ! defined $1 || $1 eq "" ) {
  64. $parsed_line = "<h3>$2</h3>";
  65. } else {
  66. $parsed_line = "<h3>$1</h3>";
  67. }
  68. print $fh "$parsed_line";
  69. } elsif ( $line =~ m/^#{4}(?!#)(.*)#{4}$|^#{4}(?!#)(.*)$/ && $inside_code == 0) {
  70. my $parsed_line;
  71. if ( ! defined $1 || $1 eq "" ) {
  72. $parsed_line = "<h4>$2</h4>";
  73. } else {
  74. $parsed_line = "<h4>$1</h4>";
  75. }
  76. print $fh "$parsed_line";
  77. } elsif ( $line =~ m/^#{5}(?!#)(.*)#{5}$|^#{5}(?!#)(.*)$/ && $inside_code == 0) {
  78. my $parsed_line;
  79. if ( ! defined $1 || $1 eq "" ) {
  80. $parsed_line = "<h5>$2</h5>";
  81. } else {
  82. $parsed_line = "<h5>$1</h5>";
  83. }
  84. print $fh "$parsed_line";
  85. } elsif ( $line =~ m/^\*(.*)/ && $inside_code == 0) {
  86. $line = strike_line($1);
  87. $line = link_line($line);
  88. my $parsed_line = "<ul><li>$line</li></ul>";
  89. print $fh "$parsed_line";
  90. } elsif ( $line =~ m/^```$/ ) {
  91. if ( $inside_code == 0 ) {
  92. $inside_code = 1;
  93. print $fh "<br>";
  94. } elsif ( $inside_code == 1 ) {
  95. $inside_code = 0;
  96. }
  97. } elsif ( $inside_code == 1 ) {
  98. print $fh "<code>$line</code><br>";
  99. } elsif ( $line =~ m/(http.*)/ ) {
  100. $line = link_line($line);
  101. print $fh "$line<br>";
  102. } elsif ( $line =~ m/^~~(.*)~~/ ) {
  103. $line = strike_line($line);
  104. print $fh "$line<br>";
  105. }
  106. else {
  107. print $fh "$line<br>";
  108. }
  109. }
  110. print $fh "<br>";
  111. close $fh;
  112. $logger->info("Parsed README");
  113. return $html_readme;
  114. }
  115. 1;