Scroll View Positioning in Flutter - flutter

I have a requirement to produce a scroll view in Flutter in which a widget containing content needs to be scrollable over top of a header widget. The header should be part of the background of the container and the content should be scrollable to cover the header. The image below illustrates this. The view on the left shows the default view when the widget is loaded. The view on the right shows the desired behavior when the view is scrolled upward to cover the header view. I've looked into SingleChildScrollView but can't find any properties that allow me to offset the content at the bottom. Can anyone suggest a different widget or point to a resource that might help? THanks!

The example below shows how you can create such feature.
import 'package:flutter/material.dart';
void main() => runApp(MaterialApp(home: App()));
class App extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
body: CustomScrollView(
slivers: [
SliverAppBar(
expandedHeight: kToolbarHeight * 6,
),
SliverFillRemaining(
child: Container(
child: Text(
'[32] Sed ut perspiciatis, unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam eaque ipsa, quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt, explicabo. Nemo enim ipsam voluptatem, quia voluptas sit, aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos, qui ratione voluptatem sequi nesciunt, neque porro quisquam est, qui dolorem ipsum, quia dolor sit amet consectetur adipisci[ng] velit, sed quia non numquam [do] eius modi tempora inci[di]dunt, ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum[d] exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? [D]Quis autem vel eum iure reprehenderit, qui in ea voluptate velit esse, quam nihil molestiae consequatur, vel illum, qui dolorem eum fugiat, quo voluptas nulla pariatur? [33] At vero eos et accusamus et iusto odio dignissimos ducimus, qui blanditiis praesentium voluptatum deleniti atque corrupti, quos dolores et quas molestias excepturi sint, obcaecati cupiditate non provident, similique sunt in culpa, qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio, cumque nihil impedit, quo minus id, quod maxime placeat, facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet, ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.',
style: Theme.of(context).textTheme.headline6,
),
),
),
],
),
);
}
}

Related

Autohotkey Hotstring is too slow

If I insert the Hotstring into another program it is not fast enough and mixes sometimes keys on the right position or it lags. It happens when I am using a long text.
I am using:
:*:ex1::Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod t
empor incididunt ut labore et dolore magna aliqua. Ut enim ad minim venia
m, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commod
o consequat. Duis aute irure dolor in reprehenderit in voluptate velit es
se cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupida
tat non proident, sunt in culpa qui officia deserunt mollit anim id est l
aborum Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod t
empor incididunt ut labore et dolore magna aliqua. Ut enim ad minim venia
m, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commod
o consequat. Duis aute irure dolor in reprehenderit in voluptate velit es
se cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupida
tat non proident, sunt in culpa qui officia deserunt mollit anim id est l
aborum
And it will result in some errors or a longer waiting duration.
This works faster, but sometimes I get an error with double text if I press an Endchar like enter too fast, or I do some different things which I can't lay my finger on.
:*:ex2::
Clipboard = %text%
Send ^v
Exit
Also there is the Clipboard messed up (I think I can store it with an variable and refill it but I am using this Multi-clipboard from windows Windows+V)
Also I am updating the Autohotkey script with excel and it is much easier to use concatenate with the first example.
=IF(List1!B34<>"",(CONCATENATE(":",List1!C34,":",List1!A34,"::",List1!B34)),(CONCATENATE(";",List1!A34)))
So I can use in C something like *0
In A the shortcut and in B the actual text.
If there is nothing in the shortcut field, my headline is inserted in the code for a better overview.
Thanks
Try this
:*:ex1::
ClipSaved := ClipboardAll ; save the entire clipboard to the variable ClipSaved
clipboard := "" ; empty the clipboard (start off empty to allow ClipWait to detect when the text has arrived)
clipboard = ; copy this text:
(
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.
Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.
Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.
Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum.
)
ClipWait, 1 ; wait for the clipboard to contain data.
If (!ErrorLevel) ; If NOT ErrorLevel clipwait found data on the clipboard
Send, ^v ; paste the text
Sleep, 300 ; don't change clipboard while pasting! (Sleep > 0)
clipboard := ClipSaved ; restore original clipboard
VarSetCapacity(ClipSaved, 0) ; free the memory
return
If you often have to send such a complex or long text, you can create a function, for not repeating the whole code every time:
:*:ex1::
my_text =
(
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.
Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat.
Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.
Duis autem vel eum iriure dolor in hendrerit in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla facilisis at vero et accumsan et iusto odio dignissim qui blandit praesent luptatum zzril delenit augue duis dolore te feugait nulla facilisi.
Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum.
)
Send(my_text)
return
Send(text){
ClipSaved := ClipboardAll
clipboard := ""
clipboard := text
ClipWait, 1
If (!ErrorLevel)
Send, ^v
Sleep, 300
clipboard := ClipSaved
VarSetCapacity(ClipSaved, 0)
}
See ClipboardAll and ClipWait

