Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add LdifLexer #2489

Merged
merged 1 commit into from Aug 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions pygments/lexers/_mapping.py
Expand Up @@ -266,6 +266,7 @@
'LassoJavascriptLexer': ('pygments.lexers.templates', 'JavaScript+Lasso', ('javascript+lasso', 'js+lasso'), (), ('application/x-javascript+lasso', 'text/x-javascript+lasso', 'text/javascript+lasso')),
'LassoLexer': ('pygments.lexers.javascript', 'Lasso', ('lasso', 'lassoscript'), ('*.lasso', '*.lasso[89]'), ('text/x-lasso',)),
'LassoXmlLexer': ('pygments.lexers.templates', 'XML+Lasso', ('xml+lasso',), (), ('application/xml+lasso',)),
'LdifLexer': ('pygments.lexers.ldap', 'LDIF', ('ldif',), ('*.ldif',), ('text/x-ldif',)),
'LeanLexer': ('pygments.lexers.theorem', 'Lean', ('lean',), ('*.lean',), ('text/x-lean',)),
'LessCssLexer': ('pygments.lexers.css', 'LessCss', ('less',), ('*.less',), ('text/x-less-css',)),
'LighttpdConfLexer': ('pygments.lexers.configs', 'Lighttpd configuration file', ('lighttpd', 'lighty'), ('lighttpd.conf',), ('text/x-lighttpd-conf',)),
Expand Down
86 changes: 86 additions & 0 deletions pygments/lexers/ldap.py
@@ -0,0 +1,86 @@
"""
pygments.lexers.ldap
~~~~~~~~~~~~~~~~~~~~

Pygments lexers for LDAP.

:copyright: Copyright 2006-2023 by the Pygments team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

import re


from pygments.lexer import RegexLexer, bygroups, default
from pygments.token import Operator, Comment, Keyword, Name, String, \
Number, Punctuation, Whitespace, Escape

__all__ = ['LdifLexer']


class LdifLexer(RegexLexer):

"""
Lexer for LDIF

