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