Replace numbers with delimiter AND the number

I have text that I would like to parse into individual sections, along with the number heading that section. To see what I mean, I currently have something similar to the following script that parses out lines of text between numbers such as '1. ' or '10. '.
DECLARE #EXAMPLE TABLE (
ID INT
, COMMENT VARCHAR(8000)
)
DECLARE
#olddelim1 VARCHAR(MAX) = '1. '
,#olddelim2 VARCHAR(MAX) = '2. '
,#olddelim3 VARCHAR(MAX) = '3. '
,#olddelim4 VARCHAR(MAX) = '4. '
,#olddelim5 VARCHAR(MAX) = '5. '
,#olddelim6 VARCHAR(MAX) = '6. '
,#olddelim7 VARCHAR(MAX) = '7. '
,#olddelim8 VARCHAR(MAX) = '8. '
,#olddelim9 VARCHAR(MAX) = '9. '
,#olddelim10 VARCHAR(MAX) = '0. '
,#newdelim VARCHAR(MAX) = '¦'
,#olddelim0 VARCHAR(MAX) = '¦¦'
INSERT INTO #EXAMPLE (ID, COMMENT)
VALUES
(1, '1. Sed ut perspiciatis 1.3 unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. 2. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. 3. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem 4. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur 5. Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?')
, (2, 'At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia 8.3 deserunt mollitia animi, id est laborum et dolorum fuga')
, (3, 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua 1. A cras semper auctor neque 2. Morbi tincidunt augue interdum velit euismod in')
, (4, '1. Amet luctus venenatis lectus magna 2. Magna ac placerat vestibulum lectus mauris ultrices eros in cursus 3. Et ligula ullamcorper malesuada proin libero nunc consequat interdum varius 4. Enim facilisis gravida neque convallis a 5. Sed lectus vestibulum mattis ullamcorper velit sed 6. Vel turpis nunc eget lorem dolor 7. Convallis convallis tellus id interdum velit laoreet id donec 8. Nibh tortor id aliquet lectus proin nibh nisl 9. Eu ultrices vitae auctor eu augue ut 10. Mus mauris vitae ultricies leo integer malesuada nunc 11. Viverra justo nec 10.4 ultrices dui sapien eget mi 12. Tristique senectus et netus et malesuada fames ac turpis')
UPDATE #EXAMPLE
SET COMMENT = REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(COMMENT, #olddelim1,#newdelim),#olddelim2,#newdelim),#olddelim3,#newdelim),#olddelim4,#newdelim),#olddelim5,#newdelim),#olddelim6,#newdelim),#olddelim7,#newdelim),#olddelim8,#newdelim),#olddelim9,#newdelim),#olddelim10,#newdelim),#olddelim0,#newdelim)
;WITH SPLIT_TABLE(ID, STARTS, POS, FOUND_SECTIONS) AS (
SELECT
ID
, 1
, CHARINDEX('¦', COMMENT)
, COMMENT
FROM #EXAMPLE
UNION ALL
SELECT
ID
, POS + 1
, CHARINDEX('¦', FOUND_SECTIONS, POS + 1)
, FOUND_SECTIONS
FROM SPLIT_TABLE
WHERE POS > 0)
, FOUND_SECTIONS_TBL(ID, FOUND_SECTIONS) AS (
SELECT
ID
, SUBSTRING(FOUND_SECTIONS, STARTS, CASE WHEN POS > 0 THEN POS - STARTS ELSE LEN(FOUND_SECTIONS) END)
FROM SPLIT_TABLE)
SELECT * FROM FOUND_SECTIONS_TBL
WHERE FOUND_SECTIONS <> ''
ORDER BY ID
However, what I would like to see is that the number I'm extracting stay associated to that section of text. However, I cannot simply do this with something like a ROW_NUMBER() over the STARTS/POS fields, as there are strings that do not initially start with a number (e.g. ID = 3). So the end result would look something like this:
CREATE TABLE #RESULTS (ID INT, SECTION_NUMBER INT, SECTION VARCHAR(8000))
INSERT INTO #RESULTS
VALUES
(1,1,'Sed ut perspiciatis 1.3 unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.')
,(1,2,'Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.')
,(1,3,'Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem')
,(1,4,'Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur')
,(1,5,'Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?')
,(2,0,'At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia 8.3 deserunt mollitia animi, id est laborum et dolorum fuga')
,(3,0,'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua')
,(3,1,'A cras semper auctor neque')
,(3,2,'Morbi tincidunt augue interdum velit euismod in')
,(4,1,'Amet luctus venenatis lectus magna')
,(4,2,'Magna ac placerat vestibulum lectus mauris ultrices eros in cursus')
,(4,3,'Et ligula ullamcorper malesuada proin libero nunc consequat interdum varius')
,(4,4,'Enim facilisis gravida neque convallis a ')
,(4,5,'Sed lectus vestibulum mattis ullamcorper velit sed')
,(4,6,'Vel turpis nunc eget lorem dolor')
,(4,7,'Convallis convallis tellus id interdum velit laoreet id donec')
,(4,8,'Nibh tortor id aliquet lectus proin nibh nisl')
,(4,9,'Eu ultrices vitae auctor eu augue ut')
,(4,10,'Mus mauris vitae ultricies leo integer malesuada nunc')
,(4,11,'Viverra justo nec')
,(4,12,'Tristique senectus et netus et malesuada fames ac turpis')
SELECT * FROM #RESULTS DROP TABLE #RESULTS
I've tried replacing my nested REPLACE statement with variations of the STUFF function, and even combinations of the STUFF/REPLACE functions, but I can't quite get it to work the way I want it to. Does anyone have ideas about how to do this? Thanks!
Note! Assuming that I understood your request, then The solution is simple using STRING_SPLIT function, but this is not something that you should do in production probably s the performance are really poor. This type of task are better do in the client side.
DDL+DML
CREATE TABLE EXAMPLE (
ID INT
, COMMENT VARCHAR(8000)
)
INSERT INTO EXAMPLE (ID, COMMENT)
VALUES
(1, '1. Sed ut perspiciatis 1.3 unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. 2. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. 3. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem 4. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur 5. Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?')
, (2, 'At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia 8.3 deserunt mollitia animi, id est laborum et dolorum fuga')
, (3, 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua 1. A cras semper auctor neque 2. Morbi tincidunt augue interdum velit euismod in')
, (4, '1. Amet luctus venenatis lectus magna 2. Magna ac placerat vestibulum lectus mauris ultrices eros in cursus 3. Et ligula ullamcorper malesuada proin libero nunc consequat interdum varius 4. Enim facilisis gravida neque convallis a 5. Sed lectus vestibulum mattis ullamcorper velit sed 6. Vel turpis nunc eget lorem dolor 7. Convallis convallis tellus id interdum velit laoreet id donec 8. Nibh tortor id aliquet lectus proin nibh nisl 9. Eu ultrices vitae auctor eu augue ut 10. Mus mauris vitae ultricies leo integer malesuada nunc 11. Viverra justo nec 10.4 ultrices dui sapien eget mi 12. Tristique senectus et netus et malesuada fames ac turpis')
GO
SELECT * FROM EXAMPLE
GO
Optional solution
Please check if this solve your needs:
;With MyCTE as (
select ID, c =
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(
REPLACE(COMMENT, '11. ', '#11# ')
, '12. ', '#12# '
)
, '13. ', '#13# '
)
, '4. ', '#4# '
)
, '5. ', '#5# '
)
, '6. ', '#6# '
)
, '7. ', '#7# '
)
, '8. ', '#8# '
)
, '9. ', '#9# '
)
, '10. ', '#10# '
)
, '1. ', '#1# '
)
, '2. ', '#2# '
)
, '3. ', '#3# '
)
FROM EXAMPLE
)
select ID,REPLACE(ISNULL(V.n,0),'# ','') as SECTION_NUMBER ,RIGHT([value], LEN([value]) - CHARINDEX('# ',[value],1)) as SECTION
from MyCTE
CROSS APPLY STRING_SPLIT(c,'#')
Left Join (values ('1# '),('2# '),('3# '),('4# '),('5# '),('6# '),('7# '),('8# '),('9# '),('10# '),('11# '),('12# '),('13# ')) V(n) ON [value] like V.n + '%'
where NOT ISNULL([value],'') = ''
GO
Comments
(1) For the sake of the demo, I manually used the numbers 1-6 but in your production you might have many more numbers. You can use dynamic query in order to build the query dynamically. With that being said, for most cases, It is HIGHLY recommended not to be lazy (at least if the amount of numbers is too high) and use this approach of manually write nested REPLACE since dynamic query might reduce performance.
(2) SQL Server does not deal parsing text well and using multiple string functions is usually not recommended. Using SQL CLR you can gain much better result probably by using regular expression.
(3) In general you should avoid such task in the server side. SQL Server is a database management application and as such it is designed for best performance in managing the data and not parsing the data.
After some research and elbow grease, I've come up with the solution below. I am not sure how performant/optimized it is, and I'm certain there's probably better ways to do this. However, I wanted to avoid hard-coding the numbers... So here it is:
CREATE TABLE #EXAMPLE (
ID INT
, COMMENT VARCHAR(8000)
)
INSERT INTO #EXAMPLE (ID, COMMENT)
VALUES
(1, '1. Sed ut perspiciatis 1.3 unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. 2. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. 3. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem 4. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur 5. Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?')
, (2, 'At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia 8.3 deserunt mollitia animi, id est laborum et dolorum fuga')
, (3, 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua 1. A cras semper auctor neque 2. Morbi tincidunt augue interdum velit euismod in')
, (4, '1. Amet luctus venenatis lectus magna 2. Magna ac placerat vestibulum lectus mauris ultrices eros in cursus 3. Et ligula ullamcorper malesuada proin libero nunc consequat interdum varius 4. Enim facilisis gravida neque convallis a 5. Sed lectus vestibulum mattis ullamcorper velit sed 6. Vel turpis nunc eget lorem dolor 7. Convallis convallis tellus id interdum velit laoreet id donec 8. Nibh tortor id aliquet lectus proin nibh nisl 9. Eu ultrices vitae auctor eu augue ut 10. Mus mauris vitae ultricies leo integer malesuada nunc 11. Viverra justo nec 10.4 ultrices dui sapien eget mi 12. Tristique senectus et netus et malesuada fames ac turpis')
GO
WITH PATTERNS AS (
SELECT
*
FROM (VALUES('%[0-9]. %', 3)
, ('%[0-9][0-9]. %', 4)
, ('%[0-9][0-9][0-9]. %', 5)) AS PATTERNS (PATTERN, LENGTH))
, L0 AS (SELECT C FROM (VALUES(1),(1)) AS D(C))
, L1 AS (SELECT 1 AS C FROM L0 AS A CROSS JOIN L0 AS B)
, L2 AS (SELECT 1 AS C FROM L1 AS A CROSS JOIN L1 AS B)
, L3 AS (SELECT 1 AS C FROM L2 AS A CROSS JOIN L2 AS B)
, L4 AS (SELECT 1 AS C FROM L3 AS A CROSS JOIN L3 AS B)
, NUMS AS (SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS ROWNUM FROM L4)
, INDXS AS (
SELECT E.*, N.*, [GROUP] = DENSE_RANK() OVER(ORDER BY N.ROWNUM) - N.ROWNUM
FROM #EXAMPLE AS E
-- Outer apply so as to capture those without the pattern at all
OUTER APPLY (
SELECT *
FROM NUMS AS N
WHERE N.ROWNUM BETWEEN 1 AND LEN(E.COMMENT)
AND (EXISTS (
SELECT *
FROM PATTERNS AS P
WHERE PATINDEX(P.PATTERN, STUFF(E.COMMENT, 1, CASE WHEN N.ROWNUM > P.LENGTH THEN N.ROWNUM - P.LENGTH ELSE 0 END, '')) BETWEEN 1 AND CASE WHEN N.ROWNUM > P.LENGTH THEN P.LENGTH ELSE N.ROWNUM END)
-- For when there is no intial number at the beginning, but others at later indices
OR N.ROWNUM = 1 )) AS N
)
, PEN AS (
SELECT *, [RN] = ROW_NUMBER() OVER(PARTITION BY ID, [GROUP] ORDER BY ID, [GROUP], ROWNUM)
FROM INDXS
)
, FINAL AS (
SELECT F.ID, F.COMMENT, F.ROWNUM, [RN] = ROW_NUMBER() OVER(PARTITION BY F.ID ORDER BY F.ID, F.ROWNUM)
FROM PEN AS F
WHERE RN = 1
)
SELECT F.ID--, F.COMMENT, F.ROWNUM, N.ROWNUM
, [SECTION_NUMBER] = CASE WHEN N.ROWNUM IS NULL AND F.ROWNUM = 1 THEN 0 ELSE REPLACE(SUBSTRING((CASE WHEN N.ROWNUM IS NULL THEN SUBSTRING(F.COMMENT, F.ROWNUM, 8000) ELSE SUBSTRING(F.COMMENT, F.ROWNUM, N.ROWNUM - F.ROWNUM) END), 1, CHARINDEX('.', (CASE WHEN N.ROWNUM IS NULL THEN SUBSTRING(F.COMMENT, F.ROWNUM, 8000) ELSE SUBSTRING(F.COMMENT, F.ROWNUM, N.ROWNUM - F.ROWNUM) END), 1)), '.', '') END
, [SECTION] = (CASE WHEN N.ROWNUM IS NULL THEN SUBSTRING(F.COMMENT, F.ROWNUM, 8000) ELSE SUBSTRING(F.COMMENT, F.ROWNUM, N.ROWNUM - F.ROWNUM) END)
, F.ROWNUM
, N.ROWNUM
FROM FINAL AS F
LEFT OUTER JOIN FINAL AS N
ON F.ID = N.ID
AND F.RN = N.RN - 1
ORDER BY F.ID, F.ROWNUM
DROP TABLE #EXAMPLE
This solution was partially inspired by Ronen Ariely's answer as well as this post from SQLServerFast: https://sqlserverfast.com/blog/hugo/2019/04/removing-multiple-patterns-from-a-string/. It is able to hardcode the patterns I want to capture rather than all the individual instances of the pattern. I tried in particular to get this part to return only the starting index point of the number pattern (so if "2. " appears at points 233, 234, and 235, I only really want 233) but alas I could not figure that out. Interesting stuff, XML.
, INDXS AS (
SELECT E.*, N.*, [GROUP] = DENSE_RANK() OVER(ORDER BY N.ROWNUM) - N.ROWNUM
FROM #EXAMPLE AS E
-- Outer apply so as to capture those without the pattern at all
OUTER APPLY (
SELECT *
FROM NUMS AS N
WHERE N.ROWNUM BETWEEN 1 AND LEN(E.COMMENT)
AND (EXISTS (
SELECT *
FROM PATTERNS AS P
WHERE PATINDEX(P.PATTERN, STUFF(E.COMMENT, 1, CASE WHEN N.ROWNUM > P.LENGTH THEN N.ROWNUM - P.LENGTH ELSE 0 END, '')) BETWEEN 1 AND CASE WHEN N.ROWNUM > P.LENGTH THEN P.LENGTH ELSE N.ROWNUM END)
-- For when there is no intial number at the beginning, but others at later indices
OR N.ROWNUM = 1 )) AS N
)
In production, I had 335 rows I was applying this to, in which the "COMMENT" field was generally much longer than the sample data I used here. It took about 24 seconds, which works for me (this is for a one time report, but I may use it for similar requests).
Thanks to those who responded!

Flutter - How to check if a SingleChildScrollView fits in a screen

Is it possible to check if a SingleChildScrollView fits in a screen so it doesn't need scrolling?
I want to achieve different behaviours based on this information.
Thanks to everyone in advance.
I had the same issue, and found a way around this. Here's how I made it:
Theory:
You need to provide a scroll controller to your SingleChildScrollView.
The reason is that the "[...] scroll controller creates a ScrollPosition to manage the state specific to an individual Scrollable widget", and we'll use exactly that to determine if the contents of our scrollable widget fits in the screen.
The property we're interested in is maxScrollExtent. It belongs to the ScrollPosition, and indicates the "maximum in-range value for pixels" that we can scroll to.
How:
The way I used it was to check if this value is greater than zero:
If so, then the contents do not fit in the given height.
Otherwise, if it's equal to zero, then the contents of the scrollable fits the screen.
Caveats in using this approach:
The child's size is a reflex of the build, so you can't know in advance if it will be scrollable or not. But what we can do is add a post frame callback to be executed after the build. By that point, when this callback is run, the build has already occurred, so we can check if the child fits in the screen or not.
Problem is, we need a StatefulWidget to do so. In that, we can schedule a post frame callback either in the initState() override - which will run only once during the widget's lifecycle, or in didChangeDependencies() - which runs whenever the widget needs rebuilding due a dependency change. See what fits best to your purpose.
TL;DR:
Here's a sample that shows how to take advantage of maxScrollExtent. Try running it in a flutter dartpad and change the width of the preview:
import 'package:flutter/material.dart';
final Color darkBlue = Color.fromARGB(255, 18, 32, 47);
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
debugShowCheckedModeBanner: false,
home: Scaffold(
body: Center(
child: MyWidget(),
),
),
);
}
}
// Here's the important widget
class MyWidget extends StatefulWidget {
#override
_MyWidgetState createState() => _MyWidgetState();
}
class _MyWidgetState extends State<MyWidget> {
final ScrollController _controller = ScrollController();
#override
void didChangeDependencies() {
super.didChangeDependencies();
WidgetsBinding.instance.addPostFrameCallback((_) {
// Checks to see the controller's [ScrollMetrics] maxScrollExtent.
// If zero, then the entire scrollable fits in the screen's viewport.
// So, triggers fadeoutController.reverse() to make scrollbar go away.
var maxScrollExtent = _controller.position.maxScrollExtent;
if (maxScrollExtent == 0) {
print('Fits entirely');
} else {
print('Needs scrolling');
}
});
}
#override
Widget build(BuildContext context) {
return SingleChildScrollView(
controller: _controller,
child: Column(
children: <Widget>[
Container(
width: MediaQuery.of(context).size.width,
child: Text(_text),
),
],
),
);
}
}
// very, very long lorem ipsum so that we can get to scroll if it doesn't fit.
const String _text = '''Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam semper, massa ac dignissim elementum, sapien nibh faucibus nibh, vel fermentum justo augue non est. Vestibulum at diam a orci hendrerit pellentesque vitae et tortor. Donec vel ultricies ipsum. Morbi eleifend dolor eget risus dignissim tempor. Curabitur suscipit eros turpis, id iaculis odio fringilla nec. Phasellus ullamcorper lacus nec dapibus euismod. Aenean convallis euismod pellentesque. Integer congue libero in turpis dapibus, vitae condimentum ex elementum. Nullam condimentum, turpis eget tincidunt ultrices, orci mi maximus ex, sit amet tempor nulla mi quis libero. Sed congue elementum magna, ut luctus felis congue ut. Aliquam fringilla tortor at elit tempus venenatis. Quisque porta commodo nisi, sit amet rhoncus arcu dapibus non. Nam sit amet ullamcorper dui. Quisque dui dolor, tincidunt in urna sit amet, ultricies egestas libero.
Sed at lorem magna. Sed dignissim ullamcorper convallis. Nunc ornare, urna eget sodales feugiat, sem odio eleifend felis, a blandit lorem mi sed orci. Nulla facilisi. Pellentesque sed mi scelerisque, sollicitudin nunc non, ullamcorper neque. Quisque purus magna, lacinia vel ex a, tempor viverra ante. Phasellus volutpat nulla nec aliquet sollicitudin. Morbi ultricies dapibus scelerisque. Pellentesque ut elit justo. Phasellus eget tempus massa. Curabitur id enim mollis, rutrum lorem in, aliquet diam. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Proin semper ultricies orci. Nunc tempor fermentum dolor, placerat aliquam arcu ullamcorper sed. Cras eleifend erat gravida, mattis dolor eu, mollis lorem. Donec eu aliquet mauris, a egestas tortor.
Vivamus eu lorem erat. Phasellus condimentum quam quam, semper mattis odio dapibus vitae. Nulla eleifend lectus malesuada sem feugiat elementum. Phasellus semper luctus sodales. Aenean facilisis eu purus eget ultricies. Mauris non hendrerit lectus. Donec mollis ante non viverra euismod. Nulla aliquam, quam a rutrum dictum, tortor magna sagittis diam, non pulvinar erat nibh id nibh. Aliquam rutrum, mauris sit amet eleifend convallis, orci arcu egestas purus, vel dignissim tellus quam sit amet dolor. In hac habitasse platea dictumst. Etiam justo orci, sagittis a arcu vitae, viverra fringilla nunc. Maecenas ac semper ligula. Suspendisse ultrices tellus placerat nisl euismod pharetra.
Quisque et tellus ut magna efficitur volutpat ut nec metus. Vestibulum sed turpis id justo porta sagittis vitae et ligula. Aliquam ultricies tortor nulla, laoreet efficitur dui dictum eget. Aenean at ante a odio ornare pharetra in eget metus. Fusce vulputate luctus tortor in convallis. Praesent a velit libero. Proin molestie condimentum commodo. Nullam congue massa a odio congue, a bibendum tortor vestibulum. Etiam pellentesque dapibus libero. Donec iaculis vitae ante luctus varius.
Donec eleifend, elit eget accumsan rhoncus, diam nunc luctus dui, eu accumsan arcu sapien sed urna. Vivamus non viverra tellus, eget tincidunt nisl. Suspendisse nec laoreet risus. Vestibulum sit amet est elit. Duis vestibulum maximus magna ut dignissim. Mauris suscipit fermentum sapien sit amet finibus. Morbi quis lectus tincidunt nibh malesuada auctor non at neque. Fusce in tortor dictum, ornare felis ut, fermentum justo. Nulla ullamcorper viverra bibendum. Aliquam erat volutpat. Mauris et neque in purus auctor bibendum. Proin posuere enim id egestas scelerisque. In sollicitudin velit a ex fringilla, nec vulputate arcu volutpat. Mauris euismod sapien justo, sit amet pulvinar nisl volutpat quis. Sed finibus, leo vel molestie porta, quam est placerat mauris, vitae placerat eros turpis porta lorem. Donec at tortor tortor.''';