.. versionadded:: 2.17
"""

name = 'LDIF'
aliases = ['ldif']
filenames = [ "*.ldif" ]
randomstuff marked this conversation as resolved.
Show resolved Hide resolved
mimetypes = ["text/x-ldif"]
url = "https://datatracker.ietf.org/doc/html/rfc2849"

tokens = {
'root': [
(r'\s*\n', Whitespace),
(r'(-)(\n)', bygroups(Punctuation, Whitespace)),
(r'(#.*)(\n)', bygroups(Comment.Single, Whitespace)),
(r'(version)(:)([ \t]*)(.*)([ \t]*\n)', bygroups(Keyword, Punctuation, Whitespace, Number.Integer, Whitespace)),
(r'(control)(:)([ \t]*)([\.0-9]+)([ \t]+)((?:true|false)?)([ \t]*)',
bygroups(Keyword, Punctuation, Whitespace, Name.Other, Whitespace, Keyword, Whitespace), "after-control"),
(r'(deleteoldrdn)(:)([ \n]*)([0-1]+)([ \t]*\n)', bygroups(Keyword, Punctuation, Whitespace, Number, Whitespace)),
(r'(add|delete|replace)(::?)(\s*)(.*)([ \t]*\n)', bygroups(Keyword, Punctuation, Whitespace, Name.Attribute, Whitespace)),
(r'(changetype)(:)([ \t]*)([a-z]*)([ \t]*\n)', bygroups(Keyword, Punctuation, Whitespace, Keyword, Whitespace)),
(r'(dn|newrdn)(::)', bygroups(Keyword, Punctuation), "base64-dn"),
(r'(dn|newrdn)(:)', bygroups(Keyword, Punctuation), "dn"),
(r'(objectclass)(:)([ \t]*)([^ \t\n]*)([ \t]*\n)', bygroups(Keyword, Punctuation, Whitespace, Name.Class, Whitespace)),
(r'([a-zA-Z]*|[0-9][0-9\.]*[0-9])(;)', bygroups(Name.Attribute, Punctuation), "property"),
(r'([a-zA-Z]*|[0-9][0-9\.]*[0-9])(:<)', bygroups(Name.Attribute, Punctuation), "url"),
(r'([a-zA-Z]*|[0-9][0-9\.]*[0-9])(::?)', bygroups(Name.Attribute, Punctuation), "value"),
],
"after-control": [
(r":<", Punctuation, ("#pop", "url")),
(r"::?", Punctuation, ("#pop", "value")),
default("#pop"),
],
'property': [
(r'([-a-zA-Z0-9]*)(;)', bygroups(Name.Property, Punctuation)),
(r'([-a-zA-Z0-9]*)(:<)', bygroups(Name.Property, Punctuation), ("#pop", "url")),
(r'([-a-zA-Z0-9]*)(::?)', bygroups(Name.Property, Punctuation), ("#pop", "value")),
],
'value': [
(r'(\s*)([^\n]+\S)(\n )', bygroups(Whitespace, String, Whitespace)),
(r'(\s*)([^\n]+\S)(\n)', bygroups(Whitespace, String, Whitespace), "#pop"),
],
'url': [
(r'([ \t]*)(\S*)([ \t]*\n )', bygroups(Whitespace, Comment.PreprocFile, Whitespace)),
(r'([ \t]*)(\S*)([ \t]*\n)', bygroups(Whitespace, Comment.PreprocFile, Whitespace), "#pop"),
],
"dn": [
(r'([ \t]*)([-a-zA-Z0-9\.]+)(=)', bygroups(Whitespace, Name.Attribute, Operator), ("#pop", "dn-value")),
],
"dn-value": [
(r'\\[^\n]', Escape),
(r',', Punctuation, ("#pop", "dn")),
(r'\+', Operator, ("#pop", "dn")),
(r'[^,\+\n]+', String),
(r'\n ', Whitespace),
(r'\n', Whitespace, "#pop"),
],
"base64-dn": [
(r'([ \t]*)([^ \t\n][^ \t\n]*[^\n])([ \t]*\n )', bygroups(Whitespace, Name, Whitespace)),
(r'([ \t]*)([^ \t\n][^ \t\n]*[^\n])([ \t]*\n)', bygroups(Whitespace, Name, Whitespace), "#pop"),
]
}
188 changes: 188 additions & 0 deletions tests/examplefiles/ldif/rfc2849.ldif
@@ -0,0 +1,188 @@
version: 1
dn: cn=Barbara Jensen, ou=Product Development, dc=airius, dc=com
objectclass: top
objectclass: person
objectclass: organizationalPerson
cn: Barbara Jensen
cn: Barbara J Jensen
cn: Babs Jensen
sn: Jensen
uid: bjensen
telephonenumber: +1 408 555 1212
description: A big sailing fan.

dn: cn=Bjorn Jensen, ou=Accounting, dc=airius, dc=com
objectclass: top
objectclass: person
objectclass: organizationalPerson
cn: Bjorn Jensen
sn: Jensen
telephonenumber: +1 408 555 1212

version: 1
dn:cn=Barbara Jensen, ou=Product Development, dc=airius, dc=com
objectclass:top
objectclass:person
objectclass:organizationalPerson
cn:Barbara Jensen
cn:Barbara J Jensen
cn:Babs Jensen
sn:Jensen
uid:bjensen
telephonenumber:+1 408 555 1212
description:Babs is a big sailing fan, and travels extensively in sea
rch of perfect sailing conditions.
title:Product Manager, Rod and Reel Division

version: 1
dn: cn=Gern Jensen, ou=Product Testing, dc=airius, dc=com
objectclass: top
objectclass: person
objectclass: organizationalPerson
cn: Gern Jensen
cn: Gern O Jensen
sn: Jensen
uid: gernj
telephonenumber: +1 408 555 1212
description:: V2hhdCBhIGNhcmVmdWwgcmVhZGVyIHlvdSBhcmUhICBUaGlzIHZhbHVl
IGlzIGJhc2UtNjQtZW5jb2RlZCBiZWNhdXNlIGl0IGhhcyBhIGNvbnRyb2wgY2hhcmFjdG
VyIGluIGl0IChhIENSKS4NICBCeSB0aGUgd2F5LCB5b3Ugc2hvdWxkIHJlYWxseSBnZXQg
b3V0IG1vcmUu

version: 1
dn:: b3U95Za25qWt6YOoLG89QWlyaXVz
# dn:: ou=<JapaneseOU>,o=Airius
objectclass: top
objectclass: organizationalUnit
ou:: 5Za25qWt6YOo
# ou:: <JapaneseOU>
ou;lang-ja:: 5Za25qWt6YOo
# ou;lang-ja:: <JapaneseOU>
ou;lang-ja;phonetic:: 44GI44GE44GO44KH44GG44G2
# ou;lang-ja:: <JapaneseOU_in_phonetic_representation>
ou;lang-en: Sales
description: Japanese office

dn:: dWlkPXJvZ2FzYXdhcmEsb3U95Za25qWt6YOoLG89QWlyaXVz
# dn:: uid=<uid>,ou=<JapaneseOU>,o=Airius
userpassword: {SHA}O3HSv1MusyL4kTjP+HKI5uxuNoM=
objectclass: top
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
uid: rogasawara
mail: rogasawara@airius.co.jp
givenname;lang-ja:: 44Ot44OJ44OL44O8
# givenname;lang-ja:: <JapaneseGivenname>
sn;lang-ja:: 5bCP56yg5Y6f
# sn;lang-ja:: <JapaneseSn>
cn;lang-ja:: 5bCP56yg5Y6fIOODreODieODi+ODvA==
# cn;lang-ja:: <JapaneseCn>
title;lang-ja:: 5Za25qWt6YOoIOmDqOmVtw==
# title;lang-ja:: <JapaneseTitle>
preferredlanguage: ja
givenname:: 44Ot44OJ44OL44O8
# givenname:: <JapaneseGivenname>
sn:: 5bCP56yg5Y6f
# sn:: <JapaneseSn>
cn:: 5bCP56yg5Y6fIOODreODieODi+ODvA==
# cn:: <JapaneseCn>
title:: 5Za25qWt6YOoIOmDqOmVtw==
# title:: <JapaneseTitle>
givenname;lang-ja;phonetic:: 44KN44Gp44Gr44O8
# givenname;lang-ja;phonetic:: <JapaneseGivenname_in_phonetic_representation_kana>
sn;lang-ja;phonetic:: 44GK44GM44GV44KP44KJ
# sn;lang-ja;phonetic:: <JapaneseSn_in_phonetic_representation_kana>
cn;lang-ja;phonetic:: 44GK44GM44GV44KP44KJIOOCjeOBqeOBq+ODvA==
# cn;lang-ja;phonetic:: <JapaneseCn_in_phonetic_representation_kana>
title;lang-ja;phonetic:: 44GI44GE44GO44KH44GG44G2IOOBtuOBoeOCh+OBhg==
# title;lang-ja;phonetic:: <JapaneseTitle_in_phonetic_representation_kana>
givenname;lang-en: Rodney
sn;lang-en: Ogasawara
cn;lang-en: Rodney Ogasawara
title;lang-en: Sales, Director

version: 1
dn: cn=Horatio Jensen, ou=Product Testing, dc=airius, dc=com
objectclass: top
objectclass: person
objectclass: organizationalPerson
cn: Horatio Jensen

cn: Horatio N Jensen
sn: Jensen
uid: hjensen
telephonenumber: +1 408 555 1212
jpegphoto:< file:///usr/local/directory/photos/hjensen.jpg

version: 1
# Add a new entry
dn: cn=Fiona Jensen, ou=Marketing, dc=airius, dc=com
changetype: add
objectclass: top
objectclass: person
objectclass: organizationalPerson
cn: Fiona Jensen
sn: Jensen
uid: fiona
telephonenumber: +1 408 555 1212
jpegphoto:< file:///usr/local/directory/photos/fiona.jpg

# Delete an existing entry
dn: cn=Robert Jensen, ou=Marketing, dc=airius, dc=com
changetype: delete

# Modify an entry's relative distinguished name
dn: cn=Paul Jensen, ou=Product Development, dc=airius, dc=com
changetype: modrdn
newrdn: cn=Paula Jensen
deleteoldrdn: 1

# Rename an entry and move all of its children to a new location in
# the directory tree (only implemented by LDAPv3 servers).
dn: ou=PD Accountants, ou=Product Development, dc=airius, dc=com
changetype: modrdn
newrdn: ou=Product Development Accountants
deleteoldrdn: 0
newsuperior: ou=Accounting, dc=airius, dc=com

# Modify an entry: add an additional value to the postaladdress
# attribute, completely delete the description attribute, replace
# the telephonenumber attribute with two values, and delete a specific
# value from the facsimiletelephonenumber attribute
dn: cn=Paula Jensen, ou=Product Development, dc=airius, dc=com
changetype: modify
add: postaladdress
postaladdress: 123 Anystreet $ Sunnyvale, CA $ 94086
-

delete: description
-
replace: telephonenumber
telephonenumber: +1 408 555 1234
telephonenumber: +1 408 555 5678
-
delete: facsimiletelephonenumber
facsimiletelephonenumber: +1 408 555 9876
-

# Modify an entry: replace the postaladdress attribute with an empty
# set of values (which will cause the attribute to be removed), and
# delete the entire description attribute. Note that the first will
# always succeed, while the second will only succeed if at least
# one value for the description attribute is present.
dn: cn=Ingrid Jensen, ou=Product Support, dc=airius, dc=com
changetype: modify
replace: postaladdress
-
delete: description
-

version: 1
# Delete an entry. The operation will attach the LDAPv3
# Tree Delete Control defined in [9]. The criticality
# field is "true" and the controlValue field is
# absent, as required by [9].
dn: ou=Product Development, dc=airius, dc=com
control: 1.2.840.113556.1.4.805 true
changetype: delete