Grammalecte  Hex Artifact Content

Artifact f8aade78d9dd33254720242285b24f09e0bc9bb68e4f744a2b407d8515027b09:


0000: 22 22 22 0a 47 72 61 6d 6d 61 6c 65 63 74 65 2c  """.Grammalecte,
0010: 20 67 72 61 6d 6d 61 72 20 63 68 65 63 6b 65 72   grammar checker
0020: 0a 22 22 22 0a 0a 69 6d 70 6f 72 74 20 69 6d 70  ."""..import imp
0030: 6f 72 74 6c 69 62 0a 69 6d 70 6f 72 74 20 6a 73  ortlib.import js
0040: 6f 6e 0a 0a 66 72 6f 6d 20 2e 20 69 6d 70 6f 72  on..from . impor
0050: 74 20 74 65 78 74 0a 0a 0a 63 6c 61 73 73 20 47  t text...class G
0060: 72 61 6d 6d 61 72 43 68 65 63 6b 65 72 3a 0a 20  rammarChecker:. 
0070: 20 20 20 22 47 72 61 6d 6d 61 72 43 68 65 63 6b     "GrammarCheck
0080: 65 72 3a 20 57 72 61 70 70 65 72 20 66 6f 72 20  er: Wrapper for 
0090: 74 68 65 20 67 72 61 6d 6d 61 72 20 63 68 65 63  the grammar chec
00a0: 6b 65 72 20 65 6e 67 69 6e 65 22 0a 0a 20 20 20  ker engine"..   
00b0: 20 64 65 66 20 5f 5f 69 6e 69 74 5f 5f 20 28 73   def __init__ (s
00c0: 65 6c 66 2c 20 73 4c 61 6e 67 43 6f 64 65 2c 20  elf, sLangCode, 
00d0: 73 43 6f 6e 74 65 78 74 3d 22 50 79 74 68 6f 6e  sContext="Python
00e0: 22 29 3a 0a 20 20 20 20 20 20 20 20 73 65 6c 66  "):.        self
00f0: 2e 73 4c 61 6e 67 43 6f 64 65 20 3d 20 73 4c 61  .sLangCode = sLa
0100: 6e 67 43 6f 64 65 0a 20 20 20 20 20 20 20 20 23  ngCode.        #
0110: 20 47 72 61 6d 6d 61 72 20 63 68 65 63 6b 65 72   Grammar checker
0120: 20 65 6e 67 69 6e 65 0a 20 20 20 20 20 20 20 20   engine.        
0130: 73 65 6c 66 2e 67 63 65 20 3d 20 69 6d 70 6f 72  self.gce = impor
0140: 74 6c 69 62 2e 69 6d 70 6f 72 74 5f 6d 6f 64 75  tlib.import_modu
0150: 6c 65 28 22 2e 22 2b 73 4c 61 6e 67 43 6f 64 65  le("."+sLangCode
0160: 2c 20 22 67 72 61 6d 6d 61 6c 65 63 74 65 22 29  , "grammalecte")
0170: 0a 20 20 20 20 20 20 20 20 73 65 6c 66 2e 67 63  .        self.gc
0180: 65 2e 6c 6f 61 64 28 73 43 6f 6e 74 65 78 74 29  e.load(sContext)
0190: 0a 20 20 20 20 20 20 20 20 23 20 53 70 65 6c 6c  .        # Spell
01a0: 20 63 68 65 63 6b 65 72 0a 20 20 20 20 20 20 20   checker.       
01b0: 20 73 65 6c 66 2e 6f 53 70 65 6c 6c 43 68 65 63   self.oSpellChec
01c0: 6b 65 72 20 3d 20 73 65 6c 66 2e 67 63 65 2e 67  ker = self.gce.g
01d0: 65 74 53 70 65 6c 6c 43 68 65 63 6b 65 72 28 29  etSpellChecker()
01e0: 0a 20 20 20 20 20 20 20 20 23 20 4c 65 78 69 63  .        # Lexic
01f0: 6f 67 72 61 70 68 65 72 0a 20 20 20 20 20 20 20  ographer.       
0200: 20 73 65 6c 66 2e 6f 4c 65 78 69 63 6f 67 72 61   self.oLexicogra
0210: 70 68 65 72 20 3d 20 4e 6f 6e 65 0a 20 20 20 20  pher = None.    
0220: 20 20 20 20 23 20 54 65 78 74 20 66 6f 72 6d 61      # Text forma
0230: 74 74 65 72 0a 20 20 20 20 20 20 20 20 73 65 6c  tter.        sel
0240: 66 2e 6f 54 65 78 74 46 6f 72 6d 61 74 74 65 72  f.oTextFormatter
0250: 20 3d 20 4e 6f 6e 65 0a 0a 20 20 20 20 64 65 66   = None..    def
0260: 20 67 65 74 47 43 45 6e 67 69 6e 65 20 28 73 65   getGCEngine (se
0270: 6c 66 29 3a 0a 20 20 20 20 20 20 20 20 22 72 65  lf):.        "re
0280: 74 75 72 6e 20 74 68 65 20 67 72 61 6d 6d 61 72  turn the grammar
0290: 20 63 68 65 63 6b 65 72 20 6f 62 6a 65 63 74 22   checker object"
02a0: 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20  .        return 
02b0: 73 65 6c 66 2e 67 63 65 0a 0a 20 20 20 20 64 65  self.gce..    de
02c0: 66 20 67 65 74 53 70 65 6c 6c 43 68 65 63 6b 65  f getSpellChecke
02d0: 72 20 28 73 65 6c 66 29 3a 0a 20 20 20 20 20 20  r (self):.      
02e0: 20 20 22 72 65 74 75 72 6e 20 74 68 65 20 73 70    "return the sp
02f0: 65 6c 6c 20 63 68 65 63 6b 65 72 20 6f 62 6a 65  ell checker obje
0300: 63 74 22 0a 20 20 20 20 20 20 20 20 72 65 74 75  ct".        retu
0310: 72 6e 20 73 65 6c 66 2e 6f 53 70 65 6c 6c 43 68  rn self.oSpellCh
0320: 65 63 6b 65 72 0a 0a 20 20 20 20 64 65 66 20 67  ecker..    def g
0330: 65 74 54 65 78 74 46 6f 72 6d 61 74 74 65 72 20  etTextFormatter 
0340: 28 73 65 6c 66 29 3a 0a 20 20 20 20 20 20 20 20  (self):.        
0350: 22 6c 6f 61 64 20 61 6e 64 20 72 65 74 75 72 6e  "load and return
0360: 20 74 68 65 20 74 65 78 74 20 66 6f 72 6d 61 74   the text format
0370: 74 65 72 22 0a 20 20 20 20 20 20 20 20 69 66 20  ter".        if 
0380: 73 65 6c 66 2e 6f 54 65 78 74 46 6f 72 6d 61 74  self.oTextFormat
0390: 74 65 72 20 69 73 20 4e 6f 6e 65 3a 0a 20 20 20  ter is None:.   
03a0: 20 20 20 20 20 20 20 20 20 74 66 20 3d 20 69 6d           tf = im
03b0: 70 6f 72 74 6c 69 62 2e 69 6d 70 6f 72 74 5f 6d  portlib.import_m
03c0: 6f 64 75 6c 65 28 22 2e 22 2b 73 65 6c 66 2e 73  odule("."+self.s
03d0: 4c 61 6e 67 43 6f 64 65 2b 22 2e 74 65 78 74 66  LangCode+".textf
03e0: 6f 72 6d 61 74 74 65 72 22 2c 20 22 67 72 61 6d  ormatter", "gram
03f0: 6d 61 6c 65 63 74 65 22 29 0a 20 20 20 20 20 20  malecte").      
0400: 20 20 20 20 20 20 73 65 6c 66 2e 6f 54 65 78 74        self.oText
0410: 46 6f 72 6d 61 74 74 65 72 20 3d 20 74 66 2e 54  Formatter = tf.T
0420: 65 78 74 46 6f 72 6d 61 74 74 65 72 28 29 0a 20  extFormatter(). 
0430: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 73 65         return se
0440: 6c 66 2e 6f 54 65 78 74 46 6f 72 6d 61 74 74 65  lf.oTextFormatte
0450: 72 0a 0a 20 20 20 20 64 65 66 20 67 65 74 4c 65  r..    def getLe
0460: 78 69 63 6f 67 72 61 70 68 65 72 20 28 73 65 6c  xicographer (sel
0470: 66 29 3a 0a 20 20 20 20 20 20 20 20 22 6c 6f 61  f):.        "loa
0480: 64 20 61 6e 64 20 72 65 74 75 72 6e 20 74 68 65  d and return the
0490: 20 6c 65 78 69 63 6f 67 72 61 70 68 65 72 22 0a   lexicographer".
04a0: 20 20 20 20 20 20 20 20 69 66 20 73 65 6c 66 2e          if self.
04b0: 6f 4c 65 78 69 63 6f 67 72 61 70 68 65 72 20 69  oLexicographer i
04c0: 73 20 4e 6f 6e 65 3a 0a 20 20 20 20 20 20 20 20  s None:.        
04d0: 20 20 20 20 6c 78 67 20 3d 20 69 6d 70 6f 72 74      lxg = import
04e0: 6c 69 62 2e 69 6d 70 6f 72 74 5f 6d 6f 64 75 6c  lib.import_modul
04f0: 65 28 22 2e 22 2b 73 65 6c 66 2e 73 4c 61 6e 67  e("."+self.sLang
0500: 43 6f 64 65 2b 22 2e 6c 65 78 69 63 6f 67 72 61  Code+".lexicogra
0510: 70 68 65 22 2c 20 22 67 72 61 6d 6d 61 6c 65 63  phe", "grammalec
0520: 74 65 22 29 0a 20 20 20 20 20 20 20 20 20 20 20  te").           
0530: 20 73 65 6c 66 2e 6f 4c 65 78 69 63 6f 67 72 61   self.oLexicogra
0540: 70 68 65 72 20 3d 20 6c 78 67 2e 4c 65 78 69 63  pher = lxg.Lexic
0550: 6f 67 72 61 70 68 65 28 73 65 6c 66 2e 6f 53 70  ographe(self.oSp
0560: 65 6c 6c 43 68 65 63 6b 65 72 29 0a 20 20 20 20  ellChecker).    
0570: 20 20 20 20 72 65 74 75 72 6e 20 73 65 6c 66 2e      return self.
0580: 6f 4c 65 78 69 63 6f 67 72 61 70 68 65 72 0a 0a  oLexicographer..
0590: 20 20 20 20 64 65 66 20 64 69 73 70 6c 61 79 47      def displayG
05a0: 43 4f 70 74 69 6f 6e 73 20 28 73 65 6c 66 29 3a  COptions (self):
05b0: 0a 20 20 20 20 20 20 20 20 22 64 69 73 70 6c 61  .        "displa
05c0: 79 20 74 68 65 20 67 72 61 6d 6d 61 72 20 63 68  y the grammar ch
05d0: 65 63 6b 65 72 20 6f 70 74 69 6f 6e 73 22 0a 20  ecker options". 
05e0: 20 20 20 20 20 20 20 73 65 6c 66 2e 67 63 65 2e         self.gce.
05f0: 64 69 73 70 6c 61 79 4f 70 74 69 6f 6e 73 28 29  displayOptions()
0600: 0a 0a 20 20 20 20 64 65 66 20 67 65 74 50 61 72  ..    def getPar
0610: 61 67 72 61 70 68 45 72 72 6f 72 73 20 28 73 65  agraphErrors (se
0620: 6c 66 2c 20 73 54 65 78 74 2c 20 64 4f 70 74 69  lf, sText, dOpti
0630: 6f 6e 73 3d 4e 6f 6e 65 2c 20 62 43 6f 6e 74 65  ons=None, bConte
0640: 78 74 3d 46 61 6c 73 65 2c 20 62 53 70 65 6c 6c  xt=False, bSpell
0650: 53 75 67 67 3d 46 61 6c 73 65 2c 20 62 44 65 62  Sugg=False, bDeb
0660: 75 67 3d 46 61 6c 73 65 29 3a 0a 20 20 20 20 20  ug=False):.     
0670: 20 20 20 22 72 65 74 75 72 6e 73 20 61 20 74 75     "returns a tu
0680: 70 6c 65 3a 20 28 67 72 61 6d 6d 61 72 20 65 72  ple: (grammar er
0690: 72 6f 72 73 2c 20 73 70 65 6c 6c 69 6e 67 20 65  rors, spelling e
06a0: 72 72 6f 72 73 29 22 0a 20 20 20 20 20 20 20 20  rrors)".        
06b0: 61 47 72 61 6d 6d 45 72 72 73 20 3d 20 73 65 6c  aGrammErrs = sel
06c0: 66 2e 67 63 65 2e 70 61 72 73 65 28 73 54 65 78  f.gce.parse(sTex
06d0: 74 2c 20 22 46 52 22 2c 20 62 44 65 62 75 67 3d  t, "FR", bDebug=
06e0: 62 44 65 62 75 67 2c 20 64 4f 70 74 69 6f 6e 73  bDebug, dOptions
06f0: 3d 64 4f 70 74 69 6f 6e 73 2c 20 62 43 6f 6e 74  =dOptions, bCont
0700: 65 78 74 3d 62 43 6f 6e 74 65 78 74 29 0a 20 20  ext=bContext).  
0710: 20 20 20 20 20 20 61 53 70 65 6c 6c 45 72 72 73        aSpellErrs
0720: 20 3d 20 73 65 6c 66 2e 6f 53 70 65 6c 6c 43 68   = self.oSpellCh
0730: 65 63 6b 65 72 2e 70 61 72 73 65 50 61 72 61 67  ecker.parseParag
0740: 72 61 70 68 28 73 54 65 78 74 2c 20 62 53 70 65  raph(sText, bSpe
0750: 6c 6c 53 75 67 67 29 0a 20 20 20 20 20 20 20 20  llSugg).        
0760: 72 65 74 75 72 6e 20 61 47 72 61 6d 6d 45 72 72  return aGrammErr
0770: 73 2c 20 61 53 70 65 6c 6c 45 72 72 73 0a 0a 20  s, aSpellErrs.. 
0780: 20 20 20 64 65 66 20 67 65 6e 65 72 61 74 65 54     def generateT
0790: 65 78 74 20 28 73 65 6c 66 2c 20 73 54 65 78 74  ext (self, sText
07a0: 2c 20 62 45 6d 70 74 79 49 66 4e 6f 45 72 72 6f  , bEmptyIfNoErro
07b0: 72 73 3d 46 61 6c 73 65 2c 20 62 53 70 65 6c 6c  rs=False, bSpell
07c0: 53 75 67 67 3d 46 61 6c 73 65 2c 20 6e 57 69 64  Sugg=False, nWid
07d0: 74 68 3d 31 30 30 2c 20 62 44 65 62 75 67 3d 46  th=100, bDebug=F
07e0: 61 6c 73 65 29 3a 0a 20 20 20 20 20 20 20 20 22  alse):.        "
07f0: 5b 74 6f 64 6f 5d 22 0a 0a 20 20 20 20 64 65 66  [todo]"..    def
0800: 20 67 65 6e 65 72 61 74 65 54 65 78 74 41 73 4a   generateTextAsJ
0810: 53 4f 4e 20 28 73 65 6c 66 2c 20 73 54 65 78 74  SON (self, sText
0820: 2c 20 62 43 6f 6e 74 65 78 74 3d 46 61 6c 73 65  , bContext=False
0830: 2c 20 62 45 6d 70 74 79 49 66 4e 6f 45 72 72 6f  , bEmptyIfNoErro
0840: 72 73 3d 46 61 6c 73 65 2c 20 62 53 70 65 6c 6c  rs=False, bSpell
0850: 53 75 67 67 3d 46 61 6c 73 65 2c 20 62 52 65 74  Sugg=False, bRet
0860: 75 72 6e 54 65 78 74 3d 46 61 6c 73 65 2c 20 62  urnText=False, b
0870: 44 65 62 75 67 3d 46 61 6c 73 65 29 3a 0a 20 20  Debug=False):.  
0880: 20 20 20 20 20 20 22 5b 74 6f 64 6f 5d 22 0a 0a        "[todo]"..
0890: 20 20 20 20 64 65 66 20 67 65 6e 65 72 61 74 65      def generate
08a0: 50 61 72 61 67 72 61 70 68 20 28 73 65 6c 66 2c  Paragraph (self,
08b0: 20 73 54 65 78 74 2c 20 64 4f 70 74 69 6f 6e 73   sText, dOptions
08c0: 3d 4e 6f 6e 65 2c 20 62 45 6d 70 74 79 49 66 4e  =None, bEmptyIfN
08d0: 6f 45 72 72 6f 72 73 3d 46 61 6c 73 65 2c 20 62  oErrors=False, b
08e0: 53 70 65 6c 6c 53 75 67 67 3d 46 61 6c 73 65 2c  SpellSugg=False,
08f0: 20 6e 57 69 64 74 68 3d 31 30 30 2c 20 62 44 65   nWidth=100, bDe
0900: 62 75 67 3d 46 61 6c 73 65 29 3a 0a 20 20 20 20  bug=False):.    
0910: 20 20 20 20 22 70 61 72 73 65 20 74 65 78 74 20      "parse text 
0920: 61 6e 64 20 72 65 74 75 72 6e 20 61 20 72 65 61  and return a rea
0930: 64 61 62 6c 65 20 74 65 78 74 20 77 69 74 68 20  dable text with 
0940: 75 6e 64 65 72 6c 69 6e 65 20 65 72 72 6f 72 73  underline errors
0950: 22 0a 20 20 20 20 20 20 20 20 61 47 72 61 6d 6d  ".        aGramm
0960: 45 72 72 73 2c 20 61 53 70 65 6c 6c 45 72 72 73  Errs, aSpellErrs
0970: 20 3d 20 73 65 6c 66 2e 67 65 74 50 61 72 61 67   = self.getParag
0980: 72 61 70 68 45 72 72 6f 72 73 28 73 54 65 78 74  raphErrors(sText
0990: 2c 20 64 4f 70 74 69 6f 6e 73 2c 20 46 61 6c 73  , dOptions, Fals
09a0: 65 2c 20 62 53 70 65 6c 6c 53 75 67 67 2c 20 62  e, bSpellSugg, b
09b0: 44 65 62 75 67 29 0a 20 20 20 20 20 20 20 20 69  Debug).        i
09c0: 66 20 62 45 6d 70 74 79 49 66 4e 6f 45 72 72 6f  f bEmptyIfNoErro
09d0: 72 73 20 61 6e 64 20 6e 6f 74 20 61 47 72 61 6d  rs and not aGram
09e0: 6d 45 72 72 73 20 61 6e 64 20 6e 6f 74 20 61 53  mErrs and not aS
09f0: 70 65 6c 6c 45 72 72 73 3a 0a 20 20 20 20 20 20  pellErrs:.      
0a00: 20 20 20 20 20 20 72 65 74 75 72 6e 20 22 22 0a        return "".
0a10: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 74          return t
0a20: 65 78 74 2e 67 65 6e 65 72 61 74 65 50 61 72 61  ext.generatePara
0a30: 67 72 61 70 68 28 73 54 65 78 74 2c 20 61 47 72  graph(sText, aGr
0a40: 61 6d 6d 45 72 72 73 2c 20 61 53 70 65 6c 6c 45  ammErrs, aSpellE
0a50: 72 72 73 2c 20 6e 57 69 64 74 68 29 0a 0a 20 20  rrs, nWidth)..  
0a60: 20 20 64 65 66 20 67 65 6e 65 72 61 74 65 50 61    def generatePa
0a70: 72 61 67 72 61 70 68 41 73 4a 53 4f 4e 20 28 73  ragraphAsJSON (s
0a80: 65 6c 66 2c 20 69 49 6e 64 65 78 2c 20 73 54 65  elf, iIndex, sTe
0a90: 78 74 2c 20 64 4f 70 74 69 6f 6e 73 3d 4e 6f 6e  xt, dOptions=Non
0aa0: 65 2c 20 62 43 6f 6e 74 65 78 74 3d 46 61 6c 73  e, bContext=Fals
0ab0: 65 2c 20 62 45 6d 70 74 79 49 66 4e 6f 45 72 72  e, bEmptyIfNoErr
0ac0: 6f 72 73 3d 46 61 6c 73 65 2c 20 62 53 70 65 6c  ors=False, bSpel
0ad0: 6c 53 75 67 67 3d 46 61 6c 73 65 2c 20 62 52 65  lSugg=False, bRe
0ae0: 74 75 72 6e 54 65 78 74 3d 46 61 6c 73 65 2c 20  turnText=False, 
0af0: 6c 4c 69 6e 65 53 65 74 3d 4e 6f 6e 65 2c 20 62  lLineSet=None, b
0b00: 44 65 62 75 67 3d 46 61 6c 73 65 29 3a 0a 20 20  Debug=False):.  
0b10: 20 20 20 20 20 20 22 70 61 72 73 65 20 74 65 78        "parse tex
0b20: 74 20 61 6e 64 20 72 65 74 75 72 6e 20 65 72 72  t and return err
0b30: 6f 72 73 20 61 73 20 61 20 4a 53 4f 4e 20 73 74  ors as a JSON st
0b40: 72 69 6e 67 22 0a 20 20 20 20 20 20 20 20 61 47  ring".        aG
0b50: 72 61 6d 6d 45 72 72 73 2c 20 61 53 70 65 6c 6c  rammErrs, aSpell
0b60: 45 72 72 73 20 3d 20 73 65 6c 66 2e 67 65 74 50  Errs = self.getP
0b70: 61 72 61 67 72 61 70 68 45 72 72 6f 72 73 28 73  aragraphErrors(s
0b80: 54 65 78 74 2c 20 64 4f 70 74 69 6f 6e 73 2c 20  Text, dOptions, 
0b90: 62 43 6f 6e 74 65 78 74 2c 20 62 53 70 65 6c 6c  bContext, bSpell
0ba0: 53 75 67 67 2c 20 62 44 65 62 75 67 29 0a 20 20  Sugg, bDebug).  
0bb0: 20 20 20 20 20 20 61 47 72 61 6d 6d 45 72 72 73        aGrammErrs
0bc0: 20 3d 20 6c 69 73 74 28 61 47 72 61 6d 6d 45 72   = list(aGrammEr
0bd0: 72 73 29 0a 20 20 20 20 20 20 20 20 69 66 20 62  rs).        if b
0be0: 45 6d 70 74 79 49 66 4e 6f 45 72 72 6f 72 73 20  EmptyIfNoErrors 
0bf0: 61 6e 64 20 6e 6f 74 20 61 47 72 61 6d 6d 45 72  and not aGrammEr
0c00: 72 73 20 61 6e 64 20 6e 6f 74 20 61 53 70 65 6c  rs and not aSpel
0c10: 6c 45 72 72 73 3a 0a 20 20 20 20 20 20 20 20 20  lErrs:.         
0c20: 20 20 20 72 65 74 75 72 6e 20 22 22 0a 20 20 20     return "".   
0c30: 20 20 20 20 20 69 66 20 6c 4c 69 6e 65 53 65 74       if lLineSet
0c40: 3a 0a 20 20 20 20 20 20 20 20 20 20 20 20 61 47  :.            aG
0c50: 72 61 6d 6d 45 72 72 73 2c 20 61 53 70 65 6c 6c  rammErrs, aSpell
0c60: 45 72 72 73 20 3d 20 74 65 78 74 2e 63 6f 6e 76  Errs = text.conv
0c70: 65 72 74 54 6f 58 59 28 61 47 72 61 6d 6d 45 72  ertToXY(aGrammEr
0c80: 72 73 2c 20 61 53 70 65 6c 6c 45 72 72 73 2c 20  rs, aSpellErrs, 
0c90: 6c 4c 69 6e 65 53 65 74 29 0a 20 20 20 20 20 20  lLineSet).      
0ca0: 20 20 20 20 20 20 72 65 74 75 72 6e 20 6a 73 6f        return jso
0cb0: 6e 2e 64 75 6d 70 73 28 7b 20 22 6c 47 72 61 6d  n.dumps({ "lGram
0cc0: 6d 61 72 45 72 72 6f 72 73 22 3a 20 61 47 72 61  marErrors": aGra
0cd0: 6d 6d 45 72 72 73 2c 20 22 6c 53 70 65 6c 6c 69  mmErrs, "lSpelli
0ce0: 6e 67 45 72 72 6f 72 73 22 3a 20 61 53 70 65 6c  ngErrors": aSpel
0cf0: 6c 45 72 72 73 20 7d 2c 20 65 6e 73 75 72 65 5f  lErrs }, ensure_
0d00: 61 73 63 69 69 3d 46 61 6c 73 65 29 0a 20 20 20  ascii=False).   
0d10: 20 20 20 20 20 69 66 20 62 52 65 74 75 72 6e 54       if bReturnT
0d20: 65 78 74 3a 0a 20 20 20 20 20 20 20 20 20 20 20  ext:.           
0d30: 20 72 65 74 75 72 6e 20 6a 73 6f 6e 2e 64 75 6d   return json.dum
0d40: 70 73 28 7b 20 22 69 50 61 72 61 67 72 61 70 68  ps({ "iParagraph
0d50: 22 3a 20 69 49 6e 64 65 78 2c 20 22 73 54 65 78  ": iIndex, "sTex
0d60: 74 22 3a 20 73 54 65 78 74 2c 20 22 6c 47 72 61  t": sText, "lGra
0d70: 6d 6d 61 72 45 72 72 6f 72 73 22 3a 20 61 47 72  mmarErrors": aGr
0d80: 61 6d 6d 45 72 72 73 2c 20 22 6c 53 70 65 6c 6c  ammErrs, "lSpell
0d90: 69 6e 67 45 72 72 6f 72 73 22 3a 20 61 53 70 65  ingErrors": aSpe
0da0: 6c 6c 45 72 72 73 20 7d 2c 20 65 6e 73 75 72 65  llErrs }, ensure
0db0: 5f 61 73 63 69 69 3d 46 61 6c 73 65 29 0a 20 20  _ascii=False).  
0dc0: 20 20 20 20 20 20 72 65 74 75 72 6e 20 6a 73 6f        return jso
0dd0: 6e 2e 64 75 6d 70 73 28 7b 20 22 69 50 61 72 61  n.dumps({ "iPara
0de0: 67 72 61 70 68 22 3a 20 69 49 6e 64 65 78 2c 20  graph": iIndex, 
0df0: 22 6c 47 72 61 6d 6d 61 72 45 72 72 6f 72 73 22  "lGrammarErrors"
0e00: 3a 20 61 47 72 61 6d 6d 45 72 72 73 2c 20 22 6c  : aGrammErrs, "l
0e10: 53 70 65 6c 6c 69 6e 67 45 72 72 6f 72 73 22 3a  SpellingErrors":
0e20: 20 61 53 70 65 6c 6c 45 72 72 73 20 7d 2c 20 65   aSpellErrs }, e
0e30: 6e 73 75 72 65 5f 61 73 63 69 69 3d 46 61 6c 73  nsure_ascii=Fals
0e40: 65 29 0a                                         e).