1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * See LICENSE.txt included in this distribution for the specific 9 * language governing permissions and limitations under the License. 10 * 11 * When distributing Covered Code, include this CDDL HEADER in each 12 * file and include the License file at LICENSE.txt. 13 * If applicable, add the following below this CDDL HEADER, with the 14 * fields enclosed by brackets "[]" replaced with your own identifying 15 * information: Portions Copyright [yyyy] [name of copyright owner] 16 * 17 * CDDL HEADER END 18 */ 19 20 /* 21 * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. 22 * Portions Copyright 2011 Jens Elkner. 23 * Portions Copyright (c) 2017, 2020, Chris Fraire <cfraire@me.com>. 24 */ 25 26 package org.opengrok.indexer.analysis.document; 27 import org.opengrok.indexer.analysis.JFlexNonXref; 28 import java.io.IOException; 29 import java.io.Writer; 30 import org.opengrok.indexer.analysis.JFlexXrefUtils; 31 import org.opengrok.indexer.web.QueryParameters; 32 import org.opengrok.indexer.web.Util; 33 %% 34 %public 35 %class TroffXref 36 %extends JFlexNonXref 37 %unicode 38 %int 39 %char 40 %init{ 41 /* 42 * Keep this antiquated management of yyline for a JFlexNonXref subclass. 43 * Hopefully JFlexNonXref will be retired before too long. 44 */ 45 yyline = 1; 46 %init} 47 %include ../CommonLexer.lexh 48 // do not include CommonXref.lexh in JFlexNonXref subclasses 49 %{ 50 int p; 51 int span; 52 int div; 53 54 @Override write(Writer out)55 public void write(Writer out) throws IOException { 56 p = 0; 57 span = 0; 58 div = 0; 59 this.out = out; 60 61 out.write("</pre><div id=\"man\">"); 62 while(yylex() != YYEOF) { 63 } 64 out.write("</div><pre>"); 65 } 66 67 @Override startNewLine()68 public void startNewLine() throws IOException { 69 // *DO NOT CALL super method* 70 71 setLineNumber(++yyline); 72 if (didSeePhysicalLOC) { 73 ++loc; 74 didSeePhysicalLOC = false; 75 } 76 } 77 78 // Q&D methods to assure well-formed documents closePara()79 protected void closePara() throws IOException { 80 if (p > 0) { 81 out.write("</p>"); 82 p--; 83 } 84 } closeSpan()85 protected void closeSpan() throws IOException { 86 if (span > 0) { 87 out.write("</span>"); 88 span--; 89 } 90 } closeDiv()91 protected void closeDiv() throws IOException { 92 if (div > 0) { 93 out.write("</div>"); 94 div--; 95 } 96 } openPara()97 protected void openPara() throws IOException { 98 out.write("<p>"); 99 p++; 100 } openSpan(char cssClass)101 protected void openSpan(char cssClass) throws IOException { 102 out.write("<span class=\""); 103 out.write(cssClass); 104 out.write("\">"); 105 span++; 106 } 107 openDiv(String cssClass)108 protected void openDiv(String cssClass) throws IOException { 109 out.write("<div class=\""); 110 out.write(cssClass); 111 out.write("\">"); 112 div++; 113 } 114 cleanup()115 protected void cleanup() { 116 try { 117 while (span > 0) { 118 closeSpan(); 119 } 120 while (p > 0) { 121 closePara(); 122 } 123 } catch (IOException e) { 124 // nothing we can do here 125 } 126 } 127 chkLOC()128 protected void chkLOC() { 129 switch (yystate()) { 130 case COMMENT: 131 break; 132 default: 133 phLOC(); 134 break; 135 } 136 } 137 %} 138 139 %eof{ 140 if (didSeePhysicalLOC) { 141 ++loc; 142 didSeePhysicalLOC = false; 143 } 144 145 cleanup(); 146 try { 147 while (div > 0) { 148 closeDiv(); 149 } catch(IOException e)150 } catch (IOException e) { 151 // nothing we can do here 152 } 153 %eof} 154 155 FNameChar = [a-zA-Z0-9_\-\.] 156 File = {FNameChar}+ "." ([chtsCHS]|"conf"|"java"|"cpp"|"CC"|"txt"|"htm"|"html"|"pl"|"xml") 157 158 %state HEADER COMMENT BOLD TBL TBLL 159 160 %include ../Common.lexh 161 %include ../CommonPath.lexh 162 %include ../CommonLaxFPath.lexh 163 %% 164 <YYINITIAL> { 165 ^\.(SH|TH|SS|IP|NH|TL|UH) { 166 chkLOC(); yybegin(HEADER); cleanup(); openDiv("b"); 167 } 168 ^(".\\\"")|(\'\\\")|("...\\\"") { yybegin(COMMENT);openSpan('c');} 169 } 170 171 <HEADER> { 172 {EOL} { yybegin(YYINITIAL); cleanup(); closeDiv(); startNewLine(); } 173 } 174 175 <COMMENT> { 176 {EOL} { yybegin(YYINITIAL); closeSpan(); out.write("<br/>"); startNewLine(); } 177 } 178 179 ^\.(B|U|BI|BX|UL|LG|NL|SB|BR|RB) { chkLOC(); yybegin(BOLD); openSpan('b'); } 180 ^\.(I|SM|IB|IR|RI|IX) { chkLOC(); yybegin(BOLD); openSpan('s'); } 181 ^\.(CW) { chkLOC(); yybegin(BOLD); openSpan('k'); } 182 ^\.(DS|LD|ID|BD|CD|RD) { chkLOC(); openSpan('k'); } 183 ^\.DE { chkLOC(); closeSpan(); } 184 185 <BOLD> { 186 {EOL} { yybegin(YYINITIAL); closeSpan(); out.write(' '); startNewLine(); } 187 } 188 189 "\\fB" { chkLOC(); openSpan('b'); } 190 "\\fI" { chkLOC(); openSpan('s'); } 191 "\\fC"|"\\f(CW" { chkLOC(); openSpan('k'); } 192 "\\fR" { chkLOC(); closeSpan(); } 193 "\\fP" { chkLOC(); closeSpan(); } 194 195 ^\.(PP|LP|P|TP|IP|HP|PD|SP|br|mk|ce) { 196 chkLOC(); 197 cleanup(); 198 openPara(); 199 } 200 201 ^\.(RS)[^\n]* { chkLOC(); cleanup(); openDiv("rs"); openPara(); } 202 ^\.(RE)[^\n]* { chkLOC(); cleanup(); closeDiv(); } 203 204 ^\.so { chkLOC(); out.write(".so "); } 205 ^\.(EQ|in|sp|ne|rt|pn|ds|de|if|ig|el|ft|hy|ie|ll|ps|rm|ta|ti|na|ad|te|hw|nh|pl)[^\n]* {EOL} { 206 207 chkLOC(); 208 startNewLine(); 209 } 210 ^\.(NH|DT|EE)[^\n]* { chkLOC(); } 211 ^"\\(bu" {EOL} { chkLOC(); startNewLine(); } 212 ^".nf" { chkLOC(); closePara(); out.write("<pre>"); } 213 ^".fi" { chkLOC(); cleanup(); out.write("</pre>"); } 214 \\\*\(Tm { chkLOC(); out.write("<sup>TM</sup> "); } 215 \\\*\R { chkLOC(); out.write("® "); } 216 \\\((l|r)q { chkLOC(); out.write('"'); } 217 \\\(mi { chkLOC(); out.write('-'); } 218 219 ^\.TS { 220 chkLOC(); 221 cleanup(); 222 yybegin(TBL); 223 out.write("<table rules=\"all\"><tr><td>"); 224 } 225 <TBL> { 226 tab\(.\) { chkLOC(); char tab = yycharat(4); } 227 \.$ { chkLOC(); yybegin(TBLL); } 228 [[\s]--[\n]] {} 229 [^\n] { chkLOC(); } 230 } 231 <TBLL> { 232 \007 { cleanup(); out.write("</td><td>"); } 233 ^[\_\=] {EOL} { chkLOC(); startNewLine(); } 234 T[\{\}] { chkLOC(); } 235 ^\.TE { 236 chkLOC(); yybegin(YYINITIAL); cleanup(); out.write("</td></tr></table>"); 237 } 238 {EOL} { cleanup(); out.write("</td></tr><tr><td>"); startNewLine(); } 239 } 240 241 {FNameChar}+ "@" {FNameChar}+ "." {FNameChar}+ 242 { 243 chkLOC(); 244 writeEMailAddress(yytext()); 245 } 246 247 {File} { 248 chkLOC(); 249 String path = yytext(); 250 out.write("<a href=\""); 251 out.write(urlPrefix); 252 out.write(QueryParameters.PATH_SEARCH_PARAM_EQ); 253 out.write(path); 254 JFlexXrefUtils.appendProject(out, project); 255 out.write("\">"); 256 out.write(path); 257 out.write("</a>");} 258 259 {RelaxedMiddleFPath} { 260 chkLOC(); 261 out.write(Util.breadcrumbPath(urlPrefix + QueryParameters.PATH_SEARCH_PARAM_EQ, yytext(), '/')); 262 } 263 \\&. { chkLOC(); out.write(yycharat(yylength() - 1)); } 264 \\- { chkLOC(); out.write('-'); } 265 "\\ " { out.write(' '); } 266 "<" { chkLOC(); out.write( "<"); } 267 ">" { chkLOC(); out.write( ">"); } 268 "&" { chkLOC(); out.write( "&"); } 269 {EOL} { out.write("\n"); startNewLine(); } 270 {WhspChar}+ { out.write(' '); } 271 [!-~] { chkLOC(); out.write(yytext()); } 272 [[\s]--[\n]] { Util.htmlize(yytext(), out); } 273 [^\n] { chkLOC(); Util.htmlize(yytext(), out); } 274