| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 |
- """
- Smart Symbols.
- pymdownx.smartsymbols
- Really simple plugin to add support for:
- copyright, trademark, and registered symbols
- plus/minus, not equal, arrows via:
- copyright = `(c)`
- trademark = `(tm)`
- registered = `(r)`
- plus/minus = `+/-`
- care/of = `c/o`
- fractions = `1/2` etc.
- (only certain available unicode fractions)
- arrows:
- left = `<--`
- right = `-->`
- both = `<-->`
- not equal = `=/=`
- (maybe this could be =/= in the future as this might be more
- intuitive to non-programmers)
- MIT license.
- Copyright (c) 2014 - 2017 Isaac Muse <isaacmuse@gmail.com>
- Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
- documentation files (the "Software"), to deal in the Software without restriction, including without limitation
- the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
- and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
- The above copyright notice and this permission notice shall be included in all copies or substantial portions
- of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
- TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
- CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
- """
- from markdown import Extension
- from markdown import treeprocessors
- from markdown.util import Registry
- from markdown.inlinepatterns import HtmlInlineProcessor
- RE_TRADE = ("smart-trademark", r'\(tm\)', r'™')
- RE_COPY = ("smart-copyright", r'\(c\)', r'©')
- RE_REG = ("smart-registered", r'\(r\)', r'®')
- RE_PLUSMINUS = ("smart-plus-minus", r'\+/-', r'±')
- RE_NOT_EQUAL = ("smart-not-equal", r'=/=', r'≠')
- RE_CARE_OF = ("smart-care-of", r'\bc/o\b', r'℅')
- RE_ORDINAL_NUMBERS = (
- "smart-ordinal-numbers",
- r'''(?x)
- \b
- (?P<leading>(?:[1-9][0-9]*)?)
- (?P<tail>(?<=1)(?:1|2|3)th|1st|2nd|3rd|[04-9]th)
- \b
- ''',
- lambda m: '%s%s<sup>%s</sup>' % (
- m.group('leading') if m.group('leading') else '',
- m.group('tail')[:-2], m.group('tail')[1:]
- )
- )
- RE_ARROWS = (
- "smart-arrows",
- r'(?P<arrows>\<-{2}\>|(?<!-)-{2}\>|\<-{2}(?!-))',
- lambda m: ARR[m.group('arrows')]
- )
- RE_FRACTIONS = (
- "smart-fractions",
- r'(?<!\d)(?P<fractions>1/4|1/2|3/4|1/3|2/3|1/5|2/5|3/5|4/5|1/6|5/6|1/8|3/8|5/8|7/8)(?!\d)',
- lambda m: FRAC[m.group('fractions')]
- )
- REPL = {
- 'trademark': RE_TRADE,
- 'copyright': RE_COPY,
- 'registered': RE_REG,
- 'plusminus': RE_PLUSMINUS,
- 'arrows': RE_ARROWS,
- 'notequal': RE_NOT_EQUAL,
- 'fractions': RE_FRACTIONS,
- 'ordinal_numbers': RE_ORDINAL_NUMBERS,
- 'care_of': RE_CARE_OF
- }
- FRAC = {
- "1/4": "¼",
- "1/2": "½",
- "3/4": "¾",
- "1/3": "⅓",
- "2/3": "⅔",
- "1/5": "⅕",
- "2/5": "⅖",
- "3/5": "⅗",
- "4/5": "⅘",
- "1/6": "⅙",
- "5/6": "⅚",
- "1/8": "⅛",
- "3/8": "⅜",
- "5/8": "⅝",
- "7/8": "⅞"
- }
- ARR = {
- '-->': "→",
- '<--': "←",
- '<-->': "↔"
- }
- class SmartSymbolsPattern(HtmlInlineProcessor):
- """Smart symbols patterns handler."""
- def __init__(self, pattern, replace, md):
- """Setup replace pattern."""
- super(SmartSymbolsPattern, self).__init__(pattern, md)
- self.replace = replace
- def handleMatch(self, m, data):
- """Replace symbol."""
- return self.md.htmlStash.store(
- m.expand(self.replace(m) if callable(self.replace) else self.replace),
- ), m.start(0), m.end(0)
- class SmartSymbolsExtension(Extension):
- """Smart Symbols extension."""
- def __init__(self, *args, **kwargs):
- """Setup config of which symbols are enabled."""
- self.config = {
- 'trademark': [True, 'Trademark'],
- 'copyright': [True, 'Copyright'],
- 'registered': [True, 'Registered'],
- 'plusminus': [True, 'Plus/Minus'],
- 'arrows': [True, 'Arrows'],
- 'notequal': [True, 'Not Equal'],
- 'fractions': [True, 'Fractions'],
- 'ordinal_numbers': [True, 'Ordinal Numbers'],
- 'care_of': [True, 'Care/of']
- }
- super(SmartSymbolsExtension, self).__init__(*args, **kwargs)
- def add_pattern(self, patterns, md):
- """Construct the inline symbol pattern."""
- self.patterns.register(SmartSymbolsPattern(patterns[1], patterns[2], md), patterns[0], 30)
- def extendMarkdown(self, md):
- """Create a dict of inline replace patterns and add to the tree processor."""
- configs = self.getConfigs()
- self.patterns = Registry()
- for k, v in REPL.items():
- if configs[k]:
- self.add_pattern(v, md)
- inline_processor = treeprocessors.InlineProcessor(md)
- inline_processor.inlinePatterns = self.patterns
- md.treeprocessors.register(inline_processor, "smart-symbols", 2.1)
- def makeExtension(*args, **kwargs):
- """Return extension."""
- return SmartSymbolsExtension(*args, **kwargs)
|