روشی که در سری ابتدایی Angular مطرح شدهاست، مبتنی بر سیستم مدیریت ماژولهای system.js هست. اما در نهایت روش توصیه شدهی توسط تیم Angular استفاده از Angular CLI است که مبتنی بر webpack است. این روش بسیار سادهتر (کار با ابزاری استاندارد)، ساختیافتهتر (به همراه تنظیماتی مبتنی بر best practices)، بهینهتر (به همراه بهینه سازیهای بسیاری جهت کاهش حجم نهایی و کاهش تعداد فایلهای تولیدی) و پیشرفتهتر از روش system.js هست و توضیحات تکمیلی آن در مطلب « Angular CLI - قسمت پنجم - ساخت و توزیع برنامه» ارائه شدهاند. این روشی است که برای ارائهی نهایی از آن استفاده میشود و در مطالبی مانند «یکپارچه سازی Angular CLI و ASP.NET Core در VS 2017» و «سفارشی سازی صفحهی اول برنامههای Angular CLI توسط ASP.NET Core» از آنها استفاده شدهاست.
حداقل دو نوع لینک را در فایلهای PDF میتوان ایجاد کرد:
الف) لینک به منابع خارجی؛ مانند یک وب سایت
ب) لینک به صفحهای داخل فایل PDF
در ادامه مثالی را مشاهده خواهید نمود که شامل هر دو نوع لینک است:
void WriteFile() { using (var doc = new Document(PageSize.LETTER)) { using (var fs = new FileStream("test.pdf", FileMode.Create)) { using (var writer = PdfWriter.GetInstance(doc, fs)) { doc.Open(); var blueFont = FontFactory.GetFont("Arial", 12, Font.NORMAL, BaseColor.BLUE); doc.Add(new Chunk("Go to URL", blueFont).SetAction(new PdfAction("http://www.google.com/", false))); doc.NewPage(); doc.Add(new Chunk("Go to Test", blueFont).SetLocalGoto("entry1")); doc.NewPage(); doc.Add(new Chunk("Test").SetLocalDestination("entry1")); doc.Close(); } } } }
در صفحه سوم یک Local Destination تعبیه شده است. در صفحه دوم به کمک یک Local Goto، لینکی به این مقصد داخلی ایجاد خواهد شد.
اصلاح لینکها در فایلهای PDF
همان مثال فوق را درنظر بگیرید. فرض کنید لینک خارجی ذکر شده در ابتدای فایل را میخواهیم به مقصدی که در صفحه دوم ایجاد کردهایم، تغییر دهیم. برای مثال خروجی PDF ایی را درنظر بگیرید که لینکهای اصلی آن به مقالاتی در یک سایت اشاره میکنند. اما همین مقالات اکنون در فایل نهایی خروجی نیز قرار دارند. بهتر است این لینکهای خارجی را به لینکهای ارجاع دهنده به مقالات موجود در فایل اصلاح کنیم، تا استفاده از نتیجه حاصل، سادهتر گردد.
پیش از اینکه کدهای این قسمت را بررسی کنیم، نیاز است کمی با ساختار سطح پایین فایلهای PDF آشنا شویم. پس از آن قادر خواهیم بود تا نسبت به اصلاح این لینکها اقدام کنیم.
در تصویر اول نحوه ذخیره شدن named destinationها را در یک فایل PDF مشاهده میکنید.
در تصویر دوم، ساختار دو نوع لینک تعریف شده در صفحات، مشخص هستند. یکی بر اساس Uri کار میکند و دیگری بر اساس GoTo.
کاری را که در ادامه قصد داریم انجام دهیم، تبدیل حالت Uri به GoTo است. برای مثال، در ادامه میخواهیم لینک مثال فوق را ویرایش کرده و آنرا تبدیل به لینکی نمائیم که به entry1 اشاره میکند. کدهای انجام اینکار را در ادامه ملاحظه میکنید:
using System; using System.Collections.Generic; using System.IO; using System.Linq; using iTextSharp.text.pdf; namespace ReplaceLinks { public class ReplacePdfLinks { Dictionary<string, PdfObject> _namedDestinations; PdfReader _reader; public string InputPdf { set; get; } public string OutputPdf { set; get; } public Func<Uri, string> UriToNamedDestination { set; get; } public void Start() { updatePdfLinks(); saveChanges(); } private PdfArray getAnnotationsOfCurrentPage(int pageNumber) { var pageDictionary = _reader.GetPageN(pageNumber); var annotations = pageDictionary.GetAsArray(PdfName.ANNOTS); return annotations; } private static bool hasAction(PdfDictionary annotationDictionary) { return annotationDictionary.Get(PdfName.SUBTYPE).Equals(PdfName.LINK); } private static bool isUriAction(PdfDictionary annotationAction) { return annotationAction.Get(PdfName.S).Equals(PdfName.URI); } private void replaceUriWithLocalDestination(PdfDictionary annotationAction) { var uri = annotationAction.Get(PdfName.URI) as PdfString; if (uri == null) return; if (string.IsNullOrWhiteSpace(uri.ToString())) return; var namedDestination = UriToNamedDestination(new Uri(uri.ToString())); if (string.IsNullOrWhiteSpace(namedDestination)) return; PdfObject entry; if (!_namedDestinations.TryGetValue(namedDestination, out entry)) return; annotationAction.Remove(PdfName.S); annotationAction.Remove(PdfName.URI); var newLocalDestination = new PdfArray(); annotationAction.Put(PdfName.S, PdfName.GOTO); var xRef = ((PdfArray)entry).First(x => x is PdfIndirectReference); newLocalDestination.Add(xRef); newLocalDestination.Add(PdfName.FITH); annotationAction.Put(PdfName.D, newLocalDestination); } private void saveChanges() { using (var fileStream = new FileStream(OutputPdf, FileMode.Create, FileAccess.Write, FileShare.None)) using (var stamper = new PdfStamper(_reader, fileStream)) { stamper.Close(); } } private void updatePdfLinks() { _reader = new PdfReader(InputPdf); _namedDestinations = _reader.GetNamedDestinationFromStrings(); var pageCount = _reader.NumberOfPages; for (var i = 1; i <= pageCount; i++) { var annotations = getAnnotationsOfCurrentPage(i); if (annotations == null || !annotations.Any()) continue; foreach (var annotation in annotations.ArrayList) { var annotationDictionary = (PdfDictionary)PdfReader.GetPdfObject(annotation); if (!hasAction(annotationDictionary)) continue; var annotationAction = annotationDictionary.Get(PdfName.A) as PdfDictionary; if (annotationAction == null) continue; if (!isUriAction(annotationAction)) continue; replaceUriWithLocalDestination(annotationAction); } } } } }
کار تغییر ساختار PDF در متد replaceUriWithLocalDestination انجام میشود. در اینجا آدرس استخراجی به استفاده کننده ارجاع شده و named destination مناسبی دریافت میشود. اگر این «مقصد نام دار» در مجموعه مقاصد نام دار PDF جاری وجود داشت، خواص لینک قبلی مانند Uri آن حذف شده و با GoTo به آدرس این مقصد جدید جایگزین میشود.
در آخر، توسط یک PdfStamper، اطلاعات تغییر کرده را در فایلی جدید ثبت خواهیم کرد.
یک نمونه از استفاده از کلاس فوق به شرح زیر است:
new ReplacePdfLinks { InputPdf = @"test.pdf", OutputPdf = "mod.pdf", UriToNamedDestination = uri => { if (uri.Host.ToLowerInvariant().Contains("google.com")) { return "entry1"; } return string.Empty; } }.Start();
چند نکته تکمیلی
- اگر قصد داشته باشیم تا لینکی را ویرایش کرده اما تنها Uri آنرا تغییر دهیم، تنها کافی است URI آنرا به نحو زیر در متد replaceUriWithLocalDestination ویرایش کنیم:
annotationAction.Put(PdfName.URI, new PdfString("http://www.bing.com/"));
newLocalDestination.Add((PdfObject)_reader.GetPageOrigRef(pageNum: 2));RemovePdfLinks.7z
Experiments with the new WASI workload in .NET 8 Preview 4
.NET 8 adds a new "wasi-experimental" workload, replacing the earlier Wasi.Sdk. This is a step towards giving .NET native, built-in support for server-side WebAssembly scenarios.
This video shows how to get started, then demonstrates how .NET+WASI creates possibilities for new kinds of apps and new ways to use .NET.
Taking advantage of WebHooks is something that many developers want to achieve, but many struggle to find a starting point. In ASP.NET WebHooks Succinctly, Gaurav Arora guides readers through the necessary skills and processes to get started.
- Introduction
- Working with WebHooks
- Creating a Real-Time Application
- Creating a WebHook Receiver
- Writing Senders
- Diagnostics
- Tips & Tricks
مصاحبه با خالق ++C
مطالبی که در این ویدئو به آن پرداخته میشود :
What is the keynote about? How do we write modern C++ code? Guideline support library and Static analysis Call to action for the C++ community! Enhancing productivity by eliminating whole classes of bugs Extending the C++ core guidelines What do you expect from these static analysis checkers? How can I get started?
سری آموزشی Angular 15
- Success
- Error
- Warning
- Verbose
- Debug
- Information
cmdlet | Name | Id |
Write-Output | Success | 1 |
Write-Error | Error | 2 |
Write-Warning | Warning | 3 |
Write-Verbose | Verbose | 4 |
Write-Debug | Debug | 5 |
Write-Information | Information | 6 |
به جز دو مورد اول، بقیه cmdletها خروجی را به صورت پیشفرض درون کنسول نمایش نمیدهند. به عنوان مثال اسکریپت زیر را در نظر بگیرید:
Write-Output 'Output' Write-Error 'This is an error' Write-Warning 'This is a warning' Write-Verbose 'This is verbose' Write-Debug 'This is Debug' Write-Information 'This is information'
با اجرای اسکریپت فوق خروجی زیر را خواهیم داشت:
Output Write-Error: This is an error WARNING: This is a warning
همانطور که مشاهده میکنید سه cmdlet فوق، خروجی را درون کنسول نمایش ندادهاند. این رفتار توسط مفهومی تحت عنوان Action Preference قابل تنظیم است که در واقع یک Enum است با مقدار زیر:
6 | Break | |
رخداد به صورت عادی مدیریت شده و برنامه ادامه پیدا میکند | 2 | Continue |
به طور کلی از رخداد صرفنظر خواهد شد؛ بدون اینکه چیزی در استریم نمایش داده شود | 4 | Ignore |
سوال پرسیده خواهد شد که برنامه را ادامه دهد یا متوقف کند | 3 | Inquire |
به طور کلی از رخداد صرفنظر خواهد شد | 0 | SilentlyContinue |
دستور را متوقف خواهد کرد | 1 | Stop |
دستور به نوعی معلق خواهد شد | 5 | Suspend |
بنابراین با تغییر Action Preference برای هر کدام از cmdletها میتوانیم رفتار اسکریپت قبلی را تغییر دهیم:
Write-Output 'Output' Write-Error 'This is an error' Write-Warning 'This is a warning' $VerbosePreference = 'Continue' Write-Verbose 'This is verbose' $DebugPreference = 'Continue' Write-Debug 'This is Debug' $InformationPreference = 'Continue' Write-Information 'This is information'
اکنون اگر اسکریپت فوق را اجرا کنید، سه خروجی آخر را نیز مشاهده خواهید کرد:
Output Write-Error: This is an error WARNING: This is a warning VERBOSE: This is verbose DEBUG: This is Debug This is information
هر کدام از استریمهای فوق قابل redirect شدن نیز هستند؛ برای اینکار میتوانیم از redirect operatorهایی که در PowerShell پشتیبانی میشود استفاده کنیم:
> >> >&1
به عنوان مثال میتوانیم تمام خطاها یا هشدارهای درون یک اسکریپت را به یک فایل منتقل کنیم:
./script.ps1 2>&1 > .\logs.txt
یا میتوانیم تمام Success streamها را به یک فایل هدایت کنیم:
.\script.ps1 > script.log
ارسال تمام Success, Warning, Errorها به یک فایل:
&{ Write-Warning "hello" Write-Error "hello" Write-Output "hi" } 3>&1 2>&1 > C:\Temp\redirection.log
ارسال تمام استریمها به یک فایل:
.\script.ps1 *> script.log
همچنین میتوانیم استریمی را به اصطلاح suppress کنیم که در خروجی نمایش داده نشود:
./script.ps1 1> $null 2> $null ./script.ps1 *> $null
از تکنیک فوق برای drop کردن خروجیهایی که نمیخواهیم نمایش داده شوند، استفاده میشود. در کد فوق دو Idهای ۱ و ۲ را به متغیر ویژهی null هدایت کردهایم؛ همچنین میتوانستیم از یک رشتهی خالی نیز بجای null استفاده کنیم. در خط بعدی از * استفاده کردهایم که به معنای تمامی استریمهای موجود است؛ با اینکار چیزی در خروجی نمایش داده نخواهد شد. یک روش دیگر برای drop کردن، استفاده از دستور Out-Null است:
Get-ChildItem | Out-Null
لازم به ذکر است که این cmdlet تا قبل از نسخه ۶ خیلی کند بود؛ زیرا همانند دیگر cmdletهای درون pipeline میبایست یک ورودی (InputObject) را دریافت کند که باعث میشد هزینهی پردازشی بالایی داشته باشد. اما در نسخه ۶ به بعد این مشکل رفع شدهاست و پارزر به محض رسیدن به این keyword به صورت کلی خروجی را discard میکند بدون اینکه Out-Null را فراخوانی کند؛ در واقع این cmdlet یک hint برای پارزر است. روش دیگر برای drop کردن خروجی، انتساب نتیجه یک دستور به متغییر null است:
New-Item -Type Directory -Path $path | Out-Null $null = New-Item -Type Directory -Path $path
همچنین میتوانیم خروجی یک دستور را به void تبدیل کنیم؛ که نتیجه مشابه با تکنیکهای فوق دارد:
[void](New-Item -Name test -ItemType Directory)
یک نکته در مورد Out-Null
در loopهای بزرگ ممکن است Out-Null حتی در PowerShell 7.x هم کند عمل کند:
PS > Measure-Command { for($i=0; $i -lt 1mb; $i++) { $i | Out-Null } } | Select-Object TotalSeconds TotalSeconds ------------ 4.3056315 PS > Measure-Command { for($i=0; $i -lt 1mb; $i++) { $null = $i } } | Select-Object TotalSeconds TotalSeconds ------------ 1.1210884 PS > Measure-Command { for($i=0; $i -lt 1mb; $i++) { [void]$i } } | Select-Object TotalSeconds TotalSeconds ------------ 1.130507 PS > Measure-Command { for($i=0; $i -lt 1mb; $i++) { $i > $null } } | Select-Object TotalSeconds TotalSeconds ------------ 1.3832427
Restangular چیست؟
// Restangular returns promises Restangular.all('users').getList() // GET: /users .then(function(users) { // returns a list of users $scope.user = users[0]; // first Restangular obj in list: { id: 123 } }) // Later in the code... // Restangular objects are self-aware and know how to make their own RESTful requests $scope.user.getList('cars'); // GET: /users/123/cars // You can also use your own custom methods on Restangular objects $scope.user.sendMessage(); // POST: /users/123/sendMessage // Chain methods together to easily build complex requests $scope.user.one('messages', 123).one('from', 123).getList('unread'); // GET: /users/123/messages/123/from/123/unread
وابستگی ها
شروع پروژه
// Add Restangular as a dependency to your app angular.module('your-app', ['restangular']); // Inject Restangular into your controller angular.module('your-app').controller('MainCtrl', function($scope, Restangular) { // ... });
برخی از متدهای RestAngular
نام متد | پارامترهای ارسالی | توضیحات |
one | route, id | این متد یک RestAngular object ایجاد میکند که از آدرسی که در route قرار داده شده با id مشخص دریافت میشود. |
all | route | این متد یک RestAngular object که لیستی از المنت هایی را که در آدرس route قرار دارد، دریافت مینماید. |
oneUrl | route, url | این متد یک RestAngular object ایجاد میکند که یک المنت از url خاصی را بازگشت میدهد. مانند: Restangular.oneUrl( 'googlers' , 'http://www.google.com/1' ).get(); |
allUrl | route, url | این متد مانند متد قبل است با این تفاوت که یک مجموعه را بازگشت میدهد. |
copy | formElement | این متد یک کپی از المنتهای یک فرم را ایجاد میکند که ما میتوانیم آنها را تغییر دهیم. |
restangularizeElement | parent,element, route, queryParams | یک المنت جدید را به صورت Restangularize تغییر میدهد. |
restangularizeCollection | parent, element, route, queryParams | یک کالکشن Collection را به صورت Restangularize تغییر میدهد. |