Advertisement
rccharles

asc adjust clipboard June, 20th 2019

Jun 20th, 2019
2,538
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. (*
  2.  
  3.   This applescript converts clipboard input into a format suited for pasting into an ASC
  4.   reply.  I observed that my copies into an ASC reply were not formated that well.  
  5.   I observed that copies from a web browser were formated much better.  I went about
  6.    adjusting the clipboard copy to the format expected by a web browser for best results.
  7.  
  8.  This applescript accepts the clipboard in either
  9.  -- plain text upon which the text is converted to HTML.  Conversion is limitted to inserting paragraph tags for blank lines and inserting links where http or https text appears. The page title is substituted for the link.  
  10.  -- HTML source code identified by text containing HTML markup.  
  11.          Caveat emptor.  
  12.  
  13. run with copy from Waterfox. List of main routines.
  14.   --- run ---
  15.   --- common ---
  16.   --- adjustCharacters ---
  17.   --- adjustBrowserHTML ---
  18.   --- adjustURLs ---
  19.   --- skipDoctype
  20.   --- adjustDuplicateAnchorURLs ---
  21.   --- adjustToAscHtml ---
  22.   --- adjustLF ---
  23.   --- convertToHTML ---
  24.  
  25. run with HTML as text from TextWrangler. List of main routines.
  26.   --- run ---
  27.   --- common ---
  28.   --- adjustCharacters ---
  29.   --- adjustBrowserHTML ---
  30.   --- adjustURLs ---
  31.   --- skipDoctype
  32.   --- adjustDuplicateAnchorURLs ---
  33.   --- adjustToAscHtml ---
  34.   --- adjustLF ---
  35.   --- adjustLF ---
  36.   --- adjustLF() ---
  37.   --- convertToHTML
  38.  
  39. run with plain text from TextWrangler. List of main routines
  40.   --- run ---
  41.   --- common ---
  42.   --- adjustCharacters ---
  43.   --- adjustURLs ---
  44.   --- addParagraphs ---
  45.   --- convertToHTML ---
  46.  
  47.  to use:
  48.  1) copy command + c what data you want to convert
  49.  2) run this applascript by double clicking on the app.
  50.  3) paste command + V into an ASC reply
  51.  
  52.  I have tested in Waterfox 56.2.9 in Yosemite.  I assume the process will work with other web browsers and other versions of macOS.
  53.  
  54.  Save as an Application Bundle.  Don't check any of the boxes.
  55.  
  56. Should you experience a problem, run in the Script Editor.
  57.   Shows how to debug via on run path. Shows items added to folder. Shows log statement.
  58.    It is easier to diagnose problems with debug information. I suggest adding log statements to your script to see what is going on.  Here is an example.  
  59.  
  60.  For testing, run in the Script Editor.
  61.         1) Click on the Event Log tab to see the output from the log statement
  62.       2) Click on Run
  63.    
  64. change log
  65. may 1, 2019   -- skip 403 forbidding title
  66. may 2, 2019   -- convert \" to ".  the \" mysteriously appears in HTML source code input.  Probably some TextEdit artifact.
  67.                 copy to TextEdit copy out of TextEdit.
  68. may 7, 2019   -- regressed May 2nd update.  Applescript was inserting \" for display purposes into output.
  69. may 8, 2019   -- special processing for html class on clipboard
  70.                         https://pastebin.com/raw/Yg138YqT
  71. may 16,2019  -- fixed hexDumpFormatOne bugs and improved output
  72. may 16,2019  -- added hexDumpFormatZero
  73. may 19,2019  -- eliminate line breaks outside the <pre>...</pre> tags in HTML. ASC intrepreting line
  74.                         breaks as meaningful <br>
  75.                         instead of white space.simplified line break code.
  76.                        https://pastebin.com/raw/Nq08cFYH
  77. may 23, 2019 -- squash leading blanks in a line. #4
  78. may 27, 2019 -- Horizontal Ellipsis. #7
  79.                          8230   U+2026  E2 80 A6    … Horizontal Ellipsis
  80.                  https://www.charset.org/utf-8/9
  81. may 28, 2019 -- decide what to do with tabs. #6
  82. may 29, 2019 -- filter titles. #1
  83.                         https://pastebin.com/raw/3xRYMXtd
  84. june 1, 2019   -- automate debugging
  85. June 8, 2019   -- Substitute title for duplicate links
  86.                         https://pastebin.com/raw/PYb9Bvri
  87. June 14, 2019 -- Substitute title for more duplicate links
  88.                         https://pastebin.com/raw/n2im5Cp5
  89. June 15, 2019 -- ignore DOCTYPE                      
  90. June 17, 2019 -- ignore signin title for lounge posts
  91. June 17, 2019 -- add "if debug" where forgotten
  92. June 18, 2019 -- skip image tags
  93.                          https://pastebin.com/raw/51DcudYf
  94.        
  95.  
  96. enhancements:
  97.  -- get pdf title
  98.  -- ignore <head>
  99.  
  100.  
  101. Author: rccharles
  102.  
  103. Copyright 2019 rccharles  
  104.      
  105.       Permission is hereby granted, free of charge, to any person obtaining a copy  
  106.       of this software and associated documentation files (the "Software"), to deal  
  107.       in the Software without restriction, including without limitation the rights  
  108.       to use, copy, modify, merge, publish, distribute, sublicense, and/or sell  
  109.       copies of the Software, and to permit persons to whom the Software is  
  110.       furnished to do so, subject to the following conditions:  
  111.        
  112.       The above copyright notice and this permission notice shall be included in all  
  113.       copies or substantial portions of the Software.  
  114.        
  115.       THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR  
  116.       IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,  
  117.       FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE  
  118.       AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER  
  119.       LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,  
  120.       OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE  
  121.        SOFTWARE.   
  122.  
  123. *)
  124.  
  125.  
  126. -- Gets invoked here when you run in AppleScript editor or double click on the app icon.
  127. on run
  128.     global debug
  129.     global squashRedundentURL
  130.     global droppedFileName
  131.    
  132.    
  133.     -- 3 and 6 are good to use
  134.     set debug to 0
  135.     -- 0 no debugging
  136.     -- 1 displays input and output to this routine & names of dropped files
  137.     -- 2 moderate
  138.     -- 3 display I'm here for important "on" blocks
  139.     -- 4 display  important data in important "on" blocks
  140.     -- 5  display I'm here for minor "on" blocks
  141.     -- 6 intense
  142.     -- 7 spewing routine "on" blocks   
  143.     -- 8 routines the spew lots of data
  144.    
  145.     -- Write a message into the event log.
  146.     log "  --- Starting on " & ((current date) as string) & " with level " & debug & " debug." & " --- "
  147.    
  148.     -- how do we process the <a> tag?
  149.     set squashRedundentURL to true
  150.     -- true -- get title for anchor
  151.     -- false -- let title of anchor be the same as the link
  152.    
  153.     -- debugging
  154.     set droppedFileName to "::: from clipboard :::"
  155.    
  156.     set lf to character id 10
  157.    
  158.     if debug ≥ 3 then log "in --- run ---"
  159.     -- initialize clipboard for debugging run
  160.     --set the clipboard to wrapupClipboardDataSelector()
  161.    
  162.     set theList to clipboard info
  163.     if debug ≥ 2 then printClipboardInfo(theList)
  164.    
  165.    
  166.    
  167.     set cbInfo to get (clipboard info) as string
  168.    
  169.     -- Most likely, if we have HTML data in the clipboard it will be from a web browser or Word.
  170.     if cbInfo contains "HTML" then
  171.        
  172.         if debug ≥ 2 then log "run: Working with HTML Class data from clipboard."
  173.         set theBoard to the clipboard as «class HTML»
  174.        
  175.         set normalHtml to do shell script "osascript -e 'try' -e 'get the clipboard as «class HTML»' -e 'end try' | awk '{sub(/«data HTML/, \"\") sub(/»/, \"\")} {print}' | xxd -r -p "
  176.         if debug ≥ 1 then
  177.             log "run: ...Print out plain text version of inputed HTML data from the clipboard..." & return & normalHtml
  178.             hexDumpFormatOne("run: after converting to printable, normalHtml", normalHtml)
  179.         end if
  180.        
  181.         set normalHtml to adjustCharacters(normalHtml)
  182.        
  183.         set returnedData to adjustBrowserHTML(normalHtml)
  184.         if debug ≥ 2 then
  185.             log "run: ...Print out plain text version of adjusted HTML data ..." & return & returnedData
  186.             log "run: ...just printed plain text version"
  187.             log "run: printed in hex"
  188.             hexDumpFormatOne("run: returnedData", returnedData)
  189.         end if
  190.        
  191.         set returnedData to convertToHTML(returnedData)
  192.         try
  193.             if debug ≥ 2 then log "returnedData is " & returnedData
  194.         on error errStr number errorNumber
  195.             log "run: ===> We didn't find HTML data.   errStr is " & errStr & " errorNumber is " & errorNumber
  196.             return 1
  197.         end try
  198.     else
  199.         -- will work with a plain html or plain text.
  200.         try
  201.             if debug ≥ 2 then log "Working with plain html or plain text"
  202.             set clipboardData to (the clipboard as text)
  203.             if debug ≥ 2 then
  204.                 log "run: class clipboardData is " & class of clipboardData
  205.                 log "run: continuing plain html or plain text"
  206.             end if
  207.            
  208.             if debug ≥ 1 then
  209.                 log "run: inputted clipboardData is " & clipboardData
  210.                 hexDumpFormatOne("run: inputted clipboardData", clipboardData)
  211.             end if
  212.         on error errStr number errorNumber
  213.             log "run: ===> We didn't find data on the clipboard.   errStr is " & errStr & " errorNumber is " & errorNumber
  214.             display dialog "We didn't find HTML source code nor plain text on the clipboard." & return & "Please copy from a different source." giving up after 15
  215.             return 1
  216.         end try
  217.         if debug ≥ 2 then log "run: calling common"
  218.         set returnedData to common(clipboardData)
  219.     end if
  220.     if debug ≥ 2 then log "run: place on the clipboard returnedData is " & returnedData
  221.     postToCLipboard(returnedData)
  222.     -- return code
  223.     return 0
  224.    
  225. end run
  226.  
  227. -- ------------------------------------------------------
  228. -- Folder actions.
  229. -- Gets invoked here when something is dropped on the folder that this script is monitoring.
  230. -- Right click on the folder to be monitored. services > Folder Action Settup...
  231. on adding folder items to this_folder after receiving added_items
  232.     -- Write a message into the event log.
  233.     log "  --- Starting on " & ((current date) as string) & " --- "
  234.     display dialog "TBD, some assembly required."
  235. end adding folder items to
  236.  
  237. -- ------------------------------------------------------
  238. (*
  239.  Gets invoked here when something is dropped on this AppleScript icon
  240. there seemed to be some confustion when calling the open handler directly from within run, so openContinued was created.
  241. *)
  242. on open dropped_items
  243.     global debug
  244.     global squashRedundentURL
  245.     global droppedFileName
  246.    
  247.     -- see on run for details
  248.     set debug to 1
  249.    
  250.     -- how do we process the <a> tag?
  251.     set squashRedundentURL to true
  252.     -- true -- get title for anchor
  253.     -- false -- let title of anchor be the same as the link
  254.    
  255.     -- for debugging error message
  256.     set droppedFileName to ""
  257.    
  258.     -- debuging for openContinued.  Displays timed display dialogs.
  259.     set localDebug to false
  260.     -- true displayed timed dialogs
  261.     -- false skip debuging
  262.    
  263.     set debugSeparator to true
  264.     -- true place a separator between the output of dropped files
  265.     -- false nothing is added      
  266.    
  267.     -- Write a message into the event log.
  268.     log "  --- Starting on " & ((current date) as string) & " --- "
  269.    
  270.     if debug ≥ 3 then log "in --- open ---"
  271.    
  272.     openContinued(dropped_items, localDebug, debugSeparator)
  273.    
  274.     -- we tried
  275.     return 0
  276.    
  277. end open
  278.  
  279. -- ------------------------------------------------------
  280. (*
  281. there seemed to be some confustion when calling the open handler directly from within run.
  282. *)
  283. on openContinued(droppedItems, localDebug, debugSeparator)
  284.     global debug
  285.     global squashRedundentURL
  286.     global droppedFileName
  287.    
  288.     if debug ≥ 3 then log "in --- openContinued ---"
  289.    
  290.     (*
  291.     -- Debug code. let's us select all items in a folder.
  292.       set fileName to choose file with prompt "get file"
  293.       set droppeditems to {fileName}
  294.     *)
  295.     if debug ≥ 2 then log "class of droppeditems is " & class of droppedItems
  296.     if (count of droppedItems) is 1 then
  297.         set substitueString to (count of droppedItems) & " item."
  298.     else
  299.         set substitueString to (count of droppedItems) & " items."
  300.     end if
  301.     display dialog "You dropped " & substitueString & return & "  Caveat emptor. You have been warned." giving up after 6
  302.    
  303.     set totalFileData to ""
  304.     repeat with droppedItem in droppedItems
  305.         set droppedFileName to droppedItem as string
  306.         if debug ≥ 1 then
  307.             log return & "... The droppedItem is " & (droppedItem as string) & " ... " & return
  308.             if localDebug then display dialog "processing file " & (droppedItem as string) giving up after 3
  309.             log "class = " & class of droppedItem
  310.         end if
  311.        
  312.         set extIs to findExtension(droppedItem)
  313.         set extIsU to makeCaseUpper(extIs)
  314.         if extIsU is "HTML" or extIsU is "HTM" or extIsU is "TEXT" or extIsU is "TXT" then
  315.             try
  316.                
  317.                 set theFileString to droppedItem as string
  318.                 if localDebug is true and debug is 0 then display dialog "theFileString " & return & theFileString giving up after 3
  319.                 set theFile to open for access file theFileString
  320.                 set allOfFile to read theFile
  321.                 close access theFile
  322.             on error theErrorMessage number theErrorNumber
  323.                 log "==> " & theErrorMessage & "error number " & theErrorNumber
  324.                 close access theFile
  325.             end try
  326.             if debug ≥ 2 then printHeader("read from file ( allOfFile )", allOfFile)
  327.            
  328.             --if localDebug then display dialog "processing " giving up after 3
  329.             if debugSeparator then
  330.                 -- get just the filename and extension
  331.                 set justTheName to last item of textToList(theFileString, ":")
  332.                 -- prevent your web broswer from acting on html like text
  333.                 set justTheName to alterString(justTheName, "&", "&amp;")
  334.                 set justTheName to alterString(justTheName, "<", "&lt;")
  335.                 set totalFileData to totalFileData & convertToHTML("<p><pre>&nbsp;&nbsp;--&gt;&nbsp;" & justTheName & "&nbsp&lt;--</pre></p>")
  336.                 if localDebug then display dialog "length and data of totalFileData   " & (length of totalFileData) & return & totalFileData giving up after 3
  337.             end if
  338.            
  339.             -- returns data converted to clipboard html
  340.             set totalFileData to totalFileData & common(allOfFile)
  341.             if localDebug then display dialog "after length and data of totalFileData   " & (length of totalFileData) & return & totalFileData giving up after 3
  342.         else
  343.             -- we do not support this extension
  344.             if localDebug then display dialog "We only support files with extenstion of html, htm, text or txt in either case. Your file had a " & extIs & " extention. Skipping" giving up after 10
  345.         end if
  346.     end repeat
  347.    
  348.     postToCLipboard(totalFileData)
  349.     if localDebug then display dialog "posted to clipboard length and data " & (length of totalFileData) & return & totalFileData giving up after 20
  350.     -- return code
  351.     return 0
  352. end openContinued
  353.  
  354. -- ------------------------------------------------------
  355. on common(clipboardData)
  356.     global debug
  357.     if debug ≥ 3 then log "in --- common ---"
  358.     set ht to character id 9
  359.     set lf to character id 10
  360.     set cbInfo to get (clipboard info) as string
  361.    
  362.     set clipboardData to adjustCharacters(clipboardData)
  363.     (*
  364.     -- for some crazy reason, I found hex "090a" (HT LF) in a html file.
  365.     set clipboardData to alterString(clipboardData, ht & lf, lf)
  366.     -- don't let Windoze confuse us. convert Return LineFeed to lf
  367.     set clipboardData to alterString(clipboardData, return & lf, lf)
  368.     -- might as will convert classic macOS return to lf. We will have to look for less things.
  369.     set clipboardData to alterString(clipboardData, return, lf)
  370.     if debug ≥ 2 then hexDumpFormatOne("change various line ends to a LF. clipboardData", clipboardData)
  371.     *)
  372.    
  373.     -- figure out what type of data we have: plain text or html source code text.
  374.     set paraCount to count of textToList(clipboardData, "<p")
  375.     set endparaCount to count of textToList(clipboardData, "</p>")
  376.     set titleCount to count of textToList(clipboardData, "<title")
  377.     set endTitleCount to count of textToList(clipboardData, "</title>")
  378.     set aLinkCount to count of textToList(clipboardData, "href=\"http")
  379.     -- mangled href="http
  380.     set mangledLinkCount to count of textToList(clipboardData, "href=\\\"http")
  381.     set brCount to count of textToList(clipboardData, "<br>")
  382.     if debug ≥ 2 then
  383.         log "common: Values used to distinguish HTML source code from plain text."
  384.         log "common: paraCount  is " & paraCount
  385.         log "common: endparaCount is " & endparaCount
  386.         log "common: titleCount is " & titleCount
  387.         log "common: endTitleCount is " & endTitleCount
  388.         log "common: aLinkCount is " & aLinkCount
  389.         log "common: brCount is " & brCount
  390.         log "common: mangledLinkCount is " & mangledLinkCount
  391.     end if
  392.    
  393.     -- note, textToList returns a count one greater than the actual because item one is the data before the first found entry.
  394.     if paraCount ≥ 4 and endparaCount ≥ 3 or brCount ≥ 4 or ((titleCount is endTitleCount) and titleCount ≥ 2) or aLinkCount ≥ 3 or mangledLinkCount ≥ 3 then
  395.         -- ASC tends to convert line-ends to either <p></p> or <p><br></p>. Isn't desireable for HTML input
  396.         if debug ≥ 2 then log return & "common:  ... found HTML input ... (in plain text format )." & return
  397.         set clipboardData to adjustBrowserHTML(clipboardData)
  398.        
  399.     else
  400.         if debug ≥ 2 then log "common: ... found plain Text input ..."
  401.         set clipboardData to typeText(clipboardData)
  402.     end if
  403.     set readyData to convertToHTML(clipboardData)
  404.     if debug ≥ 4 then log "bye, bye from  -.- common -.-"
  405.     return readyData
  406. end common
  407.  
  408. -- ------------------------------------------------------  
  409. (* add paragraphs *)
  410. on addParagraphs(theOutputBuffer)
  411.     global debug
  412.     if debug ≥ 3 then log "in --- addParagraphs ---"
  413.     set lf to character id 10
  414.    
  415.     -- start the theOutputBuffer with a paragraph tag.  We are taking a simple approach at this time.
  416.     set theOutputBuffer to "<p>" & theOutputBuffer
  417.     --  LF
  418.     -- Remember CRLF was changed to LF above and CR was chanaged to LF above.
  419.     -- we don't want no Windoze problems
  420.     set theOutputBuffer to alterString(theOutputBuffer, lf & lf, "</p><p> </p><p>")
  421.    
  422.     -- Does the string end with a dangling paragraph?  
  423.     if debug ≥ 5 then
  424.         log "length of theOutputBuffer is " & length of theOutputBuffer
  425.     end if
  426.     if (length of theOutputBuffer) > (length of "</p>") then
  427.         if text ((length of theOutputBuffer) - 2) thru (length of theOutputBuffer) of theOutputBuffer is "<p>" then
  428.             set theOutputBuffer to text 1 thru ((length of theOutputBuffer) - 3) of theOutputBuffer
  429.         else if text ((length of theOutputBuffer) - 2) thru (length of theOutputBuffer) of theOutputBuffer is not "</p>" then
  430.             set theOutputBuffer to theOutputBuffer & "</p>"
  431.         end if
  432.     end if
  433.     if debug ≥ 4 then log "bye from  -.- addParagraphs -.-"
  434.     return theOutputBuffer
  435. end addParagraphs
  436.  
  437. -- ------------------------------------------------------
  438. (*
  439.   We received HTML class data on the clipboard.  This is the manager.
  440.   At this point, we expect only LFs in the text.
  441.  *)
  442. on adjustBrowserHTML(normalHtml)
  443.     global debug
  444.     if debug ≥ 3 then log "in --- adjustBrowserHTML ---"
  445.     set lf to character id 10
  446.    
  447.     set alteredHTML to adjustURLs(normalHtml, {"https://", "http://", "<a ", "<img"})
  448.     set alteredHTML to adjustToAscHTML(alteredHTML)
  449.     if debug ≥ 4 then log "bye from  -.- adjustBrowserHTML -.-"
  450.     return alteredHTML
  451. end adjustBrowserHTML
  452.  
  453. -- ------------------------------------------------------
  454. (*
  455.     Symbol  Meaning                 Hex     Used
  456.         CR      Carriage Return         0d      classic Macintosh
  457.         LF      Line Feed                       0a      UNIX
  458.         CR/LF   Carriage Return/Line Feed   0d0a    MS-DOS, Windows, OS/2
  459.        
  460.     8230    U+2026  E2 80 A6    … Horizontal Ellipsis
  461.         https://www.charset.org/utf-8/9
  462.        &hellip;
  463.         https://www.toptal.com/designers/htmlarrows/punctuation/horizontal-ellipsis/
  464.  
  465.     *)
  466. on adjustCharacters(normalHtml)
  467.     global debug
  468.     set ht to character id 9 -- horizontal tab
  469.     set lf to character id 10
  470.     set ellipsis1 to character id 226
  471.     set ellipsis2 to character id 128
  472.     set ellipsis3 to character id 166
  473.    
  474.     if debug ≥ 3 then log "in --- adjustCharacters() ---"
  475.    
  476.     -- for some reason web broswers are having difficulty with utf-8 E2 80 A6
  477.     -- so convert to a HTML entity.  does work in <pre>
  478.     set normalHtml to alterString(normalHtml, ellipsis1 & ellipsis2 & ellipsis3, "&hellip;")
  479.    
  480.     -- don't let Windoze confuse us. convert Return LineFeed to lf
  481.     set normalHtml to alterString(normalHtml, return & lf, lf)
  482.     -- might as will convert classic macOS return to lf. We will have to look for less things.
  483.     set normalHtml to alterString(normalHtml, return, lf)
  484.     if debug ≥ 3 then hexDumpFormatOne("adjustCharacters: after altering characters normalHtml", normalHtml)
  485.     return normalHtml
  486. end adjustCharacters
  487.  
  488. -- ------------------------------------------------------
  489. (*
  490.   Is the displayed title the same as the href URL?
  491.   <a href="https://support.apple.com/en-ca/HT204759">https://support.apple.com/en-ca/HT204759</a>
  492.  
  493.   -- span tag; blank before https:  
  494.  <a href="https://reportaproblem.apple.com/?s=6"><span style="font-family: Arial;"> https://reportaproblem.apple.com/?s=6</span></a>
  495.  
  496.  -- blank display field
  497.  <a href="https://reportaproblem.apple.com/?s=6"></a>
  498.  
  499.  -- guard against http in DOCTYPE.
  500.  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
  501.  https://html.com/tags/doctype/
  502.  
  503. *)
  504. on adjustDuplicateAnchorURLs(anchorTagInput)
  505.     global debug
  506.     global squashRedundentURL
  507.     set lf to character id 10
  508.    
  509.     if debug ≥ 3 then log "in --- adjustDuplicateAnchorURLs ---"
  510.    
  511.     -- reduce LFs in title
  512.     set anchorTagString to alterString(anchorTagInput, lf, " ")
  513.     if debug ≥ 2 then hexDumpFormatOne("  adjustDuplicateAnchorURLs: anchorTagString", anchorTagString)
  514.    
  515.     -- Does the user want us to get the title for duplicate URLs?
  516.     if squashRedundentURL is false then
  517.         return anchorTagString -- --------- ignore duplicates ---------->
  518.     end if
  519.    
  520.     set splitList to textToList(anchorTagString, "href=")
  521.     if debug ≥ 4 then printList("adjustDuplicateAnchorURLs: splitList", splitList)
  522.     -- Deal with document anchor points.  <a href="#refunds">Refunds</a>
  523.     if (count of splitList) ≤ 1 then
  524.         -- we didn't find a linking anchor point. no href.
  525.         return anchorTagString -- --------- not a linking <a> tag  ---------->
  526.     end if
  527.    
  528.     -- get href url.
  529.     set hrefURL to tagContent(item 2 of splitList, "\"", "\"")
  530.     if debug ≥ 2 then log "  adjustDuplicateAnchorURLs: hrefURL is " & hrefURL
  531.    
  532.     -- get display information
  533.     set titleURL to tagContent(item 2 of splitList, ">", "</a>")
  534.     if debug ≥ 2 then log "  adjustDuplicateAnchorURLs: titleURL is " & titleURL
  535.    
  536.     -- for the display text to contain an URL it must be at least "http://" characters long.
  537.     if (length of titleURL)(length of "http://") then
  538.         -- we didn't find a url in the display text
  539.         return anchorTagString -- --------- no url in display text  ---------->
  540.     end if
  541.    
  542.    
  543.     -- http or https?
  544.     set aTagSeparator to ""
  545.     -- note, in case the delimiter isn't found all the text is returen in item # 1
  546.     set splitURLhttp to splitTextToList(titleURL, "http://")
  547.     if debug ≥ 2 then log "count of splitURLhttp is " & (count of splitURLhttp)
  548.     if debug ≥ 2 then printList("adjustDuplicateAnchorURLs: splitURLhttp is", splitURLhttp)
  549.    
  550.     set splitURLhttps to splitTextToList(titleURL, "https://")
  551.     if debug ≥ 2 then log "adjustDuplicateAnchorURLs: count of splitURLhttps is " & (count of splitURLhttps)
  552.     if debug ≥ 2 then printList("adjustDuplicateAnchorURLs: splitURLhttps is", splitURLhttps)
  553.    
  554.     set splitURLhttpLength to length of (item 1 of splitURLhttp)
  555.     set LengthsplitURLhttps to length of (item 1 of splitURLhttps)
  556.    
  557.     -- did we find the http:// header?
  558.     if (count of splitURLhttp)2 then
  559.         if debug ≥ 2 then log "adjustDuplicateAnchorURLs: http found"
  560.         set aTagSeparator to (item 1 of splitURLhttp)
  561.         -- might be a little too general.  allows blanks and line ends in the middle of the url
  562.         -- when I have seen them only in front and end.
  563.         set {titleURL, trailingText} to urlEndsWHere(item 2 of splitURLhttp)
  564.        
  565.         -- did we find the https:// header? Hence, item # 2 will be present containing what's after
  566.         -- https://
  567.     else if (count of splitURLhttps)2 then
  568.         if debug ≥ 2 then log "adjustDuplicateAnchorURLs: https found"
  569.         set aTagSeparator to (item 1 of splitURLhttps)
  570.         -- ditto
  571.         set {titleURL, trailingText} to urlEndsWHere(item 2 of splitURLhttps)
  572.     else
  573.         if debug ≥ 2 then log "adjustDuplicateAnchorURLs: no url in display text"
  574.         -- RW puts a blank character in front of the display string :-(
  575.         if length of titleURL > 0 then
  576.             if debug ≥ 2 then log "adjustDuplicateAnchorURLs: commentry title text"
  577.             return anchorTagString -- --------- ignore duplicates ---------->          
  578.         end if
  579.         ---------------------------------------- need to adjust above ..............
  580.         -- text in display text, so insert title from hrefURL.  
  581.         -- some web browsers use hrefURL
  582.         set titleURL to hrefURL
  583.     end if
  584.     if debug ≥ 2 then log "adjustDuplicateAnchorURLs: length of aTagSeparator is " & (length of aTagSeparator) & "aTagSeparator is ->" & aTagSeparator & "<-"
  585.     -- make the comparison
  586.     if debug ≥ 2 then log "  ajdustDuplicateAnchorURLs: hrefURL is " & return & hrefURL & return & " titleURL is " & return & titleURL
  587.     if hrefURL is not titleURL then
  588.         if debug ≥ 2 then "adustDuplicateAnchorURLs: href and display text are different."
  589.         return anchorTagString -- --------- assume we have the title ---------->
  590.     end if
  591.    
  592.     -- They are the same
  593.     if debug ≥ 2 then log "  adjustDuplicateAnchorURLs: href and title are the same."
  594.     set gotTitle to getTitle(hrefURL)
  595.     if debug ≥ 2 then log "  adustDuplicateAnchorURLs: gotTitle is " & gotTitle
  596.    
  597.     -- build anchor tag.
  598.     set anchorTrailer to textToList(item 2 of splitList, ">")
  599.     if debug ≥ 4 then printList("adjustDuplicateAnchorURLs: anchorTrailer", anchorTrailer)
  600.     set anchorTagOutput to (item 1 of splitList) & " href=" & item 1 of anchorTrailer & ">" & aTagSeparator & gotTitle & trailingText & "</a>"
  601.     if debug ≥ 2 then log "  adjustDuplicateAnchorURLs: anchorTagOutout is " & anchorTagOutput
  602.     return anchorTagOutput
  603.    
  604.    
  605. end adjustDuplicateAnchorURLs
  606.  
  607. -- ------------------------------------------------------
  608. -- called for HTML processing
  609. on adjustLF(theBuffer)
  610.     global debug
  611.     set ht to character id 9
  612.     set lf to character id 10
  613.     if debug ≥ 3 then log "in --- adjustLF() ---"
  614.     if debug ≥ 2 then hexDumpFormatOne("  adjustLF: input from theBuffer", theBuffer)
  615.     set numberOfLf to 1 -- for debuggin so we can display loop count
  616.    
  617.     set inputLfBuffer to theBuffer -- now, input data
  618.     set outputBuildLf to "" -- output data
  619.     -- copy & change
  620.     -- ditch leading LFs
  621.     repeat while length of inputLfBuffer ≥ 2 and text 1 thru 1 of inputLfBuffer is lf
  622.         if debug ≥ 2 then log "  adjustLF: found leading lf. current length of inputLfBuffer is " & getIntegerAndHex(length of inputLfBuffer)
  623.         -- just lob off LF
  624.         set inputLfBuffer to text 2 thru -1 of inputLfBuffer
  625.        
  626.         if debug ≥ 2 then log "  adjustLF: next text character is ->" & (text 1 thru 1 of inputLfBuffer) & "<-"
  627.     end repeat
  628.     -- for some crazy reason, I found hex "090a" (HT LF) in a html file.
  629.     set inputLfBuffer to alterString(inputLfBuffer, ht & lf, lf)
  630.     repeat until inputLfBuffer is ""
  631.        
  632.         set whereLfOffset to offset of lf in inputLfBuffer
  633.         if debug ≥ 2 then log "  adjustLF: whereLfOffset is " & whereLfOffset & " in hex " & integerToHex(whereLfOffset)
  634.        
  635.         -- get before and after characters if present.
  636.         if whereLfOffset ≥ 2 then
  637.             set priorCharacter to (text (whereLfOffset - 1) thru (whereLfOffset - 1) in inputLfBuffer)
  638.         else
  639.             set priorCharacter to ""
  640.         end if
  641.         if whereLfOffset ≥ (length of inputLfBuffer) then
  642.             -- no following character
  643.             set followingCharacter to ""
  644.         else
  645.             set followingCharacter to (text (whereLfOffset + 1) thru (whereLfOffset + 1) in inputLfBuffer)
  646.         end if
  647.         if debug ≥ 2 then log "  adjustLF: priorCharacter is >" & priorCharacter & "< followingCharacter is >" & followingCharacter & "<"
  648.        
  649.         -- process the LF. 
  650.         if (whereLfOffset is 1) and ((length of inputLfBuffer)2) then
  651.             set inputLfBuffer to text 2 thru -1 of inputLfBuffer
  652.             if debug ≥ 2 then log "  adjustLF: leading lf.  Got rid of it."
  653.             -- nothing to move to outputBuildLf            
  654.         else if (whereLfOffset is 1) and ((length of inputLfBuffer) is 1) then
  655.             -- we have found all theLFs to find.
  656.             set inputLfBuffer to ""
  657.             if debug ≥ 2 then log "  adjustLF: only one character left.  Got rid of it."
  658.         else if followingCharacter is "" then
  659.             if debug ≥ 2 then log "null"
  660.             -- didn't we just check this? Yes, but we need to iterate somehow.
  661.             set {inputLfBuffer, outputBuildLf} to trimOneChar(inputLfBuffer, outputBuildLf, whereLfOffset, " ")
  662.             -- just skip it, so we don't have to put anything on outputBuildLf
  663.         else if priorCharacter is not ">" and priorCharacter is not " " and followingCharacter is lf then
  664.             -- reduce a series of LFs to one blank
  665.             -- the next time around the next LF will be comparing to the prior character
  666.             -- as a blank
  667.             if debug ≥ 2 then log "  adjustLF: series of LFs"
  668.             set {inputLfBuffer, outputBuildLf} to trimOneChar(inputLfBuffer, outputBuildLf, whereLfOffset, " ")
  669.         else if priorCharacter is " " and followingCharacter is tab then
  670.             -- reduce a series of LFs to one blank
  671.             -- the next time around the next LF will be comparing to the prior character
  672.             -- as a blank
  673.             if debug ≥ 2 then log "  adjustLF: series of LFs"
  674.             set {inputLfBuffer, outputBuildLf} to trimOneChar(inputLfBuffer, outputBuildLf, whereLfOffset, "")
  675.             set {inputLfBuffer, outputBuildLf} to trimCharacters(inputLfBuffer, outputBuildLf, tab)
  676.         else if priorCharacter is ">" and followingCharacter is not " " then
  677.             --  LF after HTML tag. no real need for lf here.  asc tends to make these into <p></p>
  678.             if debug ≥ 2 then log "  adjustLF: found a tag"
  679.             -- copy prior stuff
  680.             set {inputLfBuffer, outputBuildLf} to trimOneChar(inputLfBuffer, outputBuildLf, whereLfOffset, "")
  681.         else if followingCharacter is lf then
  682.             -- prevent double LFs.
  683.             if debug ≥ 2 then log "  adjustLF: prevent double LFs at" & getIntegerAndHex(whereLfOffset)
  684.             set {inputLfBuffer, outputBuildLf} to trimOneChar(inputLfBuffer, outputBuildLf, whereLfOffset, "")
  685.             -- middle of text
  686.         else if (whereLfOffset < (length of inputLfBuffer)) and followingCharacter is " " then
  687.             -- we need to avoid double blanks
  688.             -- purge
  689.             if debug ≥ 2 then log "  adjustLF: getting rid of lf at " & getIntegerAndHex(whereLfOffset)
  690.             -- skip lf.
  691.             set {inputLfBuffer, outputBuildLf} to trimOneChar(inputLfBuffer, outputBuildLf, whereLfOffset, " ")
  692.             -- get read of leading spaces.  That is the spaces after the lf
  693.             set {inputLfBuffer, outputBuildLf} to trimCharacters(inputLfBuffer, outputBuildLf, " ")
  694.         else
  695.             -- assume there are character before and after the LF.
  696.             if debug ≥ 2 then log "  adjustLF: punt."
  697.             -- replace with blank
  698.             set {inputLfBuffer, outputBuildLf} to trimOneChar(inputLfBuffer, outputBuildLf, whereLfOffset, " ")
  699.         end if
  700.        
  701.         if debug ≥ 2 then
  702.             hexDumpFormatOne("  adjustLF: outputBuildLf of " & numberOfLf, outputBuildLf)
  703.             hexDumpFormatOne("  adjustLF: inputLfBuffer of " & numberOfLf, inputLfBuffer)
  704.         end if
  705.         -- next pass will be
  706.         set numberOfLf to numberOfLf + 1
  707.     end repeat
  708.     if debug ≥ 4 then log "bye from  -.- adjustLF() -.-"
  709.     return outputBuildLf
  710. end adjustLF
  711.  
  712. -- ------------------------------------------------------
  713. (* ASC likes to insert lots of white space into a page.
  714.   This routine attempt to fix up the html to avoid
  715.   all the extra white-space.
  716.  
  717.    Minimize the amount of white space inserted.
  718.  *)
  719.  
  720. on adjustToAscHTML(ascHtml)
  721.     global debug
  722.     if debug ≥ 3 then log "in --- adjustToAscHtml ---"
  723.     set lf to character id 10
  724.     set numberOfPres to 1
  725.     -- In the context of HTML, LF should mostly be insignificant.
  726.     -- Would be bad to change a LF inside the <pre>  tag.
  727.     --skip changing lf in "<pre>.  
  728.     set buildHtml to "" -- will contain the output
  729.     if debug ≥ 2 then log "adjustToAscHTML: find <pre>s"
  730.     -- copy & change
  731.     if (offset of "</pre>" in ascHtml) is not 0 then
  732.         repeat while (offset of "</pre>" in ascHtml) is not 0
  733.             -- get text before "<pre" tag
  734.             set splitString to item 1 of splitTextToList(ascHtml, "<pre")
  735.             if debug ≥ 2 then
  736.                 log "adjustToAscHTML: splitString is " & splitString
  737.                 hexDumpFormatOne("adjustToAscHTML: buildHtml *before* adjustLF()", buildHtml)
  738.             end if
  739.             set buildHtml to buildHtml & adjustLF(splitString)
  740.             if debug ≥ 2 then hexDumpFormatOne("adjustToAscHTML: buildHtml after adjustLF()", buildHtml)
  741.            
  742.             -- lob off header text we processed
  743.             -- while we found the text before "<pre", we still need to get it out
  744.             -- of ascHtml
  745.             --  & gets rid of the token ("<pre"), so fix
  746.             set ascHtml to "<pre" & chompLeftAndTag(ascHtml, "<pre")
  747.            
  748.             -- any more <pre> tags?
  749.             if ascHtml is "" then
  750.                 display dialog "adjustToAscHTML: HTML missing </pre> tag. possible logic error." giving up after 10
  751.                 -- none. We have already adjusted buildHtml
  752.                 exit repeat -- ------ done processing ascHtml ------>
  753.             end if
  754.             if debug ≥ 2 then hexDumpFormatOne("adjustToAscHTML: remaining ascHtml is ", ascHtml)
  755.            
  756.             -- tack on the unaltered <pre>..</pre> stuff
  757.             set buildHtml to buildHtml & (item 1 of splitTextToList(ascHtml, "</pre>")) & "</pre>"
  758.             if debug ≥ 2 then hexDumpFormatOne("adjustToAscHTML: buildHtml after finding </pre>", buildHtml)
  759.            
  760.             set ascHtml to chompLeftAndTag(ascHtml, "</pre>")
  761.             if debug ≥ 2 then hexDumpFormatOne("adjustToAscHTML: ascHtml end of " & numberOfPres & " pass", ascHtml)
  762.             set numberOfPres to numberOfPres + 1
  763.            
  764.         end repeat
  765.         -- remainder
  766.         set buildHtml to buildHtml & adjustLF(ascHtml)
  767.         set ascHtml to ""
  768.     else
  769.         -- lf's are only signigicant in <pre>...</pre>
  770.         if debug ≥ 2 then log "adjustToAscHTML: didn't find a <pre>"
  771.         -- all others are white space.
  772.         set buildHtml to adjustLF(ascHtml)
  773.         set ascHtml to "" -- input text processed
  774.     end if
  775.    
  776.    
  777.     (*
  778.     Hack about to fix ASC interpretation of HTML.
  779.    
  780.     ASC alters the definition of a paragraph to have not space before or after the paragraph.
  781.     A paragraph like <p></p> works like a <br>.
  782.    
  783.     Consequently, ASC converts <p> </p> to <p><br></p>, that is a
  784.     space only paragraph to a paragraph with a <br> in it.
  785.    
  786.     the code converts one tag on a line to a line of tags.
  787.     </ol>
  788.    </p>
  789.    <p>
  790.     converted form
  791.     </ol></p><p>
  792.    
  793.     so that means a change on </ol></p><p> converts both the multi-lines form and the single line form.
  794.    
  795.     *)
  796.     set buildHtml to alterString(buildHtml, "<br> ", "<br>")
  797.     -------------------- failure???
  798.     --set buildHtml to alterString(buildHtml, "<p> ", "<p>")
  799.    
  800.     -- asc paragraphs don't generate space before and after the paragraph.
  801.     set buildHtml to alterString(buildHtml, "</p><p></p><p></p>", "</p><p> </p><p></p>")
  802.    
  803.     set buildHtml to alterString(buildHtml, "</p><p></p><p></p>", "</p><p> </p><p></p>")
  804.    
  805.     set buildHtml to alterString(buildHtml, "</ol></p><p>", "</ol><p> </p></p><p>")
  806.     (*
  807.     surprisingly ASC converts <p> </p> to <p><br></p>, that is a
  808.     space only paragraph to a paragraph with a <br> in it.
  809.    
  810.     the code converts one tag on a line to a line of tags.
  811.     </ol>
  812.     </p>
  813.     <p>
  814.     converted form
  815.     </ol></p><p>
  816.    
  817.     so that means a change on </ol></p><p> converts both the multi-lines form and the single line form.
  818.    
  819.     *)
  820.     --set buildHtml to alterString(buildHtml, "<p> </p>", "<p></p>")
  821.     if debug ≥ 2 then hexDumpFormatOne("adjustToAscHTML: complete buildHtml ", buildHtml)
  822.     if debug ≥ 4 then log "bye from  -.- adjustToAscHTML -.-"
  823.     return buildHtml
  824. end adjustToAscHTML
  825.  
  826. -- ------------------------------------------------------
  827. (*
  828. example:
  829.   Free version of Parallels for individual use:</p><p><br></p>
  830.   <p>https://itunes.apple.com/us/app/parallels-desktop-lite/id1085114709?mt=12</p>
  831.   <p><br></p>
  832.   <p>Full version</p><p><a href="http://www.parallels.com/en/products/desktop/" target="_blank">
  833.      http://www.parallels.com/en/products/desktop/</a>
  834.      
  835. If asc find a URL outside of an a tag, it will place blank lines around the URL. No, it will not go the
  836. full nine yards and place an a tag around the url.
  837.  
  838. *)
  839. on adjustURLs(theOriginalInputBuffer, linkList)
  840.     -- linkList is what type of links are we searching for.
  841.     global debug
  842.     if debug ≥ 3 then log "in --- adjustURLs ---"
  843.     set alteredBuffer to false
  844.     set lf to character id 10
  845.     set theInputBuffer to theOriginalInputBuffer
  846.     if debug ≥ 2 then hexDumpFormatOne("  adjustURLs: theInputBuffer", theInputBuffer)
  847.    
  848.     -- we end up in a lot of grief when the buffer ends without
  849.     -- a line-end
  850.     if text (length of theInputBuffer) thru (length of theInputBuffer) of theInputBuffer is not lf then
  851.         -- tack LF at the end
  852.         set alteredBuffer to true
  853.         set theInputBuffer to theInputBuffer & lf
  854.         if debug ≥ 2 then hexDumpFormatOne("  adjustURLs: theInputBuffer", theInputBuffer)
  855.     end if
  856.    
  857.     set buildHtml to ""
  858.     -- DOCTYPE contains a http link, but it's not something we want to mess with.
  859.     set {buildHtml, theInputBuffer} to skipDoctype(buildHtml, theInputBuffer)
  860.    
  861.     set countI to 1 -- variable is used for debuging.
  862.     -- do until we have processed theInputBuffer
  863.     repeat until theInputBuffer is ""
  864.         if debug ≥ 2 then log "  adjustURLs: at the top of theInputBuffer ........."
  865.        
  866.         set foundWhere to {}
  867.         repeat with lookCharacters in linkList
  868.             copy (offset of lookCharacters in theInputBuffer) to the end of the foundWhere
  869.             try
  870.                 set tempLoc to (offset of lookCharacters in theInputBuffer)
  871.                 if debug ≥ 2 then log "  adjustURLs: searching for " & lookCharacters & " found at offset  " & tempLoc & " contains " & text tempLoc thru (tempLoc + ((length of lookCharacters) - 1)) of theInputBuffer
  872.             end try
  873.         end repeat
  874.         if debug ≥ 2 then log foundWhere
  875.         set foundMarkerOffset to (minimumPositiveNumber from foundWhere)
  876.         -- figure out what type of marker we got?
  877.        
  878.         -- None.  Reached the end of the data without finding one.
  879.         if foundMarkerOffset ≤ 0 then
  880.             -- we are done
  881.             if debug ≥ 2 then log "  adjustURLs: Found all links."
  882.             set buildHtml to buildHtml & theInputBuffer
  883.             if debug ≥ 2 then printHeader("  adjustURLs: buildHTML", buildHtml)
  884.             set theInputBuffer to ""
  885.             exit repeat -- ------ done processing theInputBuffer ------>
  886.         end if
  887.        
  888.         -- find which marker did we found.
  889.         -- seems a bit redunant.
  890.         set actualMarker to ""
  891.         if (text foundMarkerOffset thru (foundMarkerOffset + 2) of theInputBuffer) is "<a " then
  892.             set actualMarker to "<a "
  893.         else if text foundMarkerOffset thru (foundMarkerOffset + 3) of theInputBuffer is "<img" then
  894.             set actualMarker to "<img"
  895.         else if text foundMarkerOffset thru (foundMarkerOffset + 6) of theInputBuffer is "http://" then
  896.             set actualMarker to "http://"
  897.         else if text foundMarkerOffset thru (foundMarkerOffset + 7) of theInputBuffer is "https://" then
  898.             set actualMarker to "http://"
  899.         else
  900.             -- return is hocus pocus.
  901.             display dialog "Missed marker tag.  Found " & text foundMarkerOffset thru (foundMarkerOffset + 7) of theInputBuffer & " We will continue on, but no one knows how well." giving up after 10
  902.             log "  adjustURLs: ==> Missed marker tag.  Found " & text foundMarkerOffset thru (foundMarkerOffset + 7) of theInputBuffer
  903.             return theOriginalInputBuffer
  904.         end if
  905.         set actualMarkerOffsetLength to ((length of actualMarker) - 1)
  906.         if debug ≥ 2 then
  907.             log "  adjustURLs: actualMarker is " & actualMarker & " actualMarkerOffsetLength is " & actualMarkerOffsetLength
  908.             log "  adjustURLs: foundMarkerOffset is " & getIntegerAndHex(foundMarkerOffset) & "  verify marker text is " & text foundMarkerOffset thru (foundMarkerOffset + actualMarkerOffsetLength) of theInputBuffer
  909.         end if
  910.        
  911.        
  912.         if foundMarkerOffset ≥ 2 then
  913.             -- collect and strip off characters that are before the marker.
  914.             if debug ≥ 2 then
  915.                 log "  adjustURLs: buildHTML is " & buildHtml & " length is " & getIntegerAndHex(length of buildHtml)
  916.                 hexDumpFormatOne("  adjustURLs: theInputBuffer", theInputBuffer)
  917.                 log "  adjustURLs:  (foundMarkerOffset - 1) is " & getIntegerAndHex((foundMarkerOffset - 1))
  918.             end if
  919.             -- get the proceding text
  920.             set buildHtml to buildHtml & text 1 thru (foundMarkerOffset - 1) of theInputBuffer
  921.             if debug ≥ 2 then
  922.                 log "  adjustURLs: buildHTML is " & buildHtml
  923.                 hexDumpFormatOne("  adjustURLs: buildHTML", buildHtml)
  924.             end if
  925.            
  926.             -- https://apple.stackexchange.com/a/20135/44531
  927.            
  928.             set theInputBuffer to text foundMarkerOffset thru -1 of theInputBuffer --trim off character before what we found
  929.             if debug ≥ 2 then
  930.                 printHeader("  adjustURLs: theInputBuffer", theInputBuffer)
  931.                 hexDumpFormatOne("  adjustURLs: theInputBuffer", theInputBuffer)
  932.             end if
  933.         else
  934.             log "  adjustURLs: ==> no proceeding data."
  935.         end if
  936.        
  937.         repeat 1 times -- interate loop
  938.            
  939.             -- example" the url is also the display text
  940.             -- <a href="https://discussions.apple.com/docs/DOC-8841" target="_blank">https://discussions.apple.com/docs/DOC-8841</a>
  941.             if debug ≥ 2 then hexDumpFormatOne("  adjustURLs: theInputBuffer", theInputBuffer)
  942.            
  943.             -- check for the <a> tag
  944.             if text 1 thru (length of "<a ") of theInputBuffer is "<a " then
  945.                 -- found <a> tag
  946.                 if debug ≥ 2 then log "  adjustURLs: processing <a> tag"
  947.                 -- ASC consider a line-end as a <br> when when firefox considers it a blank
  948.                 -- change a possible line-end before an <a> tag to a " "
  949.                 if debug ≥ 2 then hexDumpFormatOne("  adjustURLs: before lf check buildHTML", buildHtml)
  950.                 if text (length of buildHtml) thru (length of buildHtml) of buildHtml is lf then
  951.                     if debug ≥ 2 then log "  adjustURLs: we need to delete a line-end before the <a> tag"
  952.                     set buildHtml to text 1 thru ((length of buildHtml) - 1) of buildHtml
  953.                     set buildHtml to buildHtml & " "
  954.                     if debug ≥ 2 then hexDumpFormatOne("  adjustURLs: after lf deletion buildHTML", buildHtml)
  955.                 end if
  956.                 -- find ending </a> tag
  957.                 set whereEnds to offset of "</a>" in theInputBuffer
  958.                 if whereEnds ≤ 0 then
  959.                     if debug ≥ 2 then log "  adjustURLs: ==> found an error in the HTML.  no ending </a>"
  960.                     set buildHtml to buildHtml & theInputBuffer
  961.                     printHeader("  adjustURLs: buildHTML", buildHtml)
  962.                     set theInputBuffer to ""
  963.                     display dialog "  adjustURLs: Found an error in the HTML.  No ending </a>.  Will skip." giving up after 10
  964.                     exit repeat -- ------ next ------>
  965.                 end if
  966.                 set lastOffsetLength to ((length of "</a>") - 1)
  967.                 if debug ≥ 2 then log "  adjustURLs: lastOffsetLength is " & lastOffsetLength
  968.                 set lastCharacterOffset to whereEnds + lastOffsetLength
  969.                 if debug ≥ 2 then log "  adjustURLs: lastCharacterOffset is " & getIntegerAndHex(lastCharacterOffset)
  970.                 -- needs to copy the ending ">"
  971.                 set anchorString to text 1 thru lastCharacterOffset of theInputBuffer
  972.                 -- don't let Windoze confuse us. convert Return LineFeed to lf
  973.                 -- Correct absure ASC bug where there is a line-end in the <a> text.
  974.                 if debug ≥ 2 then hexDumpFormatOne("  adjustURLs: before adjusting anchorString", anchorString)
  975.                 set anchorString to alterString(anchorString, lf, " ")
  976.                 if debug ≥ 2 then hexDumpFormatOne("  adjustURLs: anchorString", anchorString)
  977.                 set anchorString to adjustDuplicateAnchorURLs(anchorString, lf, " ")
  978.                 --
  979.                 -- fix up mangled url
  980.                 -- be a nice guy for RW -???-
  981.                 -- Waterfox fixes up!
  982.                 --  
  983.                 set buildHtml to buildHtml & anchorString
  984.                 if debug ≥ 2 then hexDumpFormatOne("  adjustURLs: buildHTML", buildHtml)
  985.                 -- https://apple.stackexchange.com/a/20135/44531
  986.                 -- We want first character of the "next" portion of theInputBuffer so add one
  987.                 set theInputBuffer to text (lastCharacterOffset + 1) thru -1 of theInputBuffer --trim out <a>
  988.                 if debug ≥ 2 then hexDumpFormatOne("  adjustURLs: theInputBuffer", theInputBuffer)
  989.                 -- Web Browsers like Firefox convert a line-end in text to a space.
  990.                 if text 1 thru 1 of theInputBuffer is lf then
  991.                     if (length of theInputBuffer) is 1 then
  992.                         set theInputBuffer to " "
  993.                     else
  994.                         set theInputBuffer to " " & (text 2 thru (length of theInputBuffer) of theInputBuffer)
  995.                         if debug ≥ 2 then hexDumpFormatOne("  adjustURLs: after lf deletion; theInputBuffer", theInputBuffer)
  996.                     end if
  997.                 end if
  998.                 exit repeat -- ------ next ------>
  999.             end if
  1000.            
  1001.             -- skip img tag which may contian a http or https.
  1002.             if text 1 thru (length of "<img") of theInputBuffer is "<img" then
  1003.                 -- found <img> tag
  1004.                 if debug ≥ 2 then log "  adjustURLs: processing <img> tag"
  1005.                 set {buildHtml, theInputBuffer} to skipTag(buildHtml, theInputBuffer, ">")
  1006.                 exit repeat -- ------ next ------>
  1007.             end if
  1008.            
  1009.             set {theURL, theInputBuffer} to urlEndsWHere(theInputBuffer)
  1010.            
  1011.             if debug ≥ 2 then printHeader("  adjustURLs: printHeader", theInputBuffer)
  1012.            
  1013.             set actualTagData to getTitle(theURL)
  1014.            
  1015.             -- fyi: The string " _blank" in the <a> oOpens the linked document in a new window or tab.
  1016.             set assembled to "<a href=\"" & theURL & "\" target=\"_blank\">" & actualTagData & "</a>"
  1017.             if debug ≥ 2 then log "  adjustURLs: assembled  is " & assembled
  1018.            
  1019.             if (length of theInputBuffer)0 then
  1020.                 -- We have reached the end of the input
  1021.                 if debug ≥ 2 then log "  adjustURLs: we have reached the end of the input."
  1022.                 set buildHtml to buildHtml & assembled
  1023.             else
  1024.                 if debug ≥ 2 then log "  adjustURLs: more input to process"
  1025.                 set buildHtml to buildHtml & assembled
  1026.             end if
  1027.            
  1028.             -- wrap up
  1029.             --log "transformed text from buildHTML is  " & return & buildHTML
  1030.             if debug ≥ 2 then log "  adjustURLs: #" & countI & " transformed text from buildHTML is  " & return & buildHtml
  1031.             -- number of links found
  1032.             set countI to countI + 1
  1033.            
  1034.         end repeat -- used to interate
  1035.     end repeat -- processing links in the input text
  1036.     if alteredBuffer is true then
  1037.         -- chop off the lf we added above.
  1038.         set buildHtml to text 1 thru ((length of buildHtml) - 1) of buildHtml
  1039.         set alteredBuffer to false -- somewhat redundant
  1040.     end if
  1041.     if debug ≥ 4 then log "bye from  -.- adjustURLs -.-"
  1042.     return the buildHtml
  1043.    
  1044. end adjustURLs
  1045.  
  1046. -- ------------------------------------------------------
  1047. (*
  1048. alterString
  1049.   thisText is the input string to change
  1050.   delim is what string to change.  It doesn't have to be a single character.
  1051.  replacement is the new string
  1052.  
  1053.  returns the changed string.
  1054. *)
  1055.  
  1056. on alterString(thisText, delim, replacement)
  1057.     global debug
  1058.     if debug ≥ 5 then log "in ~~~ alterString ~~~"
  1059.     set resultList to {}
  1060.     set {tid, my text item delimiters} to {my text item delimiters, delim}
  1061.     try
  1062.         set resultList to every text item of thisText
  1063.         set text item delimiters to replacement
  1064.         set resultString to resultList as string
  1065.         set my text item delimiters to tid
  1066.     on error
  1067.         set my text item delimiters to tid
  1068.     end try
  1069.     return resultString
  1070. end alterString
  1071.  
  1072. -- ------------------------------------------------------
  1073. (*
  1074.  Return the text to the right of theToken.
  1075. *)
  1076. on answerAndChomp(theString, theToken)
  1077.     global debug
  1078.     if debug ≥ 5 then log "in ~~~ answerAndChomp ~~~"
  1079.     set theOffset to offset of theToken in theString
  1080.     if debug ≥ 7 then log "theOffset is " & theOffset
  1081.     set theLength to length of theString
  1082.     if theOffset > 0 then
  1083.         set beginningPart to text 1 thru (theOffset - 1) of theString
  1084.         if debug ≥ 7 then log "beginningPart is " & beginningPart
  1085.        
  1086.         set chompped to text theOffset thru theLength of theString
  1087.         if debug ≥ 7 then log "chompped is " & chompped
  1088.         return {chompped, beginningPart}
  1089.     else
  1090.         set beginningPart to ""
  1091.         return {theString, beginningPart}
  1092.     end if
  1093.    
  1094. end answerAndChomp
  1095.  
  1096. -- ------------------------------------------------------
  1097. (*
  1098.  Delete the leading part of the string until and including theToken.
  1099. *)
  1100. on chompLeftAndTag(theString, theToken)
  1101.     global debug
  1102.     if debug ≥ 5 then log "in --- chompLeftAndTag ---"
  1103.     if debug ≥ 7 then
  1104.         log "chompLeftAndTag: theToken is " & theToken
  1105.         hexDumpFormatOne("chompLeftAndTag: theString", theString)
  1106.     end if
  1107.     set theOffset to offset of theToken in theString
  1108.     if debug ≥ 7 then log "chompLeftAndTag: theOffset is " & theOffset & " in hex is " & integerToHex(theOffset)
  1109.     set theLength to length of theString
  1110.     if debug ≥ 7 then log "chompLeftAndTag: theLength is " & theLength & " in hex is " & integerToHex(theLength)
  1111.    
  1112.     if theOffset > 0 then
  1113.         -- Do we have any more of the string to return?
  1114.         if (theOffset + (length of theToken)) ≤ length of theString then
  1115.             set chompped to text (theOffset + (length of theToken)) thru theLength of theString
  1116.         else
  1117.             set chompped to ""
  1118.         end if
  1119.         if debug ≥ 7 then log "chompLeftAndTag: length of chompped is " & integerToHex(length of chompped) & "; chompped is " & chompped
  1120.         return chompped
  1121.     else
  1122.         return ""
  1123.     end if
  1124. end chompLeftAndTag
  1125.  
  1126. -- ------------------------------------------------------
  1127. on convertToHTML(theData)
  1128.     global debug
  1129.     if debug ≥ 3 then log "in --- convertToHTML ---" & return & "  Try to send back HTML. the processed data in variable theData is " & theData
  1130.     try
  1131.         set clipboardDataQuoted to quoted form of theData
  1132.        
  1133.         if debug ≥ 1 then
  1134.             log "  convertToHTMLz: .... data soon to be returned ...." & return & "clipboardDataQuoted is " & return & clipboardDataQuoted
  1135.             hexDumpFormatOne("clipboardDataQuoted", clipboardDataQuoted)
  1136.         end if
  1137.         -- make hex string as required for HTML data on the clipboard
  1138.         set toUnix to "/bin/echo -n " & clipboardDataQuoted & " | hexdump -ve '1/1 \"%.2x\"'"
  1139.         if debug ≥ 5 then printHeader("  convertToHTMLz: toUnix to convert to hex", toUnix)
  1140.         set fromUnix to do shell script toUnix
  1141.        
  1142.         if debug ≥ 5 then printHeader("  convertToHTMLz: fromUnix", fromUnix)
  1143.        
  1144.         if debug ≥ 5 then
  1145.             log "  convertToHTMLz: displaying original string -- so we can tell if it converted successfully. "
  1146.             --hexDumpFormatOne("fromUnix", fromUnix)
  1147.         end if
  1148.     on error errMsg number n
  1149.         log "  convertToHTMLz: ==> convert to hex string failed. " & errMsg & " with number " & n
  1150.         set fromUnix to ""
  1151.     end try
  1152.     if debug ≥ 4 then log "bye from  -.- convertToHTML -.-"
  1153.     return fromUnix
  1154. end convertToHTML
  1155.  
  1156. -- ------------------------------------------------------  
  1157. (*
  1158. Yvan Koenig
  1159. https://macscripter.net/viewtopic.php?id=43133
  1160. *)
  1161. on findExtension(inputFileName)
  1162.     global debug
  1163.     if debug ≥ 5 then log "in ~~~ findExtension ~~~"
  1164.     set fileName to inputFileName as string
  1165.     set saveTID to AppleScript's text item delimiters
  1166.     set AppleScript's text item delimiters to {"."}
  1167.     set theExt to last text item of fileName
  1168.     set AppleScript's text item delimiters to saveTID
  1169.     --log "theExt is " & theExt
  1170.     if theExt ends with ":" then set theExt to text 1 thru -2 of theExt
  1171.     if debug ≥ 5 then log "theExt is " & theExt
  1172.     return theExt
  1173. end findExtension
  1174.  
  1175. -- ------------------------------------------------------
  1176. (*
  1177. length of inputLfBuffer & " in hex " & integerToHex(length of inputLfBuffer)
  1178. *)
  1179. on getIntegerAndHex(aNumber)
  1180.     global debug
  1181.     if debug ≥ 5 then log "in ~~~ getIntegerAndHex ~~~"
  1182.    
  1183.     return aNumber & " in Hex " & integerToHex(aNumber)
  1184. end getIntegerAndHex
  1185.  
  1186. -- ------------------------------------------------------
  1187. (*
  1188.  find the html title in the given web page.
  1189.  
  1190.  retrieve the file pointed to by the URL so we can
  1191.             get the title. Note: <title> can have attributes.  Example:
  1192.                
  1193.             <title data-test-page-title="Parallels Desktop Lite on the Mac App Store"
  1194.             >‎Parallels Desktop Lite on the Mac App Store</title>
  1195.  
  1196. *)
  1197. on getTitle(theURL)
  1198.     global debug
  1199.     global droppedFileName
  1200.     set lf to character id 10
  1201.    
  1202.     if debug ≥ 5 then log "in ~~~ getTitle ~~~"
  1203.     if debug ≥ 1 then log "  getTitle: ----------------------- " & theURL & " -----------------------"
  1204.     if (text 1 thru (length of "http:") of theURL is "http:") or (text 1 thru (length of "https:") of theURL is "https:") then
  1205.         -- found url we can process
  1206.         if debug ≥ 5 then log "getTitle: We can process this URL since it begins with http or https." & return & "  " & theURL
  1207.     else
  1208.         log "==> getTitle: we cannot process this url " & theURL & return & "  we will return what we received."
  1209.         return theURL --------------------------------->
  1210.     end if
  1211.    
  1212.     -- Example:
  1213.     -- curl --silent --location --max-time 10 <URL>
  1214.     set toUnix to "curl --silent --location --max-time 10 " & quoted form of theURL
  1215.     if debug ≥ 2 then log "  getTitle: what we will use to retrieve the Url. toUnix  is " & return & "  " & toUnix
  1216.     try
  1217.         if debug ≥ 2 then log "  getTitle: reading link file to get title"
  1218.         set fromUnix to do shell script toUnix
  1219.         -- enough data returned to have a title in it?
  1220.         if debug ≥ 2 then
  1221.             log "  getTitle: (length of fromUnix)  is " & (length of fromUnix)
  1222.            
  1223.             log "  getTitle: length of  (\"<title" & "</title>\")) is " & (length of ("<title" & "</title>"))
  1224.         end if
  1225.         if (length of fromUnix) < (length of ("<title" & "</title>")) then
  1226.             log "==> getTitle: site didn't return any data " & theURL & return & "  we will return what ee received."
  1227.             return theURL --------------------------------->
  1228.         end if
  1229.         if debug ≥ 2 then
  1230.             printHeader("  getTitle: fromUnix", fromUnix)
  1231.             -- may not be working with an HTLM document, so thefound title may be too long or confused.
  1232.             log "  getTitle: how far?..."
  1233.         end if
  1234.         -- there could be some bagage with the <title
  1235.         set actualTagData to tagContent(fromUnix, "<title", "</title>")
  1236.         -- Find what we will actually display in the title.
  1237.         -- Fix up gotchas.             
  1238.         if debug ≥ 2 then
  1239.             log "  getTitle: actualTagData  is ->" & actualTagData & "<-"
  1240.             hexDumpFormatOne("  getTitle: actualTagData (title)", actualTagData)
  1241.         end if
  1242.        
  1243.         if actualTagData is "" then
  1244.             set actualTagData to theURL
  1245.         else if length of actualTagData > 140 then
  1246.             if debug ≥ 2 then log "  getTitle: length of actualTagData is " & length of actualTagData & "which is too long.  Truncated."
  1247.             set actualTagData to theURL
  1248.             -- curl https://appleid.apple.com returns <title>403 Forbidden</title>
  1249.             -- which is misleading.
  1250.             -- will be extraneous characters in the title now since we haven't yet filtered them out.
  1251.         else if actualTagData contains "403" and actualTagData contains "Forbidden" then
  1252.             if debug ≥ 2 then log "  getTitle:  found 403 web page."
  1253.             set actualTagData to theURL
  1254.             -- <title>Sign In - Apple</title>
  1255.             -- got a post from the lounge.
  1256.         else if actualTagData contains "Sign In - Apple" then
  1257.             if debug ≥ 2 then log "  getTitle:  got 'Sign In - Apple' from a lounge page."
  1258.             set actualTagData to theURL
  1259.         else
  1260.             -- there could be some attributes within the <title> tag.
  1261.             -- or there could not be
  1262.             -- could an attribute have a > in it? doubtful. should be escaped.
  1263.             try
  1264.                 if debug ≥ 2 then log "  getTitle: looks like a normalist title."
  1265.                 -- find where <title ends
  1266.                 set whereToEnd to (offset of ">" in actualTagData)
  1267.                 if debug ≥ 2 then log "  getTitle: whereToEnd is " & whereToEnd
  1268.                 set whereToBegin to whereToEnd + (length of ">")
  1269.                 if debug ≥ 2 then
  1270.                     log "  getTitle: whereToBegin is " & whereToBegin
  1271.                     hexDumpFormatOne("  getTitle: actualTagData", actualTagData)
  1272.                 end if
  1273.                 set actualTagData to text whereToBegin thru (length of actualTagData) of actualTagData
  1274.                 if debug ≥ 2 then log "  getTitle: actualTagData is " & actualTagData
  1275.             on error theErrorMessage number theErrorNumber
  1276.                 log "  getTitle: ==>No ending greater than (>) for title. Badly contructed html." & return & "message is " & theErrorMessage & "error number " & theErrorNumber
  1277.                 set actualTagData to actualTagData
  1278.                 -- no need to repair.  It's not our page.
  1279.             end try
  1280.            
  1281.             -- found line-end in title.  caused confustion.
  1282.             -- note: this is new data and the multiple line-ends have not been
  1283.             -- filtered out.
  1284.             -- some joker had a line-end in the title!
  1285.             if debug ≥ 3 then
  1286.                 log "  getTitle: actualTagData (title) has been chanaged which is  " & actualTagData
  1287.                 hexDumpFormatOne("  getTitle: actualTagData (title)", actualTagData)
  1288.             end if
  1289.             set actualTagData to alterString(actualTagData, return & lf, lf)
  1290.             set actualTagData to alterString(actualTagData, return, lf)
  1291.             set actualTagData to adjustLF(actualTagData)
  1292.             if debug ≥ 2 then
  1293.                 log "  getTitle: actualTagData (title) has been chanaged which is  " & actualTagData
  1294.                 hexDumpFormatOne("  getTitle: actualTagData (title)", actualTagData)
  1295.             end if
  1296.            
  1297.         end if
  1298.     on error errMsg number n
  1299.         display dialog "  getTitle: ==> Error occured when looking for title. " & errMsg & " with number " & n & return & "  " & droppedFileName & return & "  " & theURL giving up after 10
  1300.         log "  getTitle: ==> Error occured when looking for title. " & errMsg & " with number " & n
  1301.         set actualTagData to theURL
  1302.     end try
  1303.     return actualTagData
  1304. end getTitle
  1305. -- ------------------------------------------------------
  1306. (*
  1307.  http://krypted.com/mac-os-x/to-hex-and-back/
  1308.               0    2    4    6    8    a    c    e     0 2 4 6 8 a c e
  1309. 0000000:   3c 703e 5369 6d70 6c65 2070 7574 2c20   <p>Simple put,
  1310.            *)
  1311. on hexDumpFormatOne(textMessage, hex)
  1312.     global debug
  1313.    
  1314.     set aNul to character id 1
  1315.    
  1316.     if debug ≥ 7 then log "in ~~~ hexDumpFormatOne ~~~"
  1317.     if debug ≥ 8 then log "    hexDumpFormatOne: input string is " & return & hex
  1318.    
  1319.     -- -r -p
  1320.     set displayValue to aNul & hex
  1321.     set toUnix to "/bin/echo -n " & (quoted form of displayValue) & " | xxd  "
  1322.     if debug ≥ 8 then log "    hexDumpFormatOne: toUnix is " & toUnix
  1323.    
  1324.     try
  1325.         set fromUnix to do shell script toUnix
  1326.        
  1327.         -- two hex digits
  1328.         set displayText to replaceCharacter(fromUnix, 10, "  ")
  1329.         if debug ≥ 8 then
  1330.             log "    hexDumpFormatOne: " & return & displayText
  1331.             log "    hexDumpFormatOne: length of displayText is " & length of displayText
  1332.         end if
  1333.         -- one character
  1334.         set displayText to replaceCharacter(displayText, 51, " ")
  1335.         if debug ≥ 8 then
  1336.             log "    hexDumpFormatOne: " & return & displayText
  1337.             log "    hexDumpFormatOne: almost there ..... length of displayText is " & length of displayText
  1338.         end if
  1339.         log "variable " & textMessage & " in hex is " & return & "         0    2    4    6    8    a    c    e     0 2 4 6 8 a c e" & return & displayText
  1340.     on error errMsg number n
  1341.         log "    hexDumpFormatOne: ==> convert hex string to string failed. " & errMsg & " with number " & n
  1342.     end try
  1343.     if debug ≥ 8 then
  1344.         log "leaving ~.~ hexDumpFormatOne ~.~"
  1345.     end if
  1346. end hexDumpFormatOne
  1347.  
  1348. -- ------------------------------------------------------
  1349. on hexDumpFormatZero(textMessage, hex)
  1350.     global debug
  1351.     if debug ≥ 7 then log "in ~~~ hexDumpFormatZero ~~~"
  1352.     if debug ≥ 8 then log "input string is " & hex
  1353.     -- -r -p
  1354.     set toUnix to "/bin/echo -n " & (quoted form of hex) & " | xxd  "
  1355.     if debug ≥ 8 then log "toUnix is " & toUnix
  1356.     try
  1357.         set displayText to do shell script toUnix
  1358.        
  1359.         log "variable " & textMessage & " in hex is " & return & "         0    2    4    6    8    a    c    e     0 2 4 6 8 a c e" & return & displayText
  1360.     on error errMsg number n
  1361.         log "==> convert hex string to string failed. " & errMsg & " with number " & n
  1362.     end try
  1363. end hexDumpFormatZero
  1364.  
  1365. -- ------------------------------------------------------
  1366. (*
  1367. https://macscripter.net/viewtopic.php?id=43713
  1368.  *)
  1369. on integerToHex(nDec)
  1370.     global debug
  1371.     if debug ≥ 5 then log "in ~~~ integerToHex ~~~"
  1372.     try
  1373.         set nHex to do shell script "perl -e 'printf(\"%X\", " & nDec & ")'" --> "F0"
  1374.     on error errMsg number n
  1375.         log "==> convert integer to hex. " & errMsg & " with number " & n
  1376.         set nHex to ""
  1377.     end try
  1378.     return nHex
  1379. end integerToHex
  1380.  
  1381. -- ------------------------------------------------------
  1382. (*
  1383.  
  1384. https://stackoverflow.com/questions/55838252/minimum-value-that-not-zero
  1385.       set m to get minimumPositiveNumber from {10, 2, 0, 2, 4}
  1386.     log "m is " & m
  1387.     set m to minimumPositiveNumber from {0, 0, 0}
  1388.     log "m is " & m
  1389. *)
  1390. on minimumPositiveNumber from L
  1391.     global debug
  1392.     if debug ≥ 5 then log "in ~~~ minimumPositiveNumber ~~~"
  1393.     local L
  1394.    
  1395.     if L = {} then return null
  1396.    
  1397.     set |ξ| to 0
  1398.    
  1399.     repeat with x in L
  1400.         set x to x's contents
  1401.         if (x < |ξ| and x ≠ 0) ¬
  1402.             or |ξ| = 0 then ¬
  1403.             set |ξ| to x
  1404.     end repeat
  1405.    
  1406.     |ξ|
  1407. end minimumPositiveNumber
  1408.  
  1409. -- ------------------------------------------------------
  1410. (*
  1411.  makeCaseUpper("Now is the time, perhaps, for all good men")
  1412. *)
  1413. on makeCaseUpper(theString)
  1414.     global debug
  1415.     if debug ≥ 5 then log "in ~~~ makeCaseUpper ~~~"
  1416.     set UC to "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  1417.     set LC to "abcdefghijklmnopqrstuvwxyz"
  1418.     set C to characters of theString
  1419.     repeat with ch in C
  1420.         if ch is in LC then set contents of ch to item (offset of ch in LC) of UC
  1421.     end repeat
  1422.     return C as string
  1423. end makeCaseUpper
  1424.  
  1425. -- ------------------------------------------------------
  1426. on postToCLipboard(pleasePost)
  1427.     global debug
  1428.     if debug ≥ 5 then log "in ~~~ postToCLipboard ~~~"
  1429.     try
  1430.         -- osascript -e "set the clipboard to «data HTML${hex}»"     
  1431.         set toUnixSet to "osascript -e \"set the clipboard to «data HTML" & pleasePost & \""
  1432.         if debug ≥ 5 then log "  postToCLipboard: toUnixSet is " & printHeader("toUnixSet", toUnixSet)
  1433.        
  1434.         set fromUnixSet to do shell script toUnixSet
  1435.         if debug ≥ 5 then log "  postToCLipboard: fromUnixSet is " & fromUnixSet
  1436.        
  1437.     on error errMsg number n
  1438.         log "  postToCLipboard: ==> We tried to send back HTML data, but failed. " & errMsg & " with number " & n
  1439.     end try
  1440.     -- see what ended up on the clipboard
  1441.     set theList2 to clipboard info
  1442.     if debug ≥ 2 then printClipboardInfo(theList2)
  1443. end postToCLipboard
  1444.  
  1445. -- ------------------------------------------------------
  1446. on printClipboardInfo(theList)
  1447.     global debug
  1448.     if debug ≥ 5 then log "in ~~~ printClipboardInfo ~~~"
  1449.     log (clipboard info)
  1450.     log class of theList
  1451.     log "Data types on the clipboard ... "
  1452.     printList("", theList)
  1453.     log "... "
  1454. end printClipboardInfo
  1455.  
  1456. -- ------------------------------------------------------
  1457. (* Pump out the beginning of theString *)
  1458. on printHeader(theName, theString)
  1459.     global debug
  1460.     if debug ≥ 7 then
  1461.         log "in ~~~ printHeader ~~~"
  1462.         log "  printHeader: the input string for titling  is " & theName
  1463.         -- let's not culter the log
  1464.         log "  printHeader: length of the string to print is " & length of theString
  1465.     end if
  1466.     if length of theString ≤ 0 then
  1467.         log "==> no string to print"
  1468.     else
  1469.         log theName & " is " & return & text 1 thru (minimumPositiveNumber from {400, length of theString}) of theString & "<+++++++++"
  1470.     end if
  1471. end printHeader
  1472.  
  1473.  
  1474. -- ------------------------------------------------------
  1475. (*
  1476. print out the items in a list
  1477.  
  1478. *)
  1479.  
  1480. on printList(theName, splits)
  1481.     global debug
  1482.     if debug ≥ 5 then log "in ~~~ printList ~~~"
  1483.     try
  1484.         set theCount to 1
  1485.         repeat with theEntry in splits
  1486.             if debug ≥ 7 then log "printList: class of theEntry is " & class of theEntry
  1487.             set classDisplay to class of theEntry as text
  1488.             if debug ≥ 7 then "printList: classDisplay is " & classDisplay as text
  1489.             if debug ≥ 7 then log "printList: class of classDisplay is " & class of classDisplay
  1490.             if classDisplay is "list" then
  1491.                 log "    " & theName & " # " & theCount & " is " & item 1 of theEntry & "; " & item 2 of theEntry
  1492.             else
  1493.                 log "    " & theName & " # " & theCount & " is " & theEntry
  1494.             end if
  1495.             set theCount to theCount + 1
  1496.         end repeat
  1497.     on error errMsg number n
  1498.         log "printList: ==> No go in printList. " & errMsg & " with number " & n
  1499.     end try
  1500. end printList
  1501.  
  1502. -- ------------------------------------------------------
  1503. (*
  1504. StefanK in https://macscripter.net/viewtopic.php?id=43852
  1505. Replaces one or more characters based on the length of theCharacter.
  1506.  
  1507.  Big Warning!!!
  1508.  ==============
  1509.    This on block is called by hexDumpFormatOne().  
  1510.    Therefor, you may not call hexDumpFormatOne() from this on block.
  1511.     If you so so, you get yourself into an endless loop.
  1512.     Use hexDumpFormatZero() instead.
  1513.    
  1514.     script -k <output file name>
  1515.     osascript /Applications/applescriptFiles/workwithclipboardV13-HTML.app
  1516.     use Activity Monito to stop osascript
  1517.    
  1518. *)
  1519.  
  1520. on replaceCharacter(theText, theOffset, theCharacter)
  1521.     global debug
  1522.     if debug ≥ 7 then log "in ~~~ replaceCharacter ~~~"
  1523.     if debug ≥ 7 then
  1524.         log "  theOffset is " & getIntegerAndHex(theOffset) & " with theCharacter >" & theCharacter & "<  length of theText is " & getIntegerAndHex(length of theText)
  1525.         log "theText is " & theText
  1526.     end if
  1527.    
  1528.     set theOutput to theText -- ready to return if need be.
  1529.     repeat 1 times
  1530.         -- sanity checks
  1531.         if theOffset ≤ 0 then
  1532.             display dialog "No character to replace at " & theOffset & " with character " & theCharacter & " in " & theText giving up after 10
  1533.             log "==> Adjust theOffset to be wihin the string."
  1534.             exit repeat -------------- return ---------->                  
  1535.         end if
  1536.         if (theOffset - (length of theCharacter)) ≤ 0 then
  1537.             display dialog "Too near the front of the buffer.  " & theOffset & " with character " & theCharacter & " in " & theText giving up after 10
  1538.             log "==> Too near the front of the buffer. "
  1539.             exit repeat -------------- return ---------->
  1540.         end if
  1541.         if (theOffset + (length of theCharacter) - 1) > (length of theText) then
  1542.             display dialog "To near the end of the buffer. " & theOffset & " with character " & theCharacter & " in " & theText giving up after 10
  1543.             log "==> Too near the end of the buffer. "
  1544.             log "  " & "theOffset is " & theOffset & " with theCharacter >" & theCharacter & "<  in " & theText
  1545.             log "length of buffer is " & getIntegerAndHex(length of theText)
  1546.             exit repeat -------------- return ---------->                  
  1547.         end if
  1548.        
  1549.         if debug ≥ 7 then
  1550.             log "theOffset is " & getIntegerAndHex(theOffset)
  1551.             log "theCharacter is " & theCharacter
  1552.         end if
  1553.        
  1554.         try
  1555.             -- what if we are at the end of the buffer.  We cannot get any remainder text.
  1556.             if theOffset ≥ (length of theText) then
  1557.                 set theOutput to (text 1 thru (theOffset - 1) of theText) & theCharacter
  1558.             else
  1559.                 set theOutput to (text 1 thru (theOffset - 1) of theText) & theCharacter & (text (theOffset + (length of theCharacter)) thru -1 of theText)
  1560.             end if
  1561.         on error errMsg number n
  1562.             log "==> No go. " & errMsg & " with number " & n
  1563.             exit repeat -------------- return ---------->
  1564.         end try
  1565.     end repeat
  1566.     return theOutput
  1567. end replaceCharacter
  1568.  
  1569. -- ------------------------------------------------------
  1570. (*
  1571.   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
  1572.  
  1573.  DOCTYPE contains a http link, but it's not something we want to mess with.
  1574.   Tip: The <!DOCTYPE> declaration is NOT case sensitive.
  1575.   https://www.w3schools.com/tags/tag_doctype.asp
  1576.  
  1577.   best do the parsing maually, since we will not know the casing of DOCTYPE.
  1578.   fyi: An HTML comment begins with <!–– and the comment closes with ––> .
  1579.  
  1580.  *)
  1581.  
  1582. on skipDoctype(buildHtml, theInputBuffer)
  1583.     global debug
  1584.     if debug ≥ 5 then log "in --- skipDoctype ---"
  1585.     set ourOutput to buildHtml
  1586.     set ourInput to theInputBuffer
  1587.    
  1588.     set splitDoctype to splitTextToList(ourInput, "<!")
  1589.     if (count of splitDoctype)1 then
  1590.         if debug ≥ 4 then log "skipDoctype: <! hence DOCTYPE not found."
  1591.         return {buildHtml, theInputBuffer} ------------------ <! not found -------------------->
  1592.     end if
  1593.    
  1594.     set firstWordOffset to offset of " " in (item 2 of splitDoctype)
  1595.     -- ditch trailing blank.
  1596.     set firstWordOffset to firstWordOffset - 1
  1597.     if firstWordOffset ≤ 0 then
  1598.         if debug ≥ 4 then log "skipDoctype: DOCTYPE not found."
  1599.         return {buildHtml, theInputBuffer} ------------------ <! not found -------------------->
  1600.     end if
  1601.     -- it was simple to get the header stuff at least
  1602.     set ourOutput to ourOutput & item 1 of splitDoctype
  1603.    
  1604.     set firstWord to makeCaseUpper(text 1 thru firstWordOffset of (item 2 of splitDoctype))
  1605.     if debug ≥ 4 then log "skipDoctype: firstWord is " & firstWord & "  length  of firstWord is " & length of firstWord & "  class of firstWord is " & class of firstWord
  1606.    
  1607.     if firstWord is "<!DOCTYPE" then
  1608.         -- skip over DOCTYPE tag.      
  1609.         set endOfDoctypeOffset to offset of ">" in (item 2 of splitDoctype)
  1610.         if endOfDoctypeOffset ≤ 0 then
  1611.             if debug ≥ 5 then log "skipDoctype: Closing " > " not found with DOCTYPE."
  1612.             return {buildHtml, theInputBuffer} ------------------ ">" not found ---------------->
  1613.         end if
  1614.        
  1615.         -- looks good. proceed.
  1616.         set ourOutput to ourOutput & text 1 thru endOfDoctypeOffset of (item 2 of splitDoctype)
  1617.         set ourInput to text ((length of (item 1 of splitDoctype)) + endOfDoctypeOffset + 1) thru -1 of theInputBuffer
  1618.        
  1619.     else
  1620.         if debug ≥ 4 then log "skipDoctype: DOCTYPE not found as first word."
  1621.         return {buildHtml, theInputBuffer} ---------- DOCTYPE not found ---------->
  1622.     end if
  1623.    
  1624.     if debug ≥ 4 then log "skipDoctype:" & return & "ourOutput, is " & ourOutput & return & "ourInput, is " & ourInput
  1625.    
  1626.     return {ourOutput, ourInput}
  1627. end skipDoctype
  1628.  
  1629. -- ------------------------------------------------------
  1630.  
  1631. on skipTag(buildHtml, theInputBuffer, endDelim)
  1632.     global debug
  1633.    
  1634.     if debug ≥ 5 then log "in --- skipTag ---"
  1635.     set theOutput to buildHtml
  1636.     set theInput to theInputBuffer
  1637.     if debug ≥ 4 then
  1638.         log "skipTag: length of theOutput is " & (length of theOutput) & " length of theInput is " & (length of theInput)
  1639.         log "skipTag: endDelim is ->" & endDelim & "<-"
  1640.     end if
  1641.    
  1642.     set endOfTagOffset to offset of endDelim in theInput
  1643.     -- did we find the end tag?
  1644.     if endOfTagOffset ≤ 0 then
  1645.         try
  1646.             display dialog "skipTag: tag not balanced. beginning tag is" & text 1 thru 4 of theInput & " ending tag is " & endDelim giving up after 10
  1647.             log "skipTag: ==> tag not balanced. beginning tag is" & text 1 thru 4 of theInput & " ending tag is " & endDelim
  1648.         on error errMsg number n
  1649.             log "skipTag: ==> tag not balanced." & errMsg & " with number " & n
  1650.             display dialog "skipTag: tag not balanced." giving up after 10
  1651.         end try
  1652.         -- no end tag, so consider the rest as consumed
  1653.         set theOutput to ourOutput & theInput
  1654.         set theInput to ""
  1655.         return {theOutput, theInput} -- ------------------------------------------->       
  1656.     end if
  1657.    
  1658.     -- looks good. proceed.
  1659.     set theOutput to theOutput & text 1 thru endOfTagOffset of theInput
  1660.     if endOfTagOffset < (length of theInput) then
  1661.         -- loob off tag
  1662.         set theInput to text (endOfTagOffset + 1) thru -1 of theInput
  1663.     else
  1664.         set theInput to ""
  1665.     end if
  1666.    
  1667.     if debug ≥ 4 then
  1668.         log "skipTag: length of theOutput is " & (length of theOutput) & " length of theInput is " & (length of theInput)
  1669.         printHeader("skipTag: theOutput", theOutput)
  1670.         printHeader("skipTag: theInput", theInput)
  1671.     end if
  1672.    
  1673.     return {theOutput, theInput}
  1674. end skipTag
  1675.  
  1676. -- ------------------------------------------------------
  1677. (*
  1678. splitTextToList seems to be what you are trying to do
  1679.   thisText is the input string
  1680.   delim is what to split on
  1681.  
  1682.   results returned in a list
  1683.  
  1684.   Total hack. We know splitTextToList strips of delim so add it back.
  1685. *)
  1686.  
  1687. on splitTextToList(thisText, delim)
  1688.     global debug
  1689.     if debug ≥ 5 then log "in ~~~ splitTextToList ~~~"
  1690.    
  1691.     set returnedList to textToList(thisText, delim)
  1692.     set resultArray to {}
  1693.     copy item 1 of returnedList to the end of the resultArray
  1694.    
  1695.     repeat with i from 2 to (count of returnedList) in returnedList
  1696.         set newElement to delim & item i of returnedList
  1697.         copy newElement to the end of the resultArray
  1698.     end repeat
  1699.    
  1700.     return resultArray
  1701. end splitTextToList
  1702.  
  1703. -- ------------------------------------------------------
  1704. (*
  1705.   Retrieved data between "begin" and "end" tag. Whatever is between the strings.
  1706. *)
  1707. on tagContent(theString, startTag, endTag)
  1708.     global debug
  1709.     if debug ≥ 5 then log "in ~~~ tagContent ~~~"
  1710.     try
  1711.         if debug ≥ 5 then log "tagContent:  " & return & "    startTag is ->" & startTag & "<- endTag is ->" & endTag & "<-"
  1712.         set beginningOfTag to chompLeftAndTag(theString, startTag)
  1713.         if length of beginningOfTag ≤ 0 then
  1714.             set middleText to ""
  1715.         else
  1716.             if debug ≥ 5 then printHeader("tabContent: beginningOfTag", beginningOfTag)
  1717.             set endingOffset to (offset of endTag in beginningOfTag)
  1718.            
  1719.             if endingOffset ≤ (length of endTag) then
  1720.                 set middleText to ""
  1721.             else
  1722.                 set middleText to text 1 thru (endingOffset - 1) of beginningOfTag
  1723.                 if debug ≥ 5 then printHeader("tabContent: middleText", middleText)
  1724.             end if
  1725.         end if
  1726.     on error errMsg number n
  1727.         log "tagContent: ==> finding contained text failed. " & errMsg & " with number " & n
  1728.         set middleText to ""
  1729.     end try
  1730.     if debug ≥ 5 then log "tagContent: returning with middleText is " & middleText
  1731.     return middleText
  1732. end tagContent
  1733. -- ------------------------------------------------------
  1734. (*
  1735. textToList seems to be what you are trying to do
  1736.   thisText is the input string
  1737.   delim is what to split on
  1738.  
  1739.   returns a list of strings.  
  1740.  
  1741. - textToList was found here:
  1742. - http://macscripter.net/viewtopic.php?id=15423
  1743.  
  1744. *)
  1745.  
  1746. on textToList(thisText, delim)
  1747.     global debug
  1748.     if debug ≥ 5 then log "in ~~~ textToList ~~~"
  1749.     set resultList to {}
  1750.     set {tid, my text item delimiters} to {my text item delimiters, delim}
  1751.    
  1752.     try
  1753.         set resultList to every text item of thisText
  1754.         set my text item delimiters to tid
  1755.     on error
  1756.         set my text item delimiters to tid
  1757.     end try
  1758.     return resultList
  1759. end textToList
  1760.  
  1761. -- ------------------------------------------------------
  1762.  
  1763. on trimCharacters(inputTrim, outputTrim, reduce)
  1764.     global debug
  1765.     if debug ≥ 5 then log "in ~~~ trimCharacters ~~~"
  1766.     if debug ≥ 6 then
  1767.         log "  trimCharacters: length of inputTrim is" & getIntegerAndHex(length of inputTrim)
  1768.         hexDumpFormatOne("  trimCharacters: inputTrim", inputTrim)
  1769.         log "  trimCharacters: length of outputTrim is " & getIntegerAndHex(length of outputTrim)
  1770.         hexDumpFormatOne("  trimCharacters: outputTrim", outputTrim)
  1771.         log "  trimCharacters: with reduce >" & reduce & "<  "
  1772.     end if
  1773.     set repCount to 1
  1774.    
  1775.     repeat while length of inputTrim ≥ 1 and text 1 thru 1 of inputTrim is " "
  1776.         set {inputTrim, outputTrim} to trimOneChar(inputTrim, outputTrim, 1, "")
  1777.         if debug ≥ 6 then
  1778.             log "  trimCharacters: repCount is " & repCount
  1779.             set repCount to repCount + 1
  1780.             log "  trimCharacters: length of inputTrim is" & getIntegerAndHex(length of inputTrim)
  1781.             hexDumpFormatOne("  trimCharacters: cycling inputTrim", inputTrim)
  1782.             log "  trimCharacters: length of outputTrim is " & getIntegerAndHex(length of outputTrim)
  1783.             hexDumpFormatOne("  trimCharacters: cycling outputTrim", outputTrim)
  1784.         end if
  1785.     end repeat
  1786.    
  1787.     if debug ≥ 6 then
  1788.         log "  trimCharacters: length of inputTrim is" & getIntegerAndHex(length of inputTrim)
  1789.         hexDumpFormatOne("  trimCharacters: completed inputTrim", inputTrim)
  1790.         log "  trimCharacters: length of outputTrim is " & getIntegerAndHex(length of outputTrim)
  1791.         hexDumpFormatOne("  trimCharacters: completed outputTrim", outputTrim)
  1792.         log "bye from  ~.~ trimCharacters ~.~"
  1793.     end if
  1794.     return {inputTrim, outputTrim}
  1795. end trimCharacters
  1796.  
  1797. -- ------------------------------------------------------
  1798. on trimOneChar(inputLf, outputTrimmed, theLfOffset, substitueCharacter)
  1799.     global debug
  1800.    
  1801.     if debug ≥ 3 then
  1802.         log "in ~~~ trimOneChar ~~~"
  1803.         hexDumpFormatOne("inputLf", inputLf)
  1804.         hexDumpFormatOne("outputTrimmed", outputTrimmed)
  1805.         log "trimOneChar: theLfOffset, is " & getIntegerAndHex(theLfOffset)
  1806.         log "trimOneChar: with substitueCharacter >" & substitueCharacter & "<  "
  1807.     end if
  1808.    
  1809.     -- check boundaries
  1810.     if theLfOffset ≤ 0 or (theLfOffset > (length of inputLf)) then
  1811.         -- We are almost done.
  1812.         if debug ≥ 3 then log "trimOneChar: no LF found."
  1813.         -- tack on any trialing stuff
  1814.         set outputTrimmed to outputTrimmed & inputLf
  1815.         set inputLf to ""
  1816.         if debug ≥ 3 then
  1817.             hexDumpFormatOne("trimOneChar: inputLf", inputLf)
  1818.             hexDumpFormatOne("trimOneChar: outputTrimmed", outputTrimmed)
  1819.         end if
  1820.         return {inputLf, outputTrimmed} ------------ return ------------>
  1821.     end if
  1822.    
  1823.     -- We need to deal with output first, so we haven't trimmed the input we need.
  1824.     if theLfOffset ≥ 2 then
  1825.         if debug ≥ 6 then log "  theLfOffset ≥ 2"
  1826.         set outputTrimmed to outputTrimmed & (text 1 thru (theLfOffset - 1) of inputLf) & substitueCharacter
  1827.     else if theLfOffset = 1 then
  1828.         if debug ≥ 6 then log "  theLfOffset = 1"
  1829.         -- no stuff before the lf
  1830.         set outputTrimmed to outputTrimmed & substitueCharacter
  1831.     end if
  1832.    
  1833.     -- deal with inputLf.
  1834.     if theLfOffset < (length of inputLf) then
  1835.         if debug ≥ 6 then log "trimOneChar:  theLfOffset < (length of inputLf) "
  1836.         -- trailing stuff
  1837.         set inputLf to text (theLfOffset + 1) thru -1 of inputLf
  1838.     else if theLfOffset is (length of inputLf) then
  1839.         if debug ≥ 6 then log "trimOneChar:  theLfOffset is (length of inputLf) "
  1840.         set inputLf to ""
  1841.     end if
  1842.    
  1843.     if debug ≥ 3 then
  1844.         hexDumpFormatOne("trimOneChar: inputLf", inputLf)
  1845.         hexDumpFormatOne("trimOneChar: outputTrimmed", outputTrimmed)
  1846.     end if
  1847.     if debug ≥ 4 then log "bye from  ~.~ trimOneChar ~.~"
  1848.     return {inputLf, outputTrimmed}
  1849.    
  1850. end trimOneChar
  1851.  
  1852. -- ------------------------------------------------------
  1853. (*
  1854.          Unix-like systems      LF      0A      \n
  1855.             (Linux, macOS)
  1856.                Microsoft Windows    CRLF    0D 0A   \r\n
  1857.                classic Mac OS       CR      0D          \r   Applescript return
  1858.  *)
  1859. on typeText(theData)
  1860.    
  1861.     global debug
  1862.     if debug ≥ 5 then log "in ~~~ typeText ~~~"
  1863.     set lf to character id 1
  1864.    
  1865.     if debug ≥ 2 then printHeader("the input  ( theData )", theData)
  1866.     -- Example: -- https://discussions.apple.com/docs/DOC-8841
  1867.     -- locate links
  1868.    
  1869.     set theOutputBuffer to adjustURLs(theData, {"https://", "http://", "<a ", "<img"})
  1870.    
  1871.     -- add paragraphs
  1872.     set theOutputBuffer to addParagraphs(theOutputBuffer)
  1873.    
  1874.     if debug ≥ 2 then log "theOutputBuffer is " & return & theOutputBuffer
  1875.     if debug ≥ 4 then log "bye from  -.- typeText -.-"
  1876.     return theOutputBuffer
  1877. end typeText
  1878.  
  1879. -- ------------------------------------------------------
  1880. (*
  1881.  find the end of an URL
  1882.        -- find the end of the HTML URL by splitting on blank or return 
  1883.     -- unsafe characters  <blank> " < > # % { } | \ ^ ~ [ ] `
  1884.     -- and line-end
  1885.     -- while # is listed as unsafe, it does appear in a url as a marker of some sort.
  1886.     -- leave it out as an ending character.
  1887.     -- https://perishablepress.com/stop-using-unsafe-characters-in-urls/
  1888.     -- the end of the clipboard string my end after the url, hence no " ", LF or CR
  1889.     -- Rember, CRLF was converted to LF above
  1890. *)
  1891. on urlEndsWHere(theInputBuffer)
  1892.     global debug
  1893.     set lf to character id 10
  1894.    
  1895.     if debug ≥ 5 then log "in  ~~~ urlEndsWHere ~~~"
  1896.     set endsWhere to {}
  1897.     -- the end of the url ends with one of the not allowed characters + line-end
  1898.     repeat with unsafeCharacter in {" ", "\"", lf, "<", ">", "%", "{", "}", "|", "\\", "^", "~", "[", "]"}
  1899.         copy (offset of unsafeCharacter in theInputBuffer) to the end of the endsWhere
  1900.     end repeat
  1901.     if debug ≥ 6 then log endsWhere
  1902.     set endOfURL to (minimumPositiveNumber from endsWhere) - 1
  1903.    
  1904.     if debug ≥ 6 then log "  urlEndsWHere: endOfURL is " & endOfURL
  1905.    
  1906.     if endOfURL ≤ 0 then
  1907.         -- We have reached the end of the input
  1908.         set theURL to theInputBuffer
  1909.         set theInputBuffer to ""
  1910.     else
  1911.         set theURL to text 1 thru endOfURL of theInputBuffer
  1912.         if debug ≥ 6 then log "  urlEndsWHere:s: from middle theURL is " & theURL
  1913.        
  1914.         set theInputBuffer to text (endOfURL + 1) thru -1 of theInputBuffer -- trim off url in front.
  1915.     end if
  1916.     return {theURL, theInputBuffer}
  1917. end urlEndsWHere
  1918.  
  1919. -- ------------------------------------------------------
  1920. (* 
  1921. place debuging data on cipboard
  1922. has a big side effect.  
  1923. *)
  1924. on wrapupClipboardDataSelector()
  1925.     global debug
  1926.     if debug ≥ 5 then log "in ~~~ wrapupClipboardDataSelector ~~~"
  1927.     return "<html><head><meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">
  1928. <title>roger's troubles.html</title></head>
  1929. <body>There are apps in the Play Store to sync calendars and contacts -
  1930. search on
  1931. Smoothsync for two of the best. <br>
  1932. <br>
  1933. iCloud mail is standard IMAP and you
  1934. can access it in the mail application using the settings here:<br>
  1935. <br>
  1936.  
  1937. <a href=\"https://support.apple.com/HT202304\">https://support.apple.com/HT202304</a><br>
  1938. <br>
  1939.  
  1940. As you are using a non-Apple app to access your email or other 
  1941. facilities, you are now required to use an 'app-specific' password in
  1942. place of your normal iCloud password. In order to do this you need to
  1943. set up two-factor authentication for your Apple ID, and for this you
  1944. need to have either a Mac running El Capitan or above, or an iOS device
  1945. running iOS9 or above.<br>
  1946. <br>
  1947.  
  1948. <a href=\"https://support.apple.com/HT204915\">https://support.apple.com/HT204915</a><br>
  1949. <br>
  1950.  
  1951. <a href=\"https://support.apple.com/HT204397\">https://support.apple.com/HT204397</a><br>
  1952. <br>
  1953.  
  1954. If you are unable to set up two-factor authentication you should set up
  1955. 2-step verification and use that to create an app-specific password
  1956. (see link below) . Then go
  1957. to <a href=\"https://appleid.apple.com\">https://appleid.apple.com </a>, select 'Password and Security'; click
  1958. 'Generate an App-Specific
  1959. Password' and follow the instructions. Once you have the password, copy
  1960. it and paste it into the password field in the application instead of
  1961. your usual iCloud password. You should also keep a note of it (though
  1962. you can generate a new one if required).<br>
  1963. <br>
  1964.  
  1965. <a href=\"https://support.apple.com/kb/HT204152\">https://support.apple.com/kb/HT204152</a><br>
  1966. <br>
  1967.  
  1968. You will need to nominate a 'trusted device' - any phone capable of
  1969. receiving SMS messages. There will be a 2-day wait before you can
  1970. complete the process.<br>
  1971.  
  1972. (A particular caveat (about 2-step only) - you will be issued with a
  1973. 'Recovery Key' in case you lose your 'trusted device'. Make sure to
  1974. write this down and keep it in a safe place; if you lose both it and
  1975. your trusted device you will be permanently locked out of your ID.
  1976. You'd be surprised at the number of people who've posted here that
  1977. they've got themselves into just that position.)</body></html>"
  1978.    
  1979. end wrapupClipboardDataSelector
  1980. (* <br>
  1981. Strictly speaking all purchases
  1982. are final (after all, you can't very well return them): please see this
  1983. page for information on requesting a refund:<a href=\"https://support.apple.com/HT204084\"> https://support.apple.com/HT204084</a><br>
  1984. <br>However Apple have been known to be sympathetic in cases of
  1985. actual error, so it's possible that they may allow you a refund as a
  1986. one-off concession: but please be aware that they are under no
  1987. obligation to do so: go to<a href=\"https://www.apple.com/emea/support/itunes/contact.html\"> https://www.apple.com/emea/support/itunes/contact.html</a></span><br>
  1988. <br style=\"font-family: Arial;\">
  1989. <span style=\"font-family: Arial;\">Alternatively go to the page
  1990. suggested in the Help page linked to above:</span><a href=\"https://reportaproblem.apple.com/?s=6\"><span style=\"font-family: Arial;\"> https://reportaproblem.apple.com/?s=6</span></a></font><a href=\"https://reportaproblem.apple.com/?s=6\">
  1991. </a><br>
  1992. *)
  1993. (*  return "<html><head>
  1994. <meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">
  1995. <title>asc insert title in &lt;a>.html</title>
  1996. </head>
  1997. <body>
  1998. <p></p>
  1999. <p>\"Avoid phishing scams\"
  2000. <a href=\"https://support.apple.com/en-ca/HT204759\">https://support.apple.com/en-ca/HT204759</a>
  2001. </p>
  2002. <p>Lets pad the <a> tag.</p>
  2003. <p>
  2004. <a title=\"Go to W3Schools HTML section\" href=\"https://support.apple.com/en-ca/HT204759\" target=\"_blank\">https://support.apple.com/en-ca/HT204759</a>
  2005. </p>
  2006. <p>That's all folks.</p><p></p>
  2007. </body>
  2008. <html>"
  2009.     *)
  2010. (*
  2011.    
  2012.        
  2013.     "Global Lyme Alliance Reveals Several Drugs and Drug Combinations That Show Success in Treating Lyme Disease
  2014. https://globallymealliance.org/press-releases/global-lyme-alliance-reveals-several-drugs-drug-combinations-show-success-treating-lyme-disease/?utm_source=Newsletter&utm_campaign=220eebaf84-EMAIL_CAMPAIGN_2019_04_18_03_43&utm_medium=email&utm_term=0_2eb359dd6a-220eebaf84-37014111
  2015.  
  2016. https://www.omf.ngo/community-symposium-2/
  2017. Saturday, September 7, 2019
  2018. Live streamed
  2019. https://www.omf.ngo/community-symposium-2/
  2020.  
  2021.  
  2022. New OMF-funded Research Publication: A Nanoelectronics-blood-based diagnostic biomarker for ME/CFS
  2023.  
  2024. Dr. Ron Davis, OMF Scientific Advisory Board Director, explains the PNAS publication on the nanoneedle (April 29, 2019)
  2025.  
  2026. A paper describing the nanoneedle was published in the Proceedings of the National Academy of Sciences. Ronald W. Davis, PhD, is the senior author. Rahim Esfandyarpour, PhD, is the lead author. The nanoneedle is a test that measures changes in immune cells with their blood plasma as a result of salt stress. Inside the nanoneedle, the immune cells interfere with a small electric current. The change in electrical activity is directly correlated with the health of the sample. The test, which is still in a pilot phase, is based on how a person’s immune cells respond to stress. With blood samples from 40 people — 20 with ME/CFS and 20 without — the test yielded precise results, accurately flagging all patients and none of the healthy individuals.
  2027.  
  2028.  
  2029. https://www.youtube.com/watch?v=6Qn0fIV8SbE&feature=youtu.be"
  2030.    
  2031.     return "<p> </p><p> </p><p>If you are unable to set up \"two-factor authentication,\" you should set up \"2-step.\"
  2032.    
  2033.    
  2034.  
  2035.  
  2036. Run etrecheck.  The
  2037. first five runs are free.</p> "
  2038. *)
  2039.  
  2040. (* 
  2041. set the clipboard to "<html><p>As you are using a non-Apple app to access your email or other  facilities, you are now required to use an 'app-specific' password in place of your normal iCloud password. In order to do this you need to set up two-factor authentication for your Apple ID, and for this you need to have either a Mac running El Capitan or above, or an iOS device running iOS9 or above.</p><p> </p><p><a href=\"https://support.apple.com/HT204915\" target=\"_blank\">Two-factor authentication for Apple ID - Apple Support</a></p><p> </p><p><a href=\"https://support.apple.com/HT204397\" target=\"_blank\">Using app-specific passwords - Apple Support</a></p><p> </p><p>If you are unable to set up \"two-factor authentication,\" you should set up \"2-step.\"
  2042.    
  2043.    
  2044.  
  2045.  
  2046. Run etrecheck.  The
  2047. first five runs are free. Provided a report on your
  2048. machines hardware and software.  Great for diagnosing your system.  Click on the download
  2049. link at the bottom of the screen.
  2050. <a href=\"http://etrecheck.com/\" target=\"_blank\">EtreCheck</a></p><p></p>
  2051. <p></p><p>
  2052. <ol>
  2053. <li>point 1</li>
  2054. <li>point 2</li>
  2055. <li>point 3</li>
  2056. </ol>
  2057. </p>
  2058. <p>the end</p>
  2059.  
  2060. </ol></p><p>
  2061. "
  2062. *)
  2063. (*
  2064. https://www.oreilly.com/library/view/applescript-the-definitive/0596102119/re89.html
  2065.  
  2066. https://stackoverflow.com/questions/11085654/apple-script-how-can-i-copy-html-content-to-the-clipboard
  2067.  
  2068. -- user has copied a file's icon in the Finder
  2069. clipboard info
  2070. -- {{string, 20}, {«class ut16», 44}, {«class hfs », 80}, {«class
  2071. utf8», 20}, {Unicode text, 42}, {picture, 2616}, {«class icns», 43336},
  2072. {«class furl», 62}}
  2073.  
  2074. textutil -convert html foo.rtf
  2075.  
  2076. if ((clipboard info) as string) contains "«class furl»" then
  2077.         log "the clipboard contains a file named " & (the clipboard as string)
  2078.     else
  2079.         log "the clipboard does not contain a file"
  2080.     end if
  2081.    
  2082. the clipboard       required
  2083. as  class   optional
  2084.  
  2085. tell application "Script Editor"
  2086.         activate
  2087.     end tell
  2088.    
  2089. textutil has a simplistic text to html conversion
  2090.    set clipboardDataQuoted to quoted form of theData
  2091.     log "quoted form is " & clipboardDataQuoted
  2092.    
  2093.     set toUnix to "/bin/echo -n " & clipboardDataQuoted
  2094.     set toUnix to toUnix & " | textutil -convert html -noload -nostore -stdin -stdout "
  2095.     log "toUnix is " & toUnix
  2096.     set fromUnix to do shell script toUnix
  2097.     log "fromUnix  is " & fromUnix
  2098.    
  2099.    
  2100. set s to "Today is my birthday"
  2101. log text 1 thru ((offset of "my" in s) - 1) of s
  2102. --> "Today is "
  2103.             -- text 1 thru ((offset of "my" in s) - 1) of s
  2104.             -- -1 since offset return the first character "m" position count
  2105.            
  2106. log "beginningOfTag is " & text 1 thru (minimumPositiveNumber from {200, length of beginningOfTag}) of beginningOfTag & "<+++++++++++++++++++++++"
  2107.  
  2108. https://developer.apple.com/library/archive/documentation/AppleScript/Conceptual/AppleScriptLangGuide/reference/ASLR_cmds.html
  2109.  
  2110. *)
  2111.  
  2112. --mac $ hex=`echo -n "<p>your html code here</>" | hexdump -ve '1/1 "%.2x"'`
  2113. --mac $ echo $hex
  2114. --3c703e796f75722068746d6c20636f646520686572653c2f3e
  2115. --mac $ osascript -e "set the clipboard to «data HTML${hex}»"
  2116. --mac $
  2117. (*  
  2118. A sub-routine for encoding ASCII characters.  
  2119.  
  2120. encode_char("$")  
  2121. --> returns: "%24"  
  2122.  
  2123. based on:  
  2124. https://www.macosxautomation.com/applescript/sbrt/sbrt-08.html  
  2125.  
  2126. *)
  2127. (*
  2128. Lowest Numeric Value in a List
  2129.  
  2130. This sub-routine will return the lowest numeric value in a list of items. The passed list can contain non-numeric data as well as lists within lists. For example:
  2131.  
  2132. lowest_number({-3.25, 23, 2345, "sid", 3, 67})
  2133. --> returns: -3.25
  2134. lowest_number({-3.25, 23, {-22, 78695, "bob"}, 2345, true, "sid", 3, 67})
  2135. --> returns: -22
  2136.  
  2137. If there is no numeric data in the passed list, the sub-routine will return a null string ("")
  2138.  
  2139. lowest_number({"this", "list", "contains", "only", "text"})
  2140. --> returns: ""
  2141.  
  2142. https://macosxautomation.com/applescript/sbrt/sbrt-03.html
  2143.  
  2144. Here's the sub-routine:
  2145.  
  2146. *)
  2147. (*
  2148. on lowestNumber(values_list)
  2149.     set the low_amount to ""
  2150.     repeat with i from 1 to the count of the values_list
  2151.         set this_item to item i of the values_list
  2152.         set the item_class to the class of this_item
  2153.         if the item_class is in {integer, real} then
  2154.             if the low_amount is "" then
  2155.                 set the low_amount to this_item
  2156.             else if this_item is less than the low_amount then
  2157.                 set the low_amount to item i of the values_list
  2158.             end if
  2159.         else if the item_class is list then
  2160.             set the low_value to lowest_number(this_item)
  2161.             if the the low_value is less than the low_amount then ¬
  2162.                 set the low_amount to the low_value
  2163.         end if
  2164.     end repeat
  2165.     return the low_amount
  2166. end lowestNumber
  2167.  
  2168. https://lists.apple.com/archives/applescript-users/2010/Sep/msg00139.html
  2169. set list_of_values to {10, 20, 30, 40, 50, 60, 2000, 9, 3000, 4}
  2170.  
  2171. set minimum to 9.9999999999E+12
  2172. set maximum to 0
  2173. repeat with ref_to_value in list_of_values
  2174.     set the_value to contents of ref_to_value
  2175.     if the_value > maximum then set maximum to the_value
  2176.     if the_value < minimum then set minimum to the_value
  2177. end repeat
  2178.  
  2179. {minimum, maximum}
  2180.  
  2181. may do the trick.
  2182.  
  2183. Yvan KOENIG (VALLAURIS, France) lundi 13 septembre 2010 22:32:41
  2184. *)
  2185. (* https://lists.apple.com/archives/applescript-users/2010/Sep/msg00139.html
  2186. set list_of_values to {10, 20, 30, 40, 50, 60, 2000, 9, 3000, 4}
  2187.  
  2188. set minimum to 9.9999999999E+12
  2189.  
  2190. assume it's limited to positive values
  2191.  
  2192.  
  2193. on maxValue(list_of_values)
  2194.     global debug
  2195.     if debug ≥ 5 then log "in maxValue " & return & list_of_values
  2196.     set maximum to 0
  2197.     repeat with ref_to_value in list_of_values
  2198.         set the_value to contents of ref_to_value
  2199.         if the_value > maximum then set maximum to the_value
  2200.     end repeat
  2201.     if debug ≥ 5 then log maximum
  2202.     return maximum
  2203. end maxValue
  2204. *)
  2205. -- ------------------------------------------------------
  2206. (*
  2207. http://harvey.nu/applescript_url_encode_routine.html
  2208.  
  2209. on urlencode(theText)
  2210.     set theTextEnc to ""
  2211.     repeat with eachChar in characters of theText
  2212.         set useChar to eachChar
  2213.         set eachCharNum to ASCII number of eachChar
  2214.         if eachCharNum = 32 then
  2215.             set useChar to "+"
  2216.         else if (eachCharNum ≠ 42) and (eachCharNum ≠ 95) and (eachCharNum < 45 or eachCharNum > 46) and (eachCharNum < 48 or eachCharNum > 57) and (eachCharNum < 65 or eachCharNum > 90) and (eachCharNum < 97 or eachCharNum > 122) then
  2217.             set firstDig to round (eachCharNum / 16) rounding down
  2218.             set secondDig to eachCharNum mod 16
  2219.             if firstDig > 9 then
  2220.                 set aNum to firstDig + 55
  2221.                 set firstDig to ASCII character aNum
  2222.             end if
  2223.             if secondDig > 9 then
  2224.                 set aNum to secondDig + 55
  2225.                 set secondDig to ASCII character aNum
  2226.             end if
  2227.             set numHex to ("%" & (firstDig as string) & (secondDig as string)) as string
  2228.             set useChar to numHex
  2229.         end if
  2230.         set theTextEnc to theTextEnc & useChar as string
  2231.     end repeat
  2232.     return theTextEnc
  2233. end urlencode
  2234.  
  2235. Clipboard classes after a copy from the application.
  2236. from waterfox
  2237. (*«class HTML», 13876, «class utf8», 505, «class ut16», 1012, string, 505, Unicode text, 1010*)
  2238.  
  2239. from chrome
  2240. (*«class HTML», 748, «class utf8», 204, «class ut16», 410, string, 204, Unicode text, 408*)
  2241.  
  2242. from safari
  2243. (*«class weba», 120785, «class RTF », 70255, «class HTML», 122811, «class utf8», 3370, «class ut16», 6772, uniform styles, 47132, string, 3385, scrap styles, 8122, Unicode text, 6732, uniform styles, 47132, scrap styles, 8122*)
  2244.  
  2245. iCab
  2246. (*«class weba», 1665, «class RTF », 763, «class utf8», 121, «class ut16», 244, uniform styles, 376, string, 121, scrap styles, 62, Unicode text, 242, uniform styles, 376, scrap styles, 62*)
  2247.  
  2248. Opera
  2249. (*«class HTML», 5767, «class utf8», 150, «class ut16», 302, string, 150, Unicode text, 300*)
  2250.  
  2251. Textedit
  2252. (*«class RTF », 1136, «class utf8», 138, «class ut16», 278, uniform styles, 148, string, 138, scrap styles, 22, Unicode text, 276, uniform styles, 148, scrap styles, 22*)
  2253.  
  2254. Word
  2255. (*«class DSIG», 4, «class DOBJ», 56, «class OBJD», 244, «class RTF », 30573, «class HTML», 21160, scrap styles, 22, uniform styles, 136, string, 210, Unicode text, 420, «class PDF », 13197, picture, 154058, «class EMBS», 33280, «class LNKS», 909, «class LKSD», 244, «class OJLK», 93, «class HLNK», 1387, «class OFSC», 232, «class ut16», 422, «class DSIG», 4, «class DOBJ», 56, «class OBJD», 244, scrap styles, 22, uniform styles, 136, «class EMBS», 33280, «class LNKS», 909, «class LKSD», 244, «class OJLK», 93, «class HLNK», 1387, «class OFSC», 232*)
  2256.  
  2257. TextWrangler
  2258. (*«class utf8», 185, «class BBLM», 4, «class ut16», 372, string, 185, Unicode text, 370, «class BBLM», 4*)
  2259.  
  2260. *)
  2261.  
  2262.  
  2263.  
  2264. (*
  2265.     set the clipboard to "<html><p>As you are using a non-Apple app to access your email or other  facilities, you are now required to use an 'app-specific' password in place of your normal iCloud password. In order to do this you need to set up two-factor authentication for your Apple ID, and for this you need to have either a Mac running El Capitan or above, or an iOS device running iOS9 or above.</p><p> </p><p><a href=\"https://support.apple.com/HT204915\" target=\"_blank\">Two-factor authentication for Apple ID - Apple Support</a></p><p> </p><p><a href=\"https://support.apple.com/HT204397\" target=\"_blank\">Using app-specific passwords - Apple Support</a></p><p> </p><p>If you are unable to set up two-factor authentication you should set up 2-step \"
  2266.    
  2267.    
  2268.  
  2269.  
  2270. Run etrecheck.  The
  2271. first five runs are free. Provided a report on your
  2272. machines hardware and software.  Great for diagnosing your system.  Click on the download
  2273. link at the bottom of the screen.
  2274. <a href=\"http://etrecheck.com/\" target=\"_blank\">EtreCheck</a></p><p></p>
  2275. <p></p><p>
  2276. <ol>
  2277. <li>point 1</li>
  2278. <li>point 2</li>
  2279. <li>point 3</li>
  2280. </ol>
  2281. </p>
  2282. <p>the end</p>
  2283. "
  2284.     *)
  2285. (*  set the clipboard to "<p>Simple put, Apple attempts
  2286. to provide all the
  2287. malware detection and removal you need in Mac OS X.</p>
  2288. <p></p><p></p><p></p>
  2289. <p>\"Effective defenses against malware and other threats\" by John Galt
  2290. <a href=\"https://discussions.apple.com/docs/DOC-8841\" target=\"_blank\">Effective
  2291. defenses against malware and ot… - Apple Community</a>
  2292. </p><pre>
  2293. code line #a
  2294. code line #b
  2295. code line #c
  2296. </pre><p> </p><p>\"Avoid phishing emails, fake 'virus' alerts, phony support calls, and other scams\"
  2297. <a href=\"https://support.apple.com/en-ca/HT204759\">Avoid phishing emails, fake
  2298. 'virus' alerts, phony support calls, and other scams - Apple Support</a>
  2299. <pre>
  2300. code line #1
  2301. code line #2
  2302. code line #3
  2303. </pre>"
  2304. *)
  2305. (*
  2306.     set the clipboard to "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">
  2307. <html>
  2308.  <head>
  2309.  
  2310.    <meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">
  2311.    <title>asc roger's help text</title>
  2312.   </head>
  2313.   <body>
  2314.     <meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">
  2315.    <span style=\"font-weight: bold; font-family: Lucida Grande;\">App-Specific
  2316.      passwords</span> (copy direct,
  2317.    clean up returns)<br>
  2318.    <br>
  2319.    There are apps in the Play Store to sync calendars and contacts -
  2320.    search on
  2321.    Smoothsync for two of the best. <br>
  2322.    <br>
  2323.    iCloud mail is standard IMAP and you
  2324.    can access it in the mail application using the settings here:<br>
  2325.    <br>
  2326.    <a href=\"https://support.apple.com/HT202304\">https://support.apple.com/HT202304</a><br>
  2327.    <br>
  2328.    As you are using a non-Apple app to access your email or other&nbsp;
  2329.    facilities, you are now required to use an 'app-specific' password
  2330.    in
  2331.    place of your normal iCloud password. In order to do this you need
  2332.    to
  2333.    set up two-factor authentication for your Apple ID, and for this you
  2334.    need to have either a Mac running El Capitan or above, or an iOS
  2335.    device
  2336.    running iOS9 or above.<br>
  2337.    <br>
  2338.    <a href=\"https://support.apple.com/HT204915\">https://support.apple.com/HT204915</a><br>
  2339.    <br>
  2340.    <a href=\"https://support.apple.com/HT204397\">https://support.apple.com/HT204397</a><br>
  2341.    <br>
  2342.    If you are unable to set up two-factor authentication you should set
  2343.    up
  2344.    2-step verification and use that to create an app-specific password
  2345.    (see link below) . Then go
  2346.    to https://appleid.apple.com , select 'Password and Security'; click
  2347.    'Generate an App-Specific
  2348.    Password' and follow the instructions. Once you have the password,
  2349.    copy
  2350.    it and paste it into the password field in the application instead
  2351.    of
  2352.    your usual iCloud password. You should also keep a note of it
  2353.    (though
  2354.    you can generate a new one if required).<br>
  2355.    <br>
  2356.    <a href=\"https://support.apple.com/kb/HT204152\">https://support.apple.com/kb/HT204152</a><br>
  2357.    <br>
  2358.    You will need to nominate a 'trusted device' - any phone capable of
  2359.    receiving SMS messages. There will be a 2-day wait before you can
  2360.    complete the process.<br>
  2361.    (A particular caveat (about 2-step only) - you will be issued with a
  2362.    'Recovery Key' in case you lose your 'trusted device'. Make sure to
  2363.    write this down and keep it in a safe place; if you lose both it and
  2364.    your trusted device you will be permanently locked out of your ID.
  2365.    You'd be surprised at the number of people who've posted here that
  2366.    they've got themselves into just that position.)<br>
  2367.    <br>
  2368.    Incidentally, Mail on Snow Leopard and earlier is not recognized as
  2369.    an
  2370.    Apple application because it's pre-iCloud and doesn't have the
  2371.    necessary facilities, so it will be necessary to obtain an
  2372.    app-specific
  2373.    password for that.
  2374.  </body>
  2375. </html>
  2376.  
  2377. <!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">
  2378. <html>
  2379.  <head>
  2380.  
  2381.    <meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">
  2382.    <title>asc roger's help text</title>
  2383.  </head>
  2384.  <body>
  2385.    <meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">
  2386.    <span style=\"font-weight: bold; font-family: Lucida Grande;\">App-Specific
  2387.      passwords</span> (copy direct,
  2388.    clean up returns)<br>
  2389.    <br>
  2390.    There are apps in the Play Store to sync calendars and contacts -
  2391.    search on
  2392.    Smoothsync for two of the best. <br>
  2393.    <br>
  2394.    iCloud mail is standard IMAP and you
  2395.    can access it in the mail application using the settings here:<br>
  2396.    <br>
  2397.    <a href=\"https://support.apple.com/HT202304\">https://support.apple.com/HT202304</a><br>
  2398.    <br>
  2399.    As you are using a non-Apple app to access your email or other&nbsp;
  2400.    facilities, you are now required to use an 'app-specific' password
  2401.    in
  2402.    place of your normal iCloud password. In order to do this you need
  2403.    to
  2404.    set up two-factor authentication for your Apple ID, and for this you
  2405.    need to have either a Mac running El Capitan or above, or an iOS
  2406.    device
  2407.    running iOS9 or above.<br>
  2408.    <br>
  2409.    <a href=\"https://support.apple.com/HT204915\">https://support.apple.com/HT204915</a><br>
  2410.    <br>
  2411.    <a href=\"https://support.apple.com/HT204397\">https://support.apple.com/HT204397</a><br>
  2412.    <br>
  2413.    If you are unable to set up two-factor authentication you should set
  2414.    up
  2415.    2-step verification and use that to create an app-specific password
  2416.    (see link below) . Then go
  2417.    to https://appleid.apple.com , select 'Password and Security'; click
  2418.    'Generate an App-Specific
  2419.    Password' and follow the instructions. Once you have the password,
  2420.    copy
  2421.    it and paste it into the password field in the application instead
  2422.    of
  2423.    your usual iCloud password. You should also keep a note of it
  2424.    (though
  2425.    you can generate a new one if required).<br>
  2426.    <br>
  2427.    <a href=\"https://support.apple.com/kb/HT204152\">https://support.apple.com/kb/HT204152</a><br>
  2428.    <br>
  2429.    You will need to nominate a 'trusted device' - any phone capable of
  2430.    receiving SMS messages. There will be a 2-day wait before you can
  2431.    complete the process.<br>
  2432.    (A particular caveat (about 2-step only) - you will be issued with a
  2433.    'Recovery Key' in case you lose your 'trusted device'. Make sure to
  2434.    write this down and keep it in a safe place; if you lose both it and
  2435.    your trusted device you will be permanently locked out of your ID.
  2436.    You'd be surprised at the number of people who've posted here that
  2437.    they've got themselves into just that position.)<br>
  2438.    <br>
  2439.    Incidentally, Mail on Snow Leopard and earlier is not recognized as
  2440.    an
  2441.    Apple application because it's pre-iCloud and doesn't have the
  2442.    necessary facilities, so it will be necessary to obtain an
  2443.    app-specific
  2444.    password for that.
  2445.  </body>
  2446. </html>
  2447. "
  2448.  
  2449. adustDuplicateAnchorURLs("<a href=\"https://support.apple.com/en-ca/HT204759\">https://support.apple.com/en-ca/HT204759</a>")
  2450.  
  2451. adustDuplicateAnchorURLs("<a title=\"Go to W3Schools HTML section\" href=\"https://support.apple.com/en-ca/HT204759\" target=\"_blank\">https://support.apple.com/en-ca/HT204759</a>")
  2452.    
  2453. return
  2454.    
  2455. *)
  2456. (*
  2457. on trimCharacters(inputTrim, outputTrim, reduce)
  2458.     global debug
  2459.     set charactersTrimmed to ""
  2460.     if debug ≥ 3 then
  2461.         log "in ~~~ trimCharacters ~~~"
  2462.         log "  trimCharacters: length of inputTrim is " & getIntegerAndHex(length of inputTrim)
  2463.         hexDumpFormatOne("  trimCharacters: inputTrim", inputTrim)
  2464.         log "  trimCharacters: length of outputTrim is " & getIntegerAndHex(length of outputTrim)
  2465.         hexDumpFormatOne("  trimCharacters: outputTrim", outputTrim)
  2466.         log "  trimCharacters: with reduce >" & reduce & "<  "
  2467.     end if
  2468.     set repCount to 1
  2469.    
  2470.     repeat while length of inputTrim ≥ 1 and text 1 thru 1 of inputTrim is reduce
  2471.         set charactersTrimmed to charactersTrimmed & reduce
  2472.         set {inputTrim, outputTrim} to trimOneChar(inputTrim, outputTrim, 1, "")
  2473.         if debug ≥ 6 then
  2474.             log "  trimCharacters: repCount is " & repCount
  2475.             set repCount to repCount + 1
  2476.             log "  trimCharacters: length of inputTrim is" & getIntegerAndHex(length of inputTrim)
  2477.             hexDumpFormatOne("  trimCharacters: cycling inputTrim", inputTrim)
  2478.             log "  trimCharacters: length of outputTrim is " & getIntegerAndHex(length of outputTrim)
  2479.             hexDumpFormatOne("  trimCharacters: cycling outputTrim", outputTrim)
  2480.         end if
  2481.     end repeat
  2482.    
  2483.     if debug ≥ 3 then
  2484.         log "  trimCharacters: length of inputTrim is" & getIntegerAndHex(length of inputTrim)
  2485.         hexDumpFormatOne("  trimCharacters: completed inputTrim", inputTrim)
  2486.         log "  trimCharacters: length of outputTrim is " & getIntegerAndHex(length of outputTrim)
  2487.         hexDumpFormatOne("  trimCharacters: completed outputTrim", outputTrim)
  2488.         log "  trimCharacters: charactersTrimmed  is " & charactersTrimmed
  2489.         log "bye from  ~.~ trimCharacters ~.~"
  2490.     end if
  2491.     return {inputTrim, outputTrim, charactersTrimmed}
  2492. end trimCharacters
  2493. *)
  2494. (*
  2495. -- ------------------------------------------------------
  2496. --  
  2497. -- print out the items in a list
  2498. --
  2499. --
  2500.  
  2501. on printList(theName, splits)
  2502.     global debug
  2503.     if debug ≥ 5 then log "in ~~~ printList ~~~"
  2504.     try
  2505.         set theCount to 1
  2506.         repeat with theEntry in splits
  2507.             --log "class of theEntry is " & class of theEntry
  2508.             set classDisplay to class of theEntry as text
  2509.             --log "classDisplay is " & classDisplay as text
  2510.             --log "class of classDisplay is " & class of classDisplay
  2511.             if classDisplay is "list" then
  2512.                 log "    " & theName & " # " & theCount & " is " & item 1 of theEntry & "; " & item 2 of theEntry
  2513.             else
  2514.                 log "    " & theName & " # " & theCount & " is " & theEntry
  2515.             end if
  2516.             set theCount to theCount + 1
  2517.         end repeat
  2518.     on error errMsg number n
  2519.         log "==> No go in printList. " & errMsg & " with number " & n
  2520.     end try
  2521. end printList
  2522. *)
  2523.  
  2524.  
  2525. (*
  2526.    
  2527.     tell application "Finder"
  2528.         --set theFiles to (files in folder (choose folder))
  2529.         --reveal theFiles
  2530.     end tell
  2531.     tell application "Finder"
  2532.         --  set theFile to (choose file)
  2533.         --reveal theFiles
  2534.     end tell
  2535.     set theFiles to {¬
  2536.         alias "Macintosh SSD:Users:mac:Documents:css-12-15-2018:ASC Testing:Paralles virtual machine -<a ... - html.html", ¬
  2537.         alias "Macintosh SSD:Users:mac:Documents:css-12-15-2018:ASC Testing:asc appleid login.txt", ¬
  2538.         alias "Macintosh SSD:Users:mac:Documents:css-12-15-2018:ASC Testing:asc example longer text conversion few line ends.txt", ¬
  2539.         alias "Macintosh SSD:Users:mac:Documents:css-12-15-2018:ASC Testing:asc example longer text conversion.txt", ¬
  2540.         alias "Macintosh SSD:Users:mac:Documents:css-12-15-2018:ASC Testing:asc example text conversion with list with &nbsp;.html", ¬
  2541.         alias "Macintosh SSD:Users:mac:Documents:css-12-15-2018:ASC Testing:asc example text conversion with list with <pre> with <head> \"Waterfox\".html", ¬
  2542.         alias "Macintosh SSD:Users:mac:Documents:css-12-15-2018:ASC Testing:asc example text conversion with list with <pre> with tabs and tabs in gneral.html", ¬
  2543.         alias "Macintosh SSD:Users:mac:Documents:css-12-15-2018:ASC Testing:asc example text conversion with list with <pre>.html", ¬
  2544.         alias "Macintosh SSD:Users:mac:Documents:css-12-15-2018:ASC Testing:asc example text conversion with list with lf & <pre>.html", ¬
  2545.         alias "Macintosh SSD:Users:mac:Documents:css-12-15-2018:ASC Testing:asc example text conversion with list.html", ¬
  2546.         alias "Macintosh SSD:Users:mac:Documents:css-12-15-2018:ASC Testing:asc example text conversion with list.txt", ¬
  2547.         alias "Macintosh SSD:Users:mac:Documents:css-12-15-2018:ASC Testing:asc file test \"Waterfox\".html", ¬
  2548.         alias "Macintosh SSD:Users:mac:Documents:css-12-15-2018:ASC Testing:asc file test with no begin title.html", ¬
  2549.         alias "Macintosh SSD:Users:mac:Documents:css-12-15-2018:ASC Testing:asc file test with no end title.html", ¬
  2550.         alias "Macintosh SSD:Users:mac:Documents:css-12-15-2018:ASC Testing:asc file test with title.html", ¬
  2551.         alias "Macintosh SSD:Users:mac:Documents:css-12-15-2018:ASC Testing:asc file test.html", ¬
  2552.         alias "Macintosh SSD:Users:mac:Documents:css-12-15-2018:ASC Testing:asc from Roger on Jiune 11th.htm..html", ¬
  2553.         alias "Macintosh SSD:Users:mac:Documents:css-12-15-2018:ASC Testing:asc insert title in <a>.html", ¬
  2554.         alias "Macintosh SSD:Users:mac:Documents:css-12-15-2018:ASC Testing:asc isolate a Roger issue.html", ¬
  2555.         alias "Macintosh SSD:Users:mac:Documents:css-12-15-2018:ASC Testing:asc link problem form Roger.html", ¬
  2556.         alias "Macintosh SSD:Users:mac:Documents:css-12-15-2018:ASC Testing:asc list test for ASC.html", ¬
  2557.         alias "Macintosh SSD:Users:mac:Documents:css-12-15-2018:ASC Testing:asc mangle tags via \\\".html", ¬
  2558.         alias "Macintosh SSD:Users:mac:Documents:css-12-15-2018:ASC Testing:asc my script froze on.txt", ¬
  2559.         alias "Macintosh SSD:Users:mac:Documents:css-12-15-2018:ASC Testing:asc roger's help text.html", ¬
  2560.         alias "Macintosh SSD:Users:mac:Documents:css-12-15-2018:ASC Testing:asc single ul and p with links.html", ¬
  2561.         alias "Macintosh SSD:Users:mac:Documents:css-12-15-2018:ASC Testing:asc spacing test with backslash.html", ¬
  2562.         alias "Macintosh SSD:Users:mac:Documents:css-12-15-2018:ASC Testing:asc spacing test.html", ¬
  2563.         alias "Macintosh SSD:Users:mac:Documents:css-12-15-2018:ASC Testing:links and list of numbers.txt", ¬
  2564.         alias "Macintosh SSD:Users:mac:Documents:css-12-15-2018:ASC Testing:littlebittytest.html", ¬
  2565.         alias "Macintosh SSD:Users:mac:Documents:css-12-15-2018:ASC Testing:roger's troubles.html", ¬
  2566.         alias "Macintosh SSD:Users:mac:Documents:css-12-15-2018:ASC Testing:CyberDuck demo.html"}
  2567.    
  2568.    
  2569.    
  2570.    
  2571.     -- debuging for openContinued.  Displays timed display dialogs.
  2572.     set localDebug to false
  2573.     -- true displayed timed dialogs
  2574.     -- false skip debuging 
  2575.     set debugSeparator to true
  2576.     -- true place a separator between the output of dropped files
  2577.     -- false nothing is added      
  2578.    
  2579.     -- alias "Macintosh SSD:Users:mac:Documents:css-12-15-2018:ASC Testing:roger's troubles.html"
  2580.     printList("theFiles are ", theFiles)
  2581.    
  2582.     --log theFiles
  2583.     openContinued(theFiles, localDebug, debugSeparator)
  2584.    
  2585.     return 1
  2586.    
  2587.     *)
  2588.  
  2589. (* 
  2590.     set myInput to "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\"><header>what is in the header</head>"
  2591.     skipDoctype("", myInput)
  2592.    
  2593.     return
  2594.    
  2595.     *)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement