001: /*
002: * ManFormatter.java
003: *
004: * Copyright (C) 2000-2002 Peter Graves
005: * $Id: ManFormatter.java,v 1.1.1.1 2002/09/24 16:08:26 piso Exp $
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * as published by the Free Software Foundation; either version 2
010: * of the License, or (at your option) any later version.
011: *
012: * This program is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU General Public License for more details.
016: *
017: * You should have received a copy of the GNU General Public License
018: * along with this program; if not, write to the Free Software
019: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
020: */
021:
022: package org.armedbear.j;
023:
024: public class ManFormatter extends Formatter {
025: // States.
026: private static final int STATE_BOLD = STATE_LAST + 1;
027: private static final int STATE_UNDERLINE = STATE_LAST + 2;
028:
029: // Formats.
030: private static final int MAN_FORMAT_PLAIN = 0;
031: private static final int MAN_FORMAT_BOLD = 1;
032: private static final int MAN_FORMAT_UNDERLINE = 2;
033:
034: private final FastStringBuffer sb = new FastStringBuffer();
035: private final boolean apropos;
036:
037: public ManFormatter(Buffer buffer, boolean apropos) {
038: this .buffer = buffer;
039: this .apropos = apropos;
040: }
041:
042: private void endToken(int state) {
043: if (sb.length() > 0) {
044: int format;
045: switch (state) {
046: case STATE_NEUTRAL:
047: format = MAN_FORMAT_PLAIN;
048: break;
049: case STATE_BOLD:
050: format = MAN_FORMAT_BOLD;
051: break;
052: case STATE_UNDERLINE:
053: format = MAN_FORMAT_UNDERLINE;
054: break;
055: default:
056: format = MAN_FORMAT_PLAIN;
057: break;
058: }
059: addSegment(sb.toString(), format);
060: sb.setLength(0);
061: }
062: }
063:
064: public LineSegmentList formatLine(Line line) {
065: clearSegmentList();
066: if (line == null || line.length() == 0) {
067: addSegment("", MAN_FORMAT_PLAIN);
068: return segmentList;
069: }
070: if (apropos)
071: parseLineApropos(line);
072: else
073: parseLine(line);
074: return segmentList;
075: }
076:
077: private void parseLineApropos(Line line) {
078: String text = line.getText();
079: int index = text.indexOf(' ');
080: if (index >= 0) {
081: addSegment(text, 0, index, MAN_FORMAT_BOLD);
082: addSegment(text, index, MAN_FORMAT_PLAIN);
083: } else
084: addSegment(text, MAN_FORMAT_PLAIN);
085: }
086:
087: private void parseLine(Line line) {
088: final String text = ((ManLine) line).getRawText();
089: final int limit = text.length();
090: final int tabWidth = buffer.getTabWidth();
091: int state = STATE_NEUTRAL;
092: for (int i = 0, length = 0; i < limit; i++) {
093: final char c = text.charAt(i);
094: final char nextChar = i + 1 < limit ? text.charAt(i + 1)
095: : 0;
096: switch (state) {
097: case STATE_NEUTRAL:
098: if (nextChar == '\b') {
099: final char thirdChar = i + 2 < limit ? text
100: .charAt(i + 2) : 0;
101: if (thirdChar == c) {
102: // Bold.
103: endToken(state);
104: i += 2;
105: state = STATE_BOLD;
106: sb.append(c);
107: length++;
108: continue;
109: } else if (c == '_') {
110: // Underline.
111: endToken(state);
112: i += 2;
113: state = STATE_UNDERLINE;
114: sb.append(thirdChar);
115: length++;
116: continue;
117: } else {
118: ++i;
119: continue;
120: }
121: } else {
122: if (c == '\t') {
123: for (int j = tabWidth - length % tabWidth; j-- > 0; length++)
124: sb.append(" ");
125: } else {
126: sb.append(c);
127: length++;
128: }
129: }
130: break;
131: case STATE_BOLD:
132: if (c == '\b') {
133: char prevChar = text.charAt(i - 1);
134: if (nextChar == prevChar)
135: ++i;
136: continue;
137: } else if (nextChar == '\b') {
138: final char thirdChar = i + 2 < limit ? text
139: .charAt(i + 2) : 0;
140: if (thirdChar == c) {
141: // Bold.
142: i += 2;
143: sb.append(c);
144: length++;
145: continue;
146: }
147: if (c == '_') {
148: // Underline.
149: endToken(state);
150: i += 2;
151: state = STATE_UNDERLINE;
152: sb.append(thirdChar);
153: length++;
154: continue;
155: }
156: } else {
157: endToken(state);
158: state = STATE_NEUTRAL;
159: if (c == '\t') {
160: for (int j = tabWidth - length % tabWidth; j-- > 0; length++)
161: sb.append(" ");
162: } else {
163: sb.append(c);
164: length++;
165: }
166: }
167: break;
168: case STATE_UNDERLINE:
169: if (c == '_' && nextChar == '\b') {
170: final char thirdChar = i + 2 < limit ? text
171: .charAt(i + 2) : 0;
172: if (thirdChar != 0) {
173: sb.append(thirdChar);
174: length++;
175: }
176: i += 2;
177: } else if (nextChar == '\b') {
178: endToken(state);
179: i += 2;
180: state = STATE_BOLD;
181: sb.append(c);
182: length++;
183: continue;
184: } else {
185: endToken(state);
186: state = STATE_NEUTRAL;
187: if (c == '\t') {
188: for (int j = tabWidth - length % tabWidth; j-- > 0; length++)
189: sb.append(" ");
190: } else {
191: sb.append(c);
192: length++;
193: }
194: }
195: break;
196: }
197: }
198: endToken(state);
199: }
200:
201: public FormatTable getFormatTable() {
202: if (formatTable == null) {
203: formatTable = new FormatTable("ManMode");
204: formatTable.addEntryFromPrefs(MAN_FORMAT_PLAIN, "text");
205: formatTable.addEntryFromPrefs(MAN_FORMAT_BOLD, "function");
206: formatTable.addEntryFromPrefs(MAN_FORMAT_UNDERLINE,
207: "keyword");
208: }
209: return formatTable;
210: }
211: }
|