PageRenderTime 27ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/xPapers/Parse/LineByLine.pm

https://github.com/fws-hub/xPapers
Perl | 225 lines | 143 code | 72 blank | 10 comment | 28 complexity | 698404602f8a9b449681367fc258a755 MD5 | raw file
  1. package xPapers::Parse::LineByLine;
  2. use xPapers::Legacy::Biblio;
  3. use xPapers::Legacy::Category;
  4. use xPapers::Entry;
  5. use xPapers::Parse::Parser;
  6. use xPapers::Util;
  7. use xPapers::Render::Regimented;
  8. @ISA = qw/xPapers::Parse::Parser/;
  9. sub parseBiblio {
  10. my ($me, $text, $restrict) = @_;
  11. return $me->parseBiblioFile('',$restrict,$text);
  12. }
  13. sub parseEntry {
  14. my ($me, $text) = @_;
  15. my $b = $me->parseBiblio($text);
  16. my $r = new xPapers::Render::Regimented;
  17. my @e = @{$b->getRoot->getEntries};
  18. return $#e > -1 ? $e[0] : undef;
  19. }
  20. sub parseBiblioFile {
  21. my ($me, $file, $restrict, $text) = @_;
  22. #print "[LineParser($me->{class}): opening $file]\n";
  23. $me->{errors} = [];
  24. if ($file =~ /\.loose\./) {
  25. $me->{looseMode} = 1;
  26. print "[LineParser($me->{class}): Warning: entering loose mode. Check the results afterwards. ]\n";
  27. }
  28. $restrict = $restrict ? $restrict : 0;
  29. my $bib = xPapers::Legacy::Biblio->new;
  30. my $current_cat = $bib->getRoot;
  31. my $current_ent;
  32. my $nb = 0;
  33. my $linenum = 0;
  34. my $parse = $restrict ? 0 : 1; # flag if in category to parse
  35. my $parse_level = undef; # level of the restriction category
  36. my @lines;
  37. if ($file ) {
  38. open IN,$file;
  39. binmode(IN,':utf8');
  40. } else {
  41. @lines = split(/[\r\n]/,$text);
  42. }
  43. while ( $l = <IN> || $linenum <= $#lines ) {
  44. $l = $lines[$linenum] unless $file;
  45. #print "P:$l\n";
  46. =test
  47. if ($bib->{entryIndex}->{TIMWAT}) {
  48. print "found future zombie\n";
  49. print $bib->{entryIndex}->{TIMWAT}->toString;
  50. print "\n";
  51. exit;
  52. }
  53. =cut
  54. $linenum++;
  55. next if ($l =~ /^\s*#/);
  56. if ($linenum % 1000 == 0 && $linenum > 0) {
  57. #print "[LineParser($me->{class}): $linenum lines parsed]\n";
  58. }
  59. # if parsing multi-line field
  60. =fix
  61. if ($me->{field}) {
  62. if ($l =~ /^\.\s*$/) {
  63. $me->{field} = undef;
  64. } else {
  65. $$me->{field} .= $l;
  66. }
  67. next;
  68. }
  69. =cut
  70. if ($me->parseSpecial($l, $bib, $current_cat, $current_ent)) {
  71. $me->youParsed();
  72. } elsif (my $c = $me->parseCategoryInline($l,$bib)) {
  73. $current_cat = $c;
  74. $me->youParsed();
  75. } elsif (my $ca = $me->parseCategory($l)) {
  76. my $level_diff = $current_cat->{level} - $ca->{level};
  77. # new category goes under current category. level is changed if too low.
  78. if ($level_diff < 0) {
  79. $bib->addCategory($ca, $current_cat->id());
  80. $ca->{level} = $current_cat->{level} + 1;
  81. $current_cat = $ca;
  82. }
  83. # new category is higher up or equal in the hierarchy
  84. else {
  85. # get appropriate parent for new category
  86. my $target = $current_cat;
  87. for (; $level_diff >=0; $level_diff--) {
  88. $target = $target->firstParent || die("** ERROR (line #: $linenum): can't get appropriate parent for category '$ca->{name}|$l'\n");
  89. }
  90. # add to appropriate parent
  91. $bib->addCategory($ca, $target->id());
  92. $current_cat = $ca;
  93. }
  94. if ($restrict eq $ca->id()) {
  95. $parse = 1;
  96. $parse_level = $ca->{level};
  97. } elsif ($parse == 1 && $parse_level >= $ca->{level}) {
  98. $parse = 0;
  99. }
  100. if ($ca->{oldId}) {
  101. $me->{sectMap}->{$ca->{oldId}} = $ca->numId;
  102. }
  103. $me->youParsed();
  104. } elsif ( $parse && $me->parseEntryExtraLine($current_ent,$l, $bib) ) {
  105. $me->youParsed();
  106. } elsif ( $parse && (my $e = $me->parseEntryFirstLine($l)) ) {
  107. $bib->addEntry($e, $current_cat->id());
  108. $current_ent = $e;
  109. $nb++;
  110. $me->youParsed();
  111. } elsif ( $parse ) {
  112. $me->catchAll($l,$linenum);
  113. }
  114. }
  115. # Adjust seeAlso fields if there has been injecting
  116. foreach my $c ($bib->gatherCats) {
  117. my $see = $c->{'see-also'};
  118. for (my $x=0; $x<= $#$see; $x++) {
  119. if (my $v = $me->{sectMap}->{$see->[$x]}) {
  120. $see->[$x] = $v;
  121. }
  122. }
  123. }
  124. #print $nb;
  125. if ($file) { close IN; }
  126. return $bib;;
  127. }
  128. sub catchAll {
  129. my ($me, $l, $linenum) = @_;
  130. my $err = "Line $linenum not parsed: '$l'\n" unless ($l =~ /^\s*$/);
  131. push @{$me->{errors}},$err;
  132. }
  133. sub youParsed {
  134. my $self = shift;
  135. }
  136. sub parseCategoryInline {
  137. die "parseCategoryInline not implemented.";
  138. }
  139. 1;
  140. __END__
  141. =head1 NAME
  142. xPapers::Parse::LineByLine
  143. =head1 SUBROUTINES
  144. =head2 catchAll
  145. =head2 parseBiblio
  146. =head2 parseBiblioFile
  147. =head2 parseCategoryInline
  148. =head2 parseEntry
  149. =head2 youParsed
  150. =head1 AUTHORS
  151. David Bourget with contributions from Zbigniew Lukasiak
  152. =head1 COPYRIGHT AND LICENSE
  153. See accompanying README file for licensing information.