Changeset 1446


Ignore:
Timestamp:
May 11, 2012, 6:26:46 PM (5 years ago)
Author:
joerg
Message:

improved bibtex support: (a) suggestion of canonical entry names, (b) check that entries are ordered lexicographically, (c) reformatting of bibtex entries, (e) checking for errors like pages = {102-104}. These "errors" then can be corrected using alt+enter, e.g. moving of bibtex entries to the lexicographically correct position. Moreover, the introduction of @string using alt+enter is now very nice.

Location:
trunk
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/data/styles/user.xml

    r1444 r1446  
    2222  <element name="error" style="plain" foreground="ff0000"/>
    2323  <element name="baderror" style="plain" background="ff9988"/>
     24  <element name="suggestion" style="plain" background="ffcc88"/>
    2425  <element name="begin" style="bold" foreground="000080"/>
    2526  <element name="section" style="bold" foreground="f00000"/>
  • trunk/src/jlatexeditor/JLatexEditorJFrame.java

    r1438 r1446  
    346346    createPaneShortcut(SCEPaneUI.Actions.COMPLETE, false);
    347347
    348     createPaneShortcut(SCEPaneUI.Actions.BIBTEX_MOVE, false);
    349 
    350348    createPaneShortcut(SCEPaneUI.Actions.UNDO, false);
    351349    createPaneShortcut(SCEPaneUI.Actions.REDO, false);
     
    677675    } else
    678676    if (doc.getName().endsWith(".bib")) {
    679       editor = SCEManager.createBibSourceCodeEditor();
     677      editor = SCEManager.createBibSourceCodeEditor(this);
    680678    } else {
    681679      editor = SCEManager.createLatexSourceCodeEditor();
  • trunk/src/jlatexeditor/SCEManager.java

    r1444 r1446  
    235235  }
    236236
    237   public static SourceCodeEditor<Doc> createBibSourceCodeEditor() {
     237  public static SourceCodeEditor<Doc> createBibSourceCodeEditor(JLatexEditorJFrame jle) {
    238238    SourceCodeEditor<Doc> editor = new SourceCodeEditor<Doc>(null);
    239239
     
    269269    CombinedCodeAssistant codeAssistant = new CombinedCodeAssistant();
    270270    try {
    271       codeAssistant.addAssistant(new BibAssistant());
     271      codeAssistant.addAssistant(new BibAssistant(jle));
    272272      codeAssistant.addAssistant(new SpellCheckSuggester(createSpellChecker()));
    273     } catch (Exception ignored) {
    274     }
     273    } catch (Exception ignored) { ignored.printStackTrace(); }
    275274    scePane.addCodeAssistantListener(codeAssistant);
    276275
  • trunk/src/jlatexeditor/addon/RenameElement.java

    r1445 r1446  
    165165
    166166  public static void renameBibRef(JLatexEditorJFrame jle, String oldRef) {
     167    renameBibRef(jle, oldRef, oldRef);
     168  }
     169
     170  public static void renameBibRef(JLatexEditorJFrame jle, String oldRef, String suggestRef) {
    167171      // start background parser to update document states
    168172      backgroundParserUpdate(jle);
    169173
    170174      // ask user for new label
    171       String newRef = JOptionPane.showInputDialog(jle, "Rename bibtex entry: ", oldRef);
     175      String newRef = JOptionPane.showInputDialog(jle, "Rename bibtex entry: ", suggestRef);
    172176      if (newRef == null || newRef.equals(oldRef)) return;
    173177
  • trunk/src/jlatexeditor/bib/BibAssistant.java

    r1445 r1446  
    11package jlatexeditor.bib;
    22
     3import com.sun.tools.javac.util.Pair;
    34import jlatexeditor.JLatexEditorJFrame;
     5import jlatexeditor.addon.RenameElement;
    46import org.jetbrains.annotations.Nullable;
    57import sce.codehelper.CodeAssistant;
     
    2527 */
    2628public class BibAssistant implements CodeAssistant, SCEPopup.ItemHandler {
     29  private JLatexEditorJFrame jle;
     30
    2731  private PatternPair authorPattern = new PatternPair("(?:^| and )(?:(?! and ) )*((?:(?! and ).)*?)", true, "(.*?)(?:$| and$| and )");
    28   private String[] valueOrder = new String[] {
     32  private PatternPair entryTypePattern = new PatternPair("^\\@([^\\{])*");
     33  private PatternPair entryNamePattern = new PatternPair("^\\@[^\\{]+\\{ *([^,\\{]*)", true, "([^, ]*)(?:$|,| )");
     34
     35  private String[] keyOrder = new String[] {
    2936          "author", "title",
    3037          "booktitle",
     
    4148  };
    4249
    43   public BibAssistant() {
     50  public BibAssistant(JLatexEditorJFrame jle) {
     51    this.jle = jle;
    4452  }
    4553
     
    5058    int column = pane.getCaret().getColumn();
    5159
    52     ParserStateStack stateStack = BibSyntaxHighlighting.parseRow(rows[row], column, document);
     60    ParserStateStack stateStack = BibSyntaxHighlighting.parseRow(rows[row], column, document, rows, true);
    5361    BibParserState state = (BibParserState) stateStack.peek();
    5462
     
    107115    }
    108116
     117    { // entry name correction
     118      List<WordWithPos> params = entryNamePattern.find(pane);
     119      if(params != null) {
     120        BibEntry entry = state.getEntryByNr().get(state.getEntryNr());
     121        if(entry == null) return false;
     122
     123        String canonicalEntryName = BibAssistant.getCanonicalEntryName(entry);
     124        if(canonicalEntryName.equals(entry.getName())) return false;
     125
     126        RenameElement.renameBibRef(jle, entry.getName(), canonicalEntryName);
     127
     128        return true;
     129      }
     130
     131    }
     132
     133    { // entry position correction
     134      List<WordWithPos> params = entryTypePattern.find(pane);
     135      if(params != null) {
     136        BibEntry entry = state.getEntryByNr().get(state.getEntryNr());
     137        if(entry == null) return false;
     138
     139        List<Object> list = new ArrayList<Object>();
     140        list.add(new ReformatEntry(entry, pane));
     141
     142        SCEPosition end = new SCEDocumentPosition(document.getRowsModel().getRowsCount()-1, 0);
     143        BibEntry nextEntry = state.getEntryByNr().get(state.getEntryNr()+1);
     144        if(nextEntry != null) end = nextEntry.getStartPos();
     145
     146        list.add(new MoveEntry(state.getEntryNr(), entry, end, pane));
     147
     148        // open popup
     149        pane.getPopup().openPopup(list, this);
     150
     151        return true;
     152      }
     153    }
     154
    109155    return false;
    110156  }
     
    150196    for(int entryNr = 0; entryNr < entriesCount; entryNr++) {
    151197      BibEntry entry = state.getEntryByNr().get(entryNr);
    152       if(type != null && !entry.getType().equalsIgnoreCase(type)) continue;
     198      if(type != null && !entry.getType(false).equalsIgnoreCase(type)) continue;
    153199      entries.add(entry);
    154200    }
     
    157203  }
    158204
    159   private String getAuthorString(String name) {
    160     name = name.trim().toLowerCase();
     205  public static Pair<String,String> getFirstAndLast(String name) {
     206    name = name.replace('~', ' ');
     207    String pname = "";
     208    while(pname.length() != name.length()) {
     209      pname = name;
     210      name = name.replaceFirst("\\\\.","");
     211    }
    161212    name = name.replaceAll("[^\\w\\d\\., ]", "");
    162     name = name.replaceAll(" +"," ");
     213    name = name.replaceAll(" +"," ").trim();
    163214
    164215    String firstName = "", lastName = "";
     
    178229    }
    179230
     231    return new Pair<String, String>(firstName.trim(), lastName.trim());
     232  }
     233
     234  public static String[] getValues(BibKeyValuePair keyValue) {
     235    if(keyValue == null) return new String[0];
     236
     237    ArrayList<WordWithPos> valuesList = keyValue.getValues();
     238    String[] values = new String[keyValue.getValues().size()];
     239    for(int nr = 0; nr < values.length; nr++) {
     240      values[nr] = valuesList.get(nr).word;
     241    }
     242    return values;
     243  }
     244
     245  public static String getCanonicalEntryName(BibEntry entry) {
     246    if(entry.getType(true).equalsIgnoreCase("string")) return "";
     247
     248    BibKeyValuePair author = entry.getAllParameters().get("author");
     249    String nameString = unfold(getValues(author)).replace('\n', ' ').trim();
     250    if(nameString.equals("")) {
     251      BibKeyValuePair editor = entry.getAllParameters().get("editor");
     252      nameString = unfold(getValues(editor)).replace('\n', ' ').trim();
     253    }
     254    String year = unfold(getValues(entry.getAllParameters().get("year")));
     255    return BibAssistant.getCanonicalEntryName(nameString.split(" and "), year);
     256  }
     257
     258  public static String getCanonicalEntryName(String[] names, String year) {
     259    StringBuilder builder = new StringBuilder();
     260
     261    for(String name : names) {
     262      String last = getFirstAndLast(name).snd;
     263      for(String prefix : new String[] {"van ", "von ", "de ", "der "}) {
     264        if(last.startsWith(prefix)) last = last.substring(prefix.length());
     265      }
     266      last = last.toLowerCase().replaceAll("[^\\w]","");
     267      if(last.length() > 4) last = last.substring(0,4);
     268      builder.append(last).append(":");
     269    }
     270    builder.append(year);
     271
     272    return builder.toString();
     273  }
     274
     275  public static String unfold(String[] values) {
     276    return unfold(values, new StringBuilder(), 8);
     277  }
     278
     279  public static String unfold(String[] values, StringBuilder builder, int depth) {
     280    if(depth < 0 || values == null) return "";
     281
     282    for(String value : values) {
     283      if(value.startsWith("\"") || value.startsWith("{")) {
     284        builder.append(value.substring(1,value.length()-1));
     285      } else {
     286        unfold(BibSyntaxHighlighting.stringMap.get(value.toLowerCase()), builder, depth-1);
     287      }
     288    }
     289
     290    return builder.toString();
     291  }
     292
     293  public static String getAuthorString(String name) {
     294    Pair<String,String> fs = getFirstAndLast(name);
     295    String firstName = fs.fst.toLowerCase();
     296    String lastName = fs.snd.toLowerCase();
     297
    180298    lastName = lastName.replaceAll(" ","");
    181299    lastName = lastName.replaceAll("\\W","");
     
    335453      pane.setFreezeCaret(false);
    336454    }
     455
     456    if(item instanceof ReformatEntry) {
     457      ReformatEntry action = (ReformatEntry) item;
     458
     459      BibEntry entry = action.getEntry();
     460      SCEPosition start = entry.getStartPos();
     461      SCEPosition end = entry.getEndPos();
     462
     463      SCEDocument document = action.getPane().getDocument();
     464
     465      ArrayList<String> keys = new ArrayList<String>(entry.getAllParameters().keySet());
     466      Collections.sort(keys);
     467
     468      int maxLength = 0;
     469      for(String key : keys) maxLength = Math.max(key.length(), maxLength);
     470
     471      StringBuilder builder = new StringBuilder();
     472      builder.append("@").append(entry.getType(false));
     473      builder.append("{").append(entry.getName()).append(",\n");
     474      for(String akey : keyOrder) {
     475        if(!keys.remove(akey)) continue;
     476        appendKeyValue(builder, entry, akey, maxLength);
     477      }
     478      for(String akey : keys) {
     479        appendKeyValue(builder, entry, akey, maxLength);
     480      }
     481
     482      document.replace(start, end, builder.toString());
     483    }
     484
     485    if(item instanceof MoveEntry) {
     486      MoveEntry action = (MoveEntry) item;
     487
     488      BibEntry entry = action.getEntry();
     489      SCEPosition start = entry.getStartPos();
     490      SCEPosition end = action.getEnd();
     491
     492      SCEDocument document = action.getPane().getDocument();
     493
     494      String text = document.getText(start, end);
     495      document.remove(start, end);
     496
     497      String name = getCanonicalEntryName(entry);
     498      BibParserState state = (BibParserState) document.getRowsModel().getRows()[0].parserStateStack.peek();
     499      for(int entryNr = 0; entryNr < action.getEntryNr(); entryNr++) {
     500        BibEntry otherEntry = state.getEntryByNr().get(entryNr);
     501        String otherName = getCanonicalEntryName(otherEntry);
     502        if(name.compareTo(otherName) < 0) {
     503          document.insert(text, otherEntry.getStartPos().getRow(), 0);
     504        }
     505      }
     506    }
     507  }
     508
     509  private void appendKeyValue(StringBuilder builder, BibEntry entry, String akey, int maxLength) {
     510    builder.append("  ").append(akey);
     511    for(int spaceNr = 0; spaceNr < maxLength - akey.length(); spaceNr++) {
     512      builder.append(' ');
     513    }
     514    builder.append(" = ");
     515    boolean firstValue = true;
     516    BibKeyValuePair values = entry.getAllParameters().get(akey);
     517    for(WordWithPos value : values.getValues()) {
     518      if(!firstValue) builder.append(" # ");
     519
     520      String v = value.word.replace('\n',' ').replaceAll(" +", " ");
     521
     522      if(akey.equals("pages")) v = v.replaceAll("([^-])-([^-])", "$1--$2");
     523
     524      if(v.startsWith("\"") || v.startsWith("{")) {
     525        builder.append("{").append(v.substring(1,v.length()-1)).append("}");
     526      } else {
     527        builder.append(v.toLowerCase());
     528      }
     529
     530      firstValue = false;
     531    }
     532    builder.append(",\n");
    337533  }
    338534
     
    403599  }
    404600
     601  class ReformatEntry {
     602    private BibEntry entry;
     603    private SCEPane pane;
     604
     605    ReformatEntry(BibEntry entry, SCEPane pane) {
     606      this.entry = entry;
     607      this.pane = pane;
     608    }
     609
     610    public BibEntry getEntry() {
     611      return entry;
     612    }
     613
     614    public SCEPane getPane() {
     615      return pane;
     616    }
     617
     618    @Override
     619    public String toString() {
     620      return "Reformat Entry";
     621    }
     622  }
     623
     624  class MoveEntry {
     625    private int entryNr;
     626    private BibEntry entry;
     627    private SCEPosition end;
     628    private SCEPane pane;
     629
     630    MoveEntry(int entryNr, BibEntry entry, SCEPosition end, SCEPane pane) {
     631      this.entryNr = entryNr;
     632      this.entry = entry;
     633      this.end = end;
     634      this.pane = pane;
     635    }
     636
     637    public int getEntryNr() {
     638      return entryNr;
     639    }
     640
     641    public BibEntry getEntry() {
     642      return entry;
     643    }
     644
     645    public SCEPosition getEnd() {
     646      return end;
     647    }
     648
     649    public SCEPane getPane() {
     650      return pane;
     651    }
     652
     653    @Override
     654    public String toString() {
     655      return "Move Entry";
     656    }
     657  }
     658
    405659  class WeightedElement<E> implements Comparable<WeightedElement<E>> {
    406660    private double weight;
  • trunk/src/jlatexeditor/bib/BibCodeCompletion.java

    r1444 r1446  
    3333    int column = pane.getCaret().getColumn();
    3434
    35     ParserStateStack stateStack = BibSyntaxHighlighting.parseRow(rows[row], column, document);
     35    ParserStateStack stateStack = BibSyntaxHighlighting.parseRow(rows[row], column, document, rows, true);
    3636    BibParserState state = (BibParserState) stateStack.peek();
    3737
     
    5252
    5353      HashMap<String,BibKeyValuePair> keys = state.getEntry().getAllParameters();
    54       BibEntryPattern entry = BibEntryPattern.getEntry("@" + state.getEntry().getType());
     54      BibEntryPattern entry = BibEntryPattern.getEntry("@" + state.getEntry().getType(false));
    5555      if(entry == null) return false;
    5656
  • trunk/src/jlatexeditor/bib/BibEntry.java

    r1445 r1446  
    33import sce.codehelper.WordWithPos;
    44import sce.component.SCEDocumentPosition;
     5import sce.component.SCEDocumentRange;
     6import sce.component.SCEPosition;
    57
    68import java.util.HashMap;
    79
    810public class BibEntry {
    9   private SCEDocumentPosition startPos = null;
    10   private SCEDocumentPosition endPos = null;
     11  private SCEDocumentRange range = new SCEDocumentRange(0,0,0,0);
    1112
    1213  private String type = null;
     
    1718  public BibEntry copy() {
    1819    BibEntry copy = new BibEntry();
     20    copy.range = range;
    1921    copy.type = type;
     22    copy.name = name;
    2023    copy.parameters = new HashMap<String, BibKeyValuePair>(parameters);
    2124    copy.allParameters = allParameters;
     
    2326  }
    2427
    25   public SCEDocumentPosition getStartPos() {
    26     return startPos;
     28  public SCEPosition getStartPos() {
     29    return range.getStartPos();
    2730  }
    2831
    2932  public void setStartPos(SCEDocumentPosition startPos) {
    30     this.startPos = startPos;
     33    range.setStartPos(startPos);
    3134  }
    3235
    33   public SCEDocumentPosition getEndPos() {
    34     return endPos;
     36  public SCEPosition getEndPos() {
     37    return range.getEndPos();
    3538  }
    3639
    3740  public void setEndPos(SCEDocumentPosition endPos) {
    38     this.endPos = endPos;
     41    range.setEndPos(endPos);
    3942  }
    4043
    41   public String getType() {
    42     return type;
     44  public String getType(boolean allowNull) {
     45    return type != null || allowNull ? type : "";
    4346  }
    4447
  • trunk/src/jlatexeditor/bib/BibParserState.java

    r1444 r1446  
    115115    BibParserState b = (BibParserState) obj;
    116116    return state == b.state && bracketLevel == b.bracketLevel
    117             && equals(entry.getType(), b.getEntry().getType())
     117            && equals(entry.getType(false), b.getEntry().getType(false))
    118118            && equals(entry.getParameters(), b.getEntry().getParameters())
     119            && entry.getAllParameters() == b.getEntry().getAllParameters()
    119120            && entryNr == b.entryNr;
    120121  }
  • trunk/src/jlatexeditor/bib/BibSyntaxHighlighting.java

    r1445 r1446  
    1010import util.SetTrie;
    1111
     12import java.util.ArrayList;
    1213import java.util.Arrays;
     14import java.util.Collections;
    1315import java.util.HashMap;
    1416
     
    3436  private boolean currentlyChanging = false;
    3537
     38  public static HashMap<String,String[]> stringMap = new HashMap<String, String[]>();
     39
    3640  public BibSyntaxHighlighting(SCEPane pane, BackgroundParser parser) {
    3741    super("BibTexSyntaxHighlighting");
     
    128132    while (!ready && row_nr < rowsCount) {
    129133      SCEDocumentRow row = rows[row_nr];
    130       ParserStateStack stateStack = parseRow(row, row.length, document);
     134      ParserStateStack stateStack = parseRow(row, row.length, document, rows, false);
    131135
    132136      // go to the next row
     
    144148  }
    145149
    146   public static ParserStateStack parseRow(SCEDocumentRow row, int length, SCEDocument document) {
     150  public static ParserStateStack parseRow(SCEDocumentRow row, int length, SCEDocument document, SCEDocumentRow rows[], boolean simulate) {
    147151    // this may never be
    148152    if (row.parserStateStack == null) throw new RuntimeException("Internal parser error occurred.");
     
    151155    ParserStateStack stateStack = row.parserStateStack.copy();
    152156    BibParserState state = (BibParserState) stateStack.peek();
     157    if(simulate) state = (BibParserState) state.copy();
    153158
    154159    // reset the modified value of the row
     
    165170
    166171      // @type
    167       if(state.getState() == BibParserState.STATE_NOTHING && c == '@') {
     172      if(c == '@' && (state.getState() == BibParserState.STATE_NOTHING || char_nr==0)) {
    168173        String entryType = LatexSyntaxHighlighting.getWord(row, char_nr + 1, false);
    169174        if(entryType == null) {
     
    181186
    182187        BibEntry entry = new BibEntry();
    183         state.setEntry(entry);
     188        if(!simulate) state.setEntry(entry);
    184189        entry.setStartPos(new SCEDocumentPosition(sce_char));
    185190        entry.setType(entryType);
    186         entry.setParameters(new HashMap<String, BibKeyValuePair>());
    187         entry.setAllParameters(new HashMap<String, BibKeyValuePair>());
     191
     192        state.setValue(new BibKeyValuePair());
     193
     194        state.setBracketLevel(0);
    188195        continue;
    189196      }
     
    194201        if(c != '{') sce_char.style = LatexStyles.ERROR;
    195202
    196         boolean isString = state.getEntry().getType().toLowerCase().equals("string");
     203        boolean isString = state.getEntry().getType(false).toLowerCase().equals("string");
    197204        state.setState(!isString ? BibParserState.STATE_EXPECT_NAME : BibParserState.STATE_EXPECT_KEY);
     205        state.setBracketLevel(1);
    198206        continue;
    199207      }
     
    202210      if(state.getState() == BibParserState.STATE_EXPECT_CLOSE && !Character.isWhitespace(c)) {
    203211        sce_char.style = stateStyles[LatexStyles.BRACKET];
     212
    204213        if(c != '}') {
    205214          sce_char.style = LatexStyles.ERROR;
     
    212221        sce_char.style = stateStyles[LatexStyles.BRACKET];
    213222
    214         if(state.getBracketLevel() > 1) {
    215           state.setBracketLevel(state.getBracketLevel()-1);
    216         } else
    217         if(state.getBracketLevel() == 1) {
     223        int bracketLevel = state.getBracketLevel();
     224        if(bracketLevel > 0) {
     225          state.setBracketLevel(bracketLevel-1);
     226        }
     227
     228        if(bracketLevel > 2) {
     229        } else
     230        if(bracketLevel == 2) {
    218231          // exit value
    219232          SCEDocumentPosition start = state.getValueOpening();
    220233          SCEDocumentPosition end = new SCEDocumentPosition(sce_char,0,1);
    221234          String text = document != null ? document.getText(start, end) : "";
    222 
    223235          state.getValue().addValue(new WordWithPos(text, start, end));
    224236
     237          if(state.getValue().getKey().word.equalsIgnoreCase("pages")) {
     238            if(text.matches(".*([^-])-([^-]).*")) {
     239              mark(rows, stateStyles[LatexStyles.getStyle("baderror")], start, end);
     240            }
     241          }
     242
    225243          state.setState(BibParserState.STATE_EXPECT_COMMA);
    226           state.setBracketLevel(0);
    227         } else {
     244        } else
     245        if(bracketLevel == 1) {
    228246          // exit block
    229247          BibEntry entry = state.getEntry();
     
    238256          entry.getAllParameters().putAll(entry.getParameters());
    239257
     258          boolean isString = entry.getType(false).toLowerCase().equals("string");
     259          if(isString) {
     260            BibKeyValuePair keyValue = entry.getAllParameters().get(entry.getName());
     261            String[] values = BibAssistant.getValues(keyValue);
     262            stringMap.put(entry.getName().toLowerCase(), values);
     263          } else {
     264            String canonicalEntryName = BibAssistant.getCanonicalEntryName(entry);
     265
     266            if(!entry.getName().startsWith(canonicalEntryName)) {
     267              WordWithPos name = entry.getNameWithPos();
     268              mark(rows, stateStyles[LatexStyles.getStyle("suggestion")], name.getStartPos(), name.getEndPos());
     269            }
     270
     271            // lexicographic order
     272            if(state.getEntryNr() > 1) {
     273              BibEntry previousEntry = state.getEntryByNr().get(state.getEntryNr()-2);
     274              String previousEntryName = BibAssistant.getCanonicalEntryName(previousEntry);
     275
     276              if(previousEntryName.compareTo(canonicalEntryName) > 0) {
     277                SCEDocumentPosition end = new SCEDocumentPosition(entry.getStartPos().getRow(), entry.getStartPos().getColumn() + entry.getType(false).length()+1);
     278                mark(rows, stateStyles[LatexStyles.getStyle("suggestion")], entry.getStartPos(), end);
     279              }
     280            }
     281
     282          }
     283
    240284          state.setState(BibParserState.STATE_NOTHING);
    241285          state.resetEntry();
     286        } else {
     287          sce_char.style = stateStyles[LatexStyles.COMMENT];
    242288        }
    243289
     
    312358        byte entryStyle = stateStyles[LatexStyles.MATH_COMMAND];
    313359
    314         BibEntryPattern entry = BibEntryPattern.getEntry("@" + state.getEntry().getType());
     360        BibEntryPattern entry = BibEntryPattern.getEntry("@" + state.getEntry().getType(false));
    315361        if(entry != null) {
    316362          // non-existing key
     
    320366        }
    321367
    322         boolean isString = state.getEntry().getType().toLowerCase().equals("string");
     368        boolean isString = state.getEntry().getType(false).toLowerCase().equals("string");
    323369        if(isString) {
    324370          state.getEntry().setName(new WordWithPos(key, new SCEDocumentPosition(sce_char)));
     
    410456          state.getValue().addValue(new WordWithPos(text, start, end));
    411457
    412           boolean isString = state.getEntry().getType().toLowerCase().equals("string");
    413           state.setState(!isString ? BibParserState.STATE_EXPECT_COMMA : BibParserState.STATE_EXPECT_CLOSE);
     458          if(state.getValue().getKey().word.equalsIgnoreCase("pages")) {
     459            if(text.matches(".*([^-])-([^-]).*")) {
     460              mark(rows, stateStyles[LatexStyles.getStyle("baderror")], start, end);
     461            }
     462          }
     463
     464          state.setState(BibParserState.STATE_EXPECT_COMMA);
    414465        }
    415466
     
    431482          state.setBracketLevel(state.getBracketLevel()+1);
    432483        } else
    433         if(state.getBracketLevel() == 0 && c == ',') {
    434           boolean isString = state.getEntry().getType().toLowerCase().equals("string");
    435           state.setState(!isString ? BibParserState.STATE_EXPECT_COMMA : BibParserState.STATE_EXPECT_CLOSE);
     484        if(state.getBracketLevel() == 1 && c == ',') {
     485          state.setState(BibParserState.STATE_EXPECT_COMMA);
    436486          char_nr--;
    437487        }
     
    444494  }
    445495
    446   private void mark(int style, SCEDocumentRow row, int startColumn, int length) {
    447     SCEDocumentChar[] chars = row.chars;
    448     int endColumn = startColumn + length;
    449     for (int i = startColumn; i < endColumn; i++) {
    450       chars[i].style = LatexStyles.ERROR;
     496  private static void mark(SCEDocumentRow rows[], byte style, SCEPosition start, SCEPosition end) {
     497    int startRow = start.getRow();
     498    int endRow = end.getRow();
     499    for(int rowNr = startRow; rowNr <= endRow; rowNr++) {
     500      SCEDocumentRow row = rows[rowNr];
     501
     502      int min = rowNr == startRow ? start.getColumn() : 0;
     503      int max = Math.min(row.length, rowNr == endRow ? end.getColumn() : row.length);
     504      SCEDocumentChar[] chars = row.chars;
     505      for (int i = min; i < max; i++) {
     506        chars[i].style = style;
     507      }
    451508    }
    452509  }
  • trunk/src/jlatexeditor/gproperties/GProperties.java

    r1373 r1446  
    226226    properties.addEntry(new Def("shortcut.complete", SHORTCUT, "control SPACE"));
    227227
    228     properties.addEntry(new Def("shortcut.bibtex.move", SHORTCUT, "alt B"));
    229 
    230228    properties.addEntry(new Comment(" Focus Traversal"));
    231229    properties.addEntry(new Def("shortcut.focus traversal forward", SHORTCUT, "TAB"));
  • trunk/src/sce/component/SCEDocumentRange.java

    r1444 r1446  
    3535  }
    3636
     37  public void setStartPos(SCEPosition startPos) {
     38    this.startPos = startPos;
     39  }
     40
    3741  /**
    3842   * Returns the end position of the range.
     
    4448  }
    4549
    46   public int getStartRow() {
     50  public void setEndPos(SCEPosition endPos) {
     51    this.endPos = endPos;
     52  }
     53
     54  public int getStartRow() {
    4755    return startPos.getRow();
    4856  }
  • trunk/src/sce/component/SCEPaneUI.java

    r1445 r1446  
    465465    public static final String COMPLETE                 = "complete";
    466466
    467     public static final String BIBTEX_MOVE              = "bibtex.move";
    468 
    469467    public static final String UNDO                     = "undo";
    470468    public static final String REDO                     = "redo";
     
    530528        ui.complete();
    531529      } else
    532       if (key.equals(BIBTEX_MOVE)) {
    533         Pattern pattern = Pattern.compile("@(\\w+) *\\{ *([^ ,]+) *,");
    534 
    535         String item = pane.getDocument().getSelectedText();
    536         if(item == null) return;
    537 
    538         Matcher matcher = pattern.matcher(item);
    539         if(!matcher.find()) return;
    540         String itemName = matcher.group(2);
    541 
    542         pane.cut();
    543 
    544         SCEDocument document = pane.getDocument();
    545         SCEDocumentRow[] rows = document.getRowsModel().getRows();
    546         for(SCEDocumentRow row : rows) {
    547           matcher = pattern.matcher(row.toString());
    548           if(matcher.find()) {
    549             String type = matcher.group(1);
    550             String name = matcher.group(2);
    551 
    552             if(type.toLowerCase().trim().equals("string")) continue;
    553 
    554             if(name.compareTo(itemName) > 0) {
    555               pane.getCaret().moveTo(row.row_nr, 0, false);
    556               break;
    557             }
    558           }
    559         }
    560 
    561         pane.paste();
    562       } else
    563530      if (key.equals(UNDO)) {
    564531        pane.getUndoManager().undo(false);
     
    636603        REMOVE_LINE, REMOVE_LINE_BEFORE_CARET, REMOVE_LINE_BEHIND_CARET, REMOVE_WORD_BEFORE_CARET, REMOVE_WORD_BEHIND_CARET,
    637604        COMPLETE,
    638         BIBTEX_MOVE,
    639605        UNDO, REDO, FIND, REPLACE, FIND_NEXT, FIND_PREVIOUS, CUT, COPY, PASTE, SELECT_ALL, SELECT_NONE, COMMENT, UNCOMMENT);
    640606      return am;
Note: See TracChangeset for help on using the changeset viewer.