2012-07-10 34 views
2

我有一個類似Lisp的語言,我想強調在Sphinx代碼片段文檔中使用Pygments。我的方法是擴展現有的CommonLispLexer以使用NameHighlightFilter添加內置名稱。然而,它不工作,所以我必須錯過明顯的東西。我已將以下內容添加到我的conf.py中:獅身人面像Pygments詞法分析器過濾器擴展?

def setup(app): 
    from sphinx.highlighting import lexers 
    from pygments.lexers import CommonLispLexer 
    from pygments.token import Name 
    from pygments.filters import NameHighlightFilter 
    tl_lexer = CommonLispLexer() 
    tl_lexer.add_filter(NameHighlightFilter(
      names=['define-function', 'define-macro', 
        'define-variable', 'define-constant'], 
      tokentype=Name.Builtin, 
      )) 
    app.add_lexer('tl', tl_lexer) 

highlight_language = 'tl' 

但是NameHighlightFilter沒有任何作用。代碼塊突出顯示,就好像它們是Lisp一樣,但是我的新內建名稱沒有特別突出顯示。

+0

在交互式Python會話中運行此代碼,確認過濾器不按我的意圖工作。即使在如上所述調用add_filter之後,define函數仍然被標記爲「Name.Variable」,而不是「Name.Builtin」。 – 2012-07-10 12:57:49

回答

4

的原因是NameHighlighFilter只有轉換的詞法分析器作爲分類記號Token.Name,但CommonLispLexer分類幾乎一切爲Name.Variable。這是NameHighlightFilter的過濾功能,從Pygments來做源代碼:

def filter(self, lexer, stream): 
    for ttype, value in stream: 
     if ttype is Name and value in self.names: 
      yield self.tokentype, value 
     else: 
      yield ttype, value 

我唯一的解決方法是寫我自己的過濾器。這個功能給了我想要的樣子。

def filter(self, lexer, stream): 
    define = False 
    for ttype, value in stream: 
     if value in self.tl_toplevel_forms: 
      ttype = Name.Builtin 
      define = True 
     elif define and ttype == Name.Variable: 
      define = False 
      ttype = Name.Function 
     elif value in self.tl_special_forms: 
      ttype = Name.Variable 
     # the Common Lisp lexer highlights everything else as 
     # variables, which isn't the look I want. Instead 
     # highlight all non-special things as text. 
     elif ttype == Name.Variable: 
      ttype = Name.Text 
     yield ttype, value 

作爲一個說明,以Pygments來做開發者,或許NameHighlightFilter可以採取表示令牌類型(一個或多個)被轉換(目前只需要輸出令牌類型)的可選參數。