Pasting text that triggers the scroll leaves cursor in visually the wrong location

See what I mean by going here: https://codemirror.net/demo/indentwrap.html
Paste in something large enough to trigger scrollbar, you may need to remove existing text first:
Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur? Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?
The cursor will appear not in the correct location until you type or move it. Has anyone seen this or know of a solution or workaround?
Edit:
If I put listeners for pasting and do a refresh() and scrollIntoView() it seems to work most of the time... but doesnt always seem effective if I'm posting between content for some reason.
Although it has the small side affect of always having a 17px padding on the right side... adding padding-right: 17px !important to .CodeMirror-sizer seems to fix the problem.
The problem seems to have been caused by when the scrollbar appears, it makes the scrollbar visible, and also adds the 17px right padding to the sizer (so the text doesn't run under the scrollbar). The cursor appears to be positioned based on if that padding was never added until the user types or does something that would move the cursor. By always having that right padding, we don't run into this problem.
The small side affect doesn't matter much to me so I'm happy with this workaround, however... if someone else finds a better solution I'd like to see it.

Can iFrames work on iPhone/iPad?

I have read so much and still no real answer. How can I get iFrames to work on the iPhone and iPad? Especially now you can't 2 finger scroll. I just want to have an iFrame scroll or something that functions like one. I feel like this should be so simple!
Here is a sample page:
http://olbrichdesigns.com/ffff/characters/test.html
Thanks!
jenny
Mobile safari supports them but generally they're not great.
Using a DIV with overflow-y: scroll would probably be better for you
<div style="overflow-y: scroll; height: 100px;">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam at laoreet augue. Pellentesque felis arcu, convallis eu luctus vitae, imperdiet ut est. Nulla rhoncus varius odio, non facilisis felis imperdiet pellentesque. Aliquam in luctus orci. Ut convallis felis sodales diam ultricies in elementum ligula ultricies. Vivamus consequat convallis mauris, sed ullamcorper ante fermentum a. Quisque at velit eu velit venenatis faucibus id vel velit. Integer eget nisi elit. Ut blandit eros lorem, sed feugiat nunc. Sed lacus nisi, placerat sit amet blandit feugiat, accumsan ut urna. Proin risus sapien, porttitor sed euismod quis, adipiscing vitae nulla. Vestibulum at ipsum vel tortor fermentum tristique. Fusce laoreet magna vitae tellus accumsan eget adipiscing velit ullamcorper. Proin tempus volutpat fringilla. Etiam eu magna sit amet mi commodo volutpat sit amet eget lacus. Nullam euismod tellus id odio tempus id tincidunt felis mollis.
</div>